Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[cascardo/linux.git] / fs / cifs / cifssmb.c
1 /*
2  *   fs/cifs/cifssmb.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2010
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   Contains the routines for constructing the SMB PDUs themselves
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23
24  /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c   */
25  /* These are mostly routines that operate on a pathname, or on a tree id     */
26  /* (mounted volume), but there are eight handle based routines which must be */
27  /* treated slightly differently for reconnection purposes since we never     */
28  /* want to reuse a stale file handle and only the caller knows the file info */
29
30 #include <linux/fs.h>
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <asm/uaccess.h>
39 #include "cifspdu.h"
40 #include "cifsglob.h"
41 #include "cifsacl.h"
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
45 #include "fscache.h"
46
47 #ifdef CONFIG_CIFS_POSIX
48 static struct {
49         int index;
50         char *name;
51 } protocols[] = {
52 #ifdef CONFIG_CIFS_WEAK_PW_HASH
53         {LANMAN_PROT, "\2LM1.2X002"},
54         {LANMAN2_PROT, "\2LANMAN2.1"},
55 #endif /* weak password hashing for legacy clients */
56         {CIFS_PROT, "\2NT LM 0.12"},
57         {POSIX_PROT, "\2POSIX 2"},
58         {BAD_PROT, "\2"}
59 };
60 #else
61 static struct {
62         int index;
63         char *name;
64 } protocols[] = {
65 #ifdef CONFIG_CIFS_WEAK_PW_HASH
66         {LANMAN_PROT, "\2LM1.2X002"},
67         {LANMAN2_PROT, "\2LANMAN2.1"},
68 #endif /* weak password hashing for legacy clients */
69         {CIFS_PROT, "\2NT LM 0.12"},
70         {BAD_PROT, "\2"}
71 };
72 #endif
73
74 /* define the number of elements in the cifs dialect array */
75 #ifdef CONFIG_CIFS_POSIX
76 #ifdef CONFIG_CIFS_WEAK_PW_HASH
77 #define CIFS_NUM_PROT 4
78 #else
79 #define CIFS_NUM_PROT 2
80 #endif /* CIFS_WEAK_PW_HASH */
81 #else /* not posix */
82 #ifdef CONFIG_CIFS_WEAK_PW_HASH
83 #define CIFS_NUM_PROT 3
84 #else
85 #define CIFS_NUM_PROT 1
86 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
87 #endif /* CIFS_POSIX */
88
89 /*
90  * Mark as invalid, all open files on tree connections since they
91  * were closed when session to server was lost.
92  */
93 void
94 cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
95 {
96         struct cifsFileInfo *open_file = NULL;
97         struct list_head *tmp;
98         struct list_head *tmp1;
99
100         /* list all files open on tree connection and mark them invalid */
101         spin_lock(&cifs_file_list_lock);
102         list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
103                 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
104                 open_file->invalidHandle = true;
105                 open_file->oplock_break_cancelled = true;
106         }
107         spin_unlock(&cifs_file_list_lock);
108         /*
109          * BB Add call to invalidate_inodes(sb) for all superblocks mounted
110          * to this tcon.
111          */
112 }
113
114 /* reconnect the socket, tcon, and smb session if needed */
115 static int
116 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
117 {
118         int rc;
119         struct cifs_ses *ses;
120         struct TCP_Server_Info *server;
121         struct nls_table *nls_codepage;
122
123         /*
124          * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
125          * tcp and smb session status done differently for those three - in the
126          * calling routine
127          */
128         if (!tcon)
129                 return 0;
130
131         ses = tcon->ses;
132         server = ses->server;
133
134         /*
135          * only tree disconnect, open, and write, (and ulogoff which does not
136          * have tcon) are allowed as we start force umount
137          */
138         if (tcon->tidStatus == CifsExiting) {
139                 if (smb_command != SMB_COM_WRITE_ANDX &&
140                     smb_command != SMB_COM_OPEN_ANDX &&
141                     smb_command != SMB_COM_TREE_DISCONNECT) {
142                         cFYI(1, "can not send cmd %d while umounting",
143                                 smb_command);
144                         return -ENODEV;
145                 }
146         }
147
148         /*
149          * Give demultiplex thread up to 10 seconds to reconnect, should be
150          * greater than cifs socket timeout which is 7 seconds
151          */
152         while (server->tcpStatus == CifsNeedReconnect) {
153                 wait_event_interruptible_timeout(server->response_q,
154                         (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
155
156                 /* are we still trying to reconnect? */
157                 if (server->tcpStatus != CifsNeedReconnect)
158                         break;
159
160                 /*
161                  * on "soft" mounts we wait once. Hard mounts keep
162                  * retrying until process is killed or server comes
163                  * back on-line
164                  */
165                 if (!tcon->retry) {
166                         cFYI(1, "gave up waiting on reconnect in smb_init");
167                         return -EHOSTDOWN;
168                 }
169         }
170
171         if (!ses->need_reconnect && !tcon->need_reconnect)
172                 return 0;
173
174         nls_codepage = load_nls_default();
175
176         /*
177          * need to prevent multiple threads trying to simultaneously
178          * reconnect the same SMB session
179          */
180         mutex_lock(&ses->session_mutex);
181         rc = cifs_negotiate_protocol(0, ses);
182         if (rc == 0 && ses->need_reconnect)
183                 rc = cifs_setup_session(0, ses, nls_codepage);
184
185         /* do we need to reconnect tcon? */
186         if (rc || !tcon->need_reconnect) {
187                 mutex_unlock(&ses->session_mutex);
188                 goto out;
189         }
190
191         cifs_mark_open_files_invalid(tcon);
192         rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
193         mutex_unlock(&ses->session_mutex);
194         cFYI(1, "reconnect tcon rc = %d", rc);
195
196         if (rc)
197                 goto out;
198
199         /*
200          * FIXME: check if wsize needs updated due to negotiated smb buffer
201          *        size shrinking
202          */
203         atomic_inc(&tconInfoReconnectCount);
204
205         /* tell server Unix caps we support */
206         if (ses->capabilities & CAP_UNIX)
207                 reset_cifs_unix_caps(0, tcon, NULL, NULL);
208
209         /*
210          * Removed call to reopen open files here. It is safer (and faster) to
211          * reopen files one at a time as needed in read and write.
212          *
213          * FIXME: what about file locks? don't we need to reclaim them ASAP?
214          */
215
216 out:
217         /*
218          * Check if handle based operation so we know whether we can continue
219          * or not without returning to caller to reset file handle
220          */
221         switch (smb_command) {
222         case SMB_COM_READ_ANDX:
223         case SMB_COM_WRITE_ANDX:
224         case SMB_COM_CLOSE:
225         case SMB_COM_FIND_CLOSE2:
226         case SMB_COM_LOCKING_ANDX:
227                 rc = -EAGAIN;
228         }
229
230         unload_nls(nls_codepage);
231         return rc;
232 }
233
234 /* Allocate and return pointer to an SMB request buffer, and set basic
235    SMB information in the SMB header.  If the return code is zero, this
236    function must have filled in request_buf pointer */
237 static int
238 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
239                 void **request_buf)
240 {
241         int rc;
242
243         rc = cifs_reconnect_tcon(tcon, smb_command);
244         if (rc)
245                 return rc;
246
247         *request_buf = cifs_small_buf_get();
248         if (*request_buf == NULL) {
249                 /* BB should we add a retry in here if not a writepage? */
250                 return -ENOMEM;
251         }
252
253         header_assemble((struct smb_hdr *) *request_buf, smb_command,
254                         tcon, wct);
255
256         if (tcon != NULL)
257                 cifs_stats_inc(&tcon->num_smbs_sent);
258
259         return 0;
260 }
261
262 int
263 small_smb_init_no_tc(const int smb_command, const int wct,
264                      struct cifs_ses *ses, void **request_buf)
265 {
266         int rc;
267         struct smb_hdr *buffer;
268
269         rc = small_smb_init(smb_command, wct, NULL, request_buf);
270         if (rc)
271                 return rc;
272
273         buffer = (struct smb_hdr *)*request_buf;
274         buffer->Mid = get_next_mid(ses->server);
275         if (ses->capabilities & CAP_UNICODE)
276                 buffer->Flags2 |= SMBFLG2_UNICODE;
277         if (ses->capabilities & CAP_STATUS32)
278                 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
279
280         /* uid, tid can stay at zero as set in header assemble */
281
282         /* BB add support for turning on the signing when
283         this function is used after 1st of session setup requests */
284
285         return rc;
286 }
287
288 /* If the return code is zero, this function must fill in request_buf pointer */
289 static int
290 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
291                         void **request_buf, void **response_buf)
292 {
293         *request_buf = cifs_buf_get();
294         if (*request_buf == NULL) {
295                 /* BB should we add a retry in here if not a writepage? */
296                 return -ENOMEM;
297         }
298     /* Although the original thought was we needed the response buf for  */
299     /* potential retries of smb operations it turns out we can determine */
300     /* from the mid flags when the request buffer can be resent without  */
301     /* having to use a second distinct buffer for the response */
302         if (response_buf)
303                 *response_buf = *request_buf;
304
305         header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
306                         wct);
307
308         if (tcon != NULL)
309                 cifs_stats_inc(&tcon->num_smbs_sent);
310
311         return 0;
312 }
313
314 /* If the return code is zero, this function must fill in request_buf pointer */
315 static int
316 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
317          void **request_buf, void **response_buf)
318 {
319         int rc;
320
321         rc = cifs_reconnect_tcon(tcon, smb_command);
322         if (rc)
323                 return rc;
324
325         return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
326 }
327
328 static int
329 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
330                         void **request_buf, void **response_buf)
331 {
332         if (tcon->ses->need_reconnect || tcon->need_reconnect)
333                 return -EHOSTDOWN;
334
335         return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
336 }
337
338 static int validate_t2(struct smb_t2_rsp *pSMB)
339 {
340         unsigned int total_size;
341
342         /* check for plausible wct */
343         if (pSMB->hdr.WordCount < 10)
344                 goto vt2_err;
345
346         /* check for parm and data offset going beyond end of smb */
347         if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
348             get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
349                 goto vt2_err;
350
351         total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
352         if (total_size >= 512)
353                 goto vt2_err;
354
355         /* check that bcc is at least as big as parms + data, and that it is
356          * less than negotiated smb buffer
357          */
358         total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
359         if (total_size > get_bcc(&pSMB->hdr) ||
360             total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
361                 goto vt2_err;
362
363         return 0;
364 vt2_err:
365         cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
366                 sizeof(struct smb_t2_rsp) + 16);
367         return -EINVAL;
368 }
369
370 int
371 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
372 {
373         NEGOTIATE_REQ *pSMB;
374         NEGOTIATE_RSP *pSMBr;
375         int rc = 0;
376         int bytes_returned;
377         int i;
378         struct TCP_Server_Info *server;
379         u16 count;
380         unsigned int secFlags;
381
382         if (ses->server)
383                 server = ses->server;
384         else {
385                 rc = -EIO;
386                 return rc;
387         }
388         rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
389                       (void **) &pSMB, (void **) &pSMBr);
390         if (rc)
391                 return rc;
392
393         /* if any of auth flags (ie not sign or seal) are overriden use them */
394         if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
395                 secFlags = ses->overrideSecFlg;  /* BB FIXME fix sign flags? */
396         else /* if override flags set only sign/seal OR them with global auth */
397                 secFlags = global_secflags | ses->overrideSecFlg;
398
399         cFYI(1, "secFlags 0x%x", secFlags);
400
401         pSMB->hdr.Mid = get_next_mid(server);
402         pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
403
404         if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
405                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
406         else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
407                 cFYI(1, "Kerberos only mechanism, enable extended security");
408                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
409         } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
410                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
411         else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
412                 cFYI(1, "NTLMSSP only mechanism, enable extended security");
413                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
414         }
415
416         count = 0;
417         for (i = 0; i < CIFS_NUM_PROT; i++) {
418                 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
419                 count += strlen(protocols[i].name) + 1;
420                 /* null at end of source and target buffers anyway */
421         }
422         inc_rfc1001_len(pSMB, count);
423         pSMB->ByteCount = cpu_to_le16(count);
424
425         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
426                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
427         if (rc != 0)
428                 goto neg_err_exit;
429
430         server->dialect = le16_to_cpu(pSMBr->DialectIndex);
431         cFYI(1, "Dialect: %d", server->dialect);
432         /* Check wct = 1 error case */
433         if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
434                 /* core returns wct = 1, but we do not ask for core - otherwise
435                 small wct just comes when dialect index is -1 indicating we
436                 could not negotiate a common dialect */
437                 rc = -EOPNOTSUPP;
438                 goto neg_err_exit;
439 #ifdef CONFIG_CIFS_WEAK_PW_HASH
440         } else if ((pSMBr->hdr.WordCount == 13)
441                         && ((server->dialect == LANMAN_PROT)
442                                 || (server->dialect == LANMAN2_PROT))) {
443                 __s16 tmp;
444                 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
445
446                 if ((secFlags & CIFSSEC_MAY_LANMAN) ||
447                         (secFlags & CIFSSEC_MAY_PLNTXT))
448                         server->secType = LANMAN;
449                 else {
450                         cERROR(1, "mount failed weak security disabled"
451                                    " in /proc/fs/cifs/SecurityFlags");
452                         rc = -EOPNOTSUPP;
453                         goto neg_err_exit;
454                 }
455                 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
456                 server->maxReq = min_t(unsigned int,
457                                        le16_to_cpu(rsp->MaxMpxCount),
458                                        cifs_max_pending);
459                 set_credits(server, server->maxReq);
460                 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
461                 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
462                 /* even though we do not use raw we might as well set this
463                 accurately, in case we ever find a need for it */
464                 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
465                         server->max_rw = 0xFF00;
466                         server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
467                 } else {
468                         server->max_rw = 0;/* do not need to use raw anyway */
469                         server->capabilities = CAP_MPX_MODE;
470                 }
471                 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
472                 if (tmp == -1) {
473                         /* OS/2 often does not set timezone therefore
474                          * we must use server time to calc time zone.
475                          * Could deviate slightly from the right zone.
476                          * Smallest defined timezone difference is 15 minutes
477                          * (i.e. Nepal).  Rounding up/down is done to match
478                          * this requirement.
479                          */
480                         int val, seconds, remain, result;
481                         struct timespec ts, utc;
482                         utc = CURRENT_TIME;
483                         ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
484                                             rsp->SrvTime.Time, 0);
485                         cFYI(1, "SrvTime %d sec since 1970 (utc: %d) diff: %d",
486                                 (int)ts.tv_sec, (int)utc.tv_sec,
487                                 (int)(utc.tv_sec - ts.tv_sec));
488                         val = (int)(utc.tv_sec - ts.tv_sec);
489                         seconds = abs(val);
490                         result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
491                         remain = seconds % MIN_TZ_ADJ;
492                         if (remain >= (MIN_TZ_ADJ / 2))
493                                 result += MIN_TZ_ADJ;
494                         if (val < 0)
495                                 result = -result;
496                         server->timeAdj = result;
497                 } else {
498                         server->timeAdj = (int)tmp;
499                         server->timeAdj *= 60; /* also in seconds */
500                 }
501                 cFYI(1, "server->timeAdj: %d seconds", server->timeAdj);
502
503
504                 /* BB get server time for time conversions and add
505                 code to use it and timezone since this is not UTC */
506
507                 if (rsp->EncryptionKeyLength ==
508                                 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
509                         memcpy(ses->server->cryptkey, rsp->EncryptionKey,
510                                 CIFS_CRYPTO_KEY_SIZE);
511                 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
512                         rc = -EIO; /* need cryptkey unless plain text */
513                         goto neg_err_exit;
514                 }
515
516                 cFYI(1, "LANMAN negotiated");
517                 /* we will not end up setting signing flags - as no signing
518                 was in LANMAN and server did not return the flags on */
519                 goto signing_check;
520 #else /* weak security disabled */
521         } else if (pSMBr->hdr.WordCount == 13) {
522                 cERROR(1, "mount failed, cifs module not built "
523                           "with CIFS_WEAK_PW_HASH support");
524                 rc = -EOPNOTSUPP;
525 #endif /* WEAK_PW_HASH */
526                 goto neg_err_exit;
527         } else if (pSMBr->hdr.WordCount != 17) {
528                 /* unknown wct */
529                 rc = -EOPNOTSUPP;
530                 goto neg_err_exit;
531         }
532         /* else wct == 17 NTLM */
533         server->sec_mode = pSMBr->SecurityMode;
534         if ((server->sec_mode & SECMODE_USER) == 0)
535                 cFYI(1, "share mode security");
536
537         if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
538 #ifdef CONFIG_CIFS_WEAK_PW_HASH
539                 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
540 #endif /* CIFS_WEAK_PW_HASH */
541                         cERROR(1, "Server requests plain text password"
542                                   " but client support disabled");
543
544         if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
545                 server->secType = NTLMv2;
546         else if (secFlags & CIFSSEC_MAY_NTLM)
547                 server->secType = NTLM;
548         else if (secFlags & CIFSSEC_MAY_NTLMV2)
549                 server->secType = NTLMv2;
550         else if (secFlags & CIFSSEC_MAY_KRB5)
551                 server->secType = Kerberos;
552         else if (secFlags & CIFSSEC_MAY_NTLMSSP)
553                 server->secType = RawNTLMSSP;
554         else if (secFlags & CIFSSEC_MAY_LANMAN)
555                 server->secType = LANMAN;
556         else {
557                 rc = -EOPNOTSUPP;
558                 cERROR(1, "Invalid security type");
559                 goto neg_err_exit;
560         }
561         /* else ... any others ...? */
562
563         /* one byte, so no need to convert this or EncryptionKeyLen from
564            little endian */
565         server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
566                                cifs_max_pending);
567         set_credits(server, server->maxReq);
568         /* probably no need to store and check maxvcs */
569         server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
570         server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
571         cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);
572         server->capabilities = le32_to_cpu(pSMBr->Capabilities);
573         server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
574         server->timeAdj *= 60;
575         if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
576                 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
577                        CIFS_CRYPTO_KEY_SIZE);
578         } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
579                         server->capabilities & CAP_EXTENDED_SECURITY) &&
580                                 (pSMBr->EncryptionKeyLength == 0)) {
581                 /* decode security blob */
582                 count = get_bcc(&pSMBr->hdr);
583                 if (count < 16) {
584                         rc = -EIO;
585                         goto neg_err_exit;
586                 }
587                 spin_lock(&cifs_tcp_ses_lock);
588                 if (server->srv_count > 1) {
589                         spin_unlock(&cifs_tcp_ses_lock);
590                         if (memcmp(server->server_GUID,
591                                    pSMBr->u.extended_response.
592                                    GUID, 16) != 0) {
593                                 cFYI(1, "server UID changed");
594                                 memcpy(server->server_GUID,
595                                         pSMBr->u.extended_response.GUID,
596                                         16);
597                         }
598                 } else {
599                         spin_unlock(&cifs_tcp_ses_lock);
600                         memcpy(server->server_GUID,
601                                pSMBr->u.extended_response.GUID, 16);
602                 }
603
604                 if (count == 16) {
605                         server->secType = RawNTLMSSP;
606                 } else {
607                         rc = decode_negTokenInit(pSMBr->u.extended_response.
608                                                  SecurityBlob, count - 16,
609                                                  server);
610                         if (rc == 1)
611                                 rc = 0;
612                         else
613                                 rc = -EINVAL;
614                         if (server->secType == Kerberos) {
615                                 if (!server->sec_kerberos &&
616                                                 !server->sec_mskerberos)
617                                         rc = -EOPNOTSUPP;
618                         } else if (server->secType == RawNTLMSSP) {
619                                 if (!server->sec_ntlmssp)
620                                         rc = -EOPNOTSUPP;
621                         } else
622                                         rc = -EOPNOTSUPP;
623                 }
624         } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
625                 rc = -EIO; /* no crypt key only if plain text pwd */
626                 goto neg_err_exit;
627         } else
628                 server->capabilities &= ~CAP_EXTENDED_SECURITY;
629
630 #ifdef CONFIG_CIFS_WEAK_PW_HASH
631 signing_check:
632 #endif
633         if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
634                 /* MUST_SIGN already includes the MAY_SIGN FLAG
635                    so if this is zero it means that signing is disabled */
636                 cFYI(1, "Signing disabled");
637                 if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
638                         cERROR(1, "Server requires "
639                                    "packet signing to be enabled in "
640                                    "/proc/fs/cifs/SecurityFlags.");
641                         rc = -EOPNOTSUPP;
642                 }
643                 server->sec_mode &=
644                         ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
645         } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
646                 /* signing required */
647                 cFYI(1, "Must sign - secFlags 0x%x", secFlags);
648                 if ((server->sec_mode &
649                         (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
650                         cERROR(1, "signing required but server lacks support");
651                         rc = -EOPNOTSUPP;
652                 } else
653                         server->sec_mode |= SECMODE_SIGN_REQUIRED;
654         } else {
655                 /* signing optional ie CIFSSEC_MAY_SIGN */
656                 if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
657                         server->sec_mode &=
658                                 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
659         }
660
661 neg_err_exit:
662         cifs_buf_release(pSMB);
663
664         cFYI(1, "negprot rc %d", rc);
665         return rc;
666 }
667
668 int
669 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
670 {
671         struct smb_hdr *smb_buffer;
672         int rc = 0;
673
674         cFYI(1, "In tree disconnect");
675
676         /* BB: do we need to check this? These should never be NULL. */
677         if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
678                 return -EIO;
679
680         /*
681          * No need to return error on this operation if tid invalidated and
682          * closed on server already e.g. due to tcp session crashing. Also,
683          * the tcon is no longer on the list, so no need to take lock before
684          * checking this.
685          */
686         if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
687                 return 0;
688
689         rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
690                             (void **)&smb_buffer);
691         if (rc)
692                 return rc;
693
694         rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
695         if (rc)
696                 cFYI(1, "Tree disconnect failed %d", rc);
697
698         /* No need to return error on this operation if tid invalidated and
699            closed on server already e.g. due to tcp session crashing */
700         if (rc == -EAGAIN)
701                 rc = 0;
702
703         return rc;
704 }
705
706 /*
707  * This is a no-op for now. We're not really interested in the reply, but
708  * rather in the fact that the server sent one and that server->lstrp
709  * gets updated.
710  *
711  * FIXME: maybe we should consider checking that the reply matches request?
712  */
713 static void
714 cifs_echo_callback(struct mid_q_entry *mid)
715 {
716         struct TCP_Server_Info *server = mid->callback_data;
717
718         DeleteMidQEntry(mid);
719         add_credits(server, 1, CIFS_ECHO_OP);
720 }
721
722 int
723 CIFSSMBEcho(struct TCP_Server_Info *server)
724 {
725         ECHO_REQ *smb;
726         int rc = 0;
727         struct kvec iov;
728         struct smb_rqst rqst = { .rq_iov = &iov,
729                                  .rq_nvec = 1 };
730
731         cFYI(1, "In echo request");
732
733         rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
734         if (rc)
735                 return rc;
736
737         /* set up echo request */
738         smb->hdr.Tid = 0xffff;
739         smb->hdr.WordCount = 1;
740         put_unaligned_le16(1, &smb->EchoCount);
741         put_bcc(1, &smb->hdr);
742         smb->Data[0] = 'a';
743         inc_rfc1001_len(smb, 3);
744         iov.iov_base = smb;
745         iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
746
747         rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback,
748                              server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
749         if (rc)
750                 cFYI(1, "Echo request failed: %d", rc);
751
752         cifs_small_buf_release(smb);
753
754         return rc;
755 }
756
757 int
758 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
759 {
760         LOGOFF_ANDX_REQ *pSMB;
761         int rc = 0;
762
763         cFYI(1, "In SMBLogoff for session disconnect");
764
765         /*
766          * BB: do we need to check validity of ses and server? They should
767          * always be valid since we have an active reference. If not, that
768          * should probably be a BUG()
769          */
770         if (!ses || !ses->server)
771                 return -EIO;
772
773         mutex_lock(&ses->session_mutex);
774         if (ses->need_reconnect)
775                 goto session_already_dead; /* no need to send SMBlogoff if uid
776                                               already closed due to reconnect */
777         rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
778         if (rc) {
779                 mutex_unlock(&ses->session_mutex);
780                 return rc;
781         }
782
783         pSMB->hdr.Mid = get_next_mid(ses->server);
784
785         if (ses->server->sec_mode &
786                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
787                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
788
789         pSMB->hdr.Uid = ses->Suid;
790
791         pSMB->AndXCommand = 0xFF;
792         rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
793 session_already_dead:
794         mutex_unlock(&ses->session_mutex);
795
796         /* if session dead then we do not need to do ulogoff,
797                 since server closed smb session, no sense reporting
798                 error */
799         if (rc == -EAGAIN)
800                 rc = 0;
801         return rc;
802 }
803
804 int
805 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
806                  const char *fileName, __u16 type,
807                  const struct nls_table *nls_codepage, int remap)
808 {
809         TRANSACTION2_SPI_REQ *pSMB = NULL;
810         TRANSACTION2_SPI_RSP *pSMBr = NULL;
811         struct unlink_psx_rq *pRqD;
812         int name_len;
813         int rc = 0;
814         int bytes_returned = 0;
815         __u16 params, param_offset, offset, byte_count;
816
817         cFYI(1, "In POSIX delete");
818 PsxDelete:
819         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
820                       (void **) &pSMBr);
821         if (rc)
822                 return rc;
823
824         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
825                 name_len =
826                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
827                                        PATH_MAX, nls_codepage, remap);
828                 name_len++;     /* trailing null */
829                 name_len *= 2;
830         } else { /* BB add path length overrun check */
831                 name_len = strnlen(fileName, PATH_MAX);
832                 name_len++;     /* trailing null */
833                 strncpy(pSMB->FileName, fileName, name_len);
834         }
835
836         params = 6 + name_len;
837         pSMB->MaxParameterCount = cpu_to_le16(2);
838         pSMB->MaxDataCount = 0; /* BB double check this with jra */
839         pSMB->MaxSetupCount = 0;
840         pSMB->Reserved = 0;
841         pSMB->Flags = 0;
842         pSMB->Timeout = 0;
843         pSMB->Reserved2 = 0;
844         param_offset = offsetof(struct smb_com_transaction2_spi_req,
845                                 InformationLevel) - 4;
846         offset = param_offset + params;
847
848         /* Setup pointer to Request Data (inode type) */
849         pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
850         pRqD->type = cpu_to_le16(type);
851         pSMB->ParameterOffset = cpu_to_le16(param_offset);
852         pSMB->DataOffset = cpu_to_le16(offset);
853         pSMB->SetupCount = 1;
854         pSMB->Reserved3 = 0;
855         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
856         byte_count = 3 /* pad */  + params + sizeof(struct unlink_psx_rq);
857
858         pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
859         pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
860         pSMB->ParameterCount = cpu_to_le16(params);
861         pSMB->TotalParameterCount = pSMB->ParameterCount;
862         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
863         pSMB->Reserved4 = 0;
864         inc_rfc1001_len(pSMB, byte_count);
865         pSMB->ByteCount = cpu_to_le16(byte_count);
866         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
867                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
868         if (rc)
869                 cFYI(1, "Posix delete returned %d", rc);
870         cifs_buf_release(pSMB);
871
872         cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
873
874         if (rc == -EAGAIN)
875                 goto PsxDelete;
876
877         return rc;
878 }
879
880 int
881 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
882                struct cifs_sb_info *cifs_sb)
883 {
884         DELETE_FILE_REQ *pSMB = NULL;
885         DELETE_FILE_RSP *pSMBr = NULL;
886         int rc = 0;
887         int bytes_returned;
888         int name_len;
889         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
890
891 DelFileRetry:
892         rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
893                       (void **) &pSMBr);
894         if (rc)
895                 return rc;
896
897         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
898                 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
899                                               PATH_MAX, cifs_sb->local_nls,
900                                               remap);
901                 name_len++;     /* trailing null */
902                 name_len *= 2;
903         } else {                /* BB improve check for buffer overruns BB */
904                 name_len = strnlen(name, PATH_MAX);
905                 name_len++;     /* trailing null */
906                 strncpy(pSMB->fileName, name, name_len);
907         }
908         pSMB->SearchAttributes =
909             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
910         pSMB->BufferFormat = 0x04;
911         inc_rfc1001_len(pSMB, name_len + 1);
912         pSMB->ByteCount = cpu_to_le16(name_len + 1);
913         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
914                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
915         cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
916         if (rc)
917                 cFYI(1, "Error in RMFile = %d", rc);
918
919         cifs_buf_release(pSMB);
920         if (rc == -EAGAIN)
921                 goto DelFileRetry;
922
923         return rc;
924 }
925
926 int
927 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
928              struct cifs_sb_info *cifs_sb)
929 {
930         DELETE_DIRECTORY_REQ *pSMB = NULL;
931         DELETE_DIRECTORY_RSP *pSMBr = NULL;
932         int rc = 0;
933         int bytes_returned;
934         int name_len;
935         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
936
937         cFYI(1, "In CIFSSMBRmDir");
938 RmDirRetry:
939         rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
940                       (void **) &pSMBr);
941         if (rc)
942                 return rc;
943
944         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
945                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
946                                               PATH_MAX, cifs_sb->local_nls,
947                                               remap);
948                 name_len++;     /* trailing null */
949                 name_len *= 2;
950         } else {                /* BB improve check for buffer overruns BB */
951                 name_len = strnlen(name, PATH_MAX);
952                 name_len++;     /* trailing null */
953                 strncpy(pSMB->DirName, name, name_len);
954         }
955
956         pSMB->BufferFormat = 0x04;
957         inc_rfc1001_len(pSMB, name_len + 1);
958         pSMB->ByteCount = cpu_to_le16(name_len + 1);
959         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
960                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
961         cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
962         if (rc)
963                 cFYI(1, "Error in RMDir = %d", rc);
964
965         cifs_buf_release(pSMB);
966         if (rc == -EAGAIN)
967                 goto RmDirRetry;
968         return rc;
969 }
970
971 int
972 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
973              struct cifs_sb_info *cifs_sb)
974 {
975         int rc = 0;
976         CREATE_DIRECTORY_REQ *pSMB = NULL;
977         CREATE_DIRECTORY_RSP *pSMBr = NULL;
978         int bytes_returned;
979         int name_len;
980         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
981
982         cFYI(1, "In CIFSSMBMkDir");
983 MkDirRetry:
984         rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
985                       (void **) &pSMBr);
986         if (rc)
987                 return rc;
988
989         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
990                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
991                                               PATH_MAX, cifs_sb->local_nls,
992                                               remap);
993                 name_len++;     /* trailing null */
994                 name_len *= 2;
995         } else {                /* BB improve check for buffer overruns BB */
996                 name_len = strnlen(name, PATH_MAX);
997                 name_len++;     /* trailing null */
998                 strncpy(pSMB->DirName, name, name_len);
999         }
1000
1001         pSMB->BufferFormat = 0x04;
1002         inc_rfc1001_len(pSMB, name_len + 1);
1003         pSMB->ByteCount = cpu_to_le16(name_len + 1);
1004         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1005                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1006         cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1007         if (rc)
1008                 cFYI(1, "Error in Mkdir = %d", rc);
1009
1010         cifs_buf_release(pSMB);
1011         if (rc == -EAGAIN)
1012                 goto MkDirRetry;
1013         return rc;
1014 }
1015
1016 int
1017 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1018                 __u32 posix_flags, __u64 mode, __u16 *netfid,
1019                 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1020                 const char *name, const struct nls_table *nls_codepage,
1021                 int remap)
1022 {
1023         TRANSACTION2_SPI_REQ *pSMB = NULL;
1024         TRANSACTION2_SPI_RSP *pSMBr = NULL;
1025         int name_len;
1026         int rc = 0;
1027         int bytes_returned = 0;
1028         __u16 params, param_offset, offset, byte_count, count;
1029         OPEN_PSX_REQ *pdata;
1030         OPEN_PSX_RSP *psx_rsp;
1031
1032         cFYI(1, "In POSIX Create");
1033 PsxCreat:
1034         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1035                       (void **) &pSMBr);
1036         if (rc)
1037                 return rc;
1038
1039         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1040                 name_len =
1041                     cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1042                                        PATH_MAX, nls_codepage, remap);
1043                 name_len++;     /* trailing null */
1044                 name_len *= 2;
1045         } else {        /* BB improve the check for buffer overruns BB */
1046                 name_len = strnlen(name, PATH_MAX);
1047                 name_len++;     /* trailing null */
1048                 strncpy(pSMB->FileName, name, name_len);
1049         }
1050
1051         params = 6 + name_len;
1052         count = sizeof(OPEN_PSX_REQ);
1053         pSMB->MaxParameterCount = cpu_to_le16(2);
1054         pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1055         pSMB->MaxSetupCount = 0;
1056         pSMB->Reserved = 0;
1057         pSMB->Flags = 0;
1058         pSMB->Timeout = 0;
1059         pSMB->Reserved2 = 0;
1060         param_offset = offsetof(struct smb_com_transaction2_spi_req,
1061                                 InformationLevel) - 4;
1062         offset = param_offset + params;
1063         pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1064         pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1065         pdata->Permissions = cpu_to_le64(mode);
1066         pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1067         pdata->OpenFlags =  cpu_to_le32(*pOplock);
1068         pSMB->ParameterOffset = cpu_to_le16(param_offset);
1069         pSMB->DataOffset = cpu_to_le16(offset);
1070         pSMB->SetupCount = 1;
1071         pSMB->Reserved3 = 0;
1072         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1073         byte_count = 3 /* pad */  + params + count;
1074
1075         pSMB->DataCount = cpu_to_le16(count);
1076         pSMB->ParameterCount = cpu_to_le16(params);
1077         pSMB->TotalDataCount = pSMB->DataCount;
1078         pSMB->TotalParameterCount = pSMB->ParameterCount;
1079         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1080         pSMB->Reserved4 = 0;
1081         inc_rfc1001_len(pSMB, byte_count);
1082         pSMB->ByteCount = cpu_to_le16(byte_count);
1083         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1084                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1085         if (rc) {
1086                 cFYI(1, "Posix create returned %d", rc);
1087                 goto psx_create_err;
1088         }
1089
1090         cFYI(1, "copying inode info");
1091         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1092
1093         if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1094                 rc = -EIO;      /* bad smb */
1095                 goto psx_create_err;
1096         }
1097
1098         /* copy return information to pRetData */
1099         psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1100                         + le16_to_cpu(pSMBr->t2.DataOffset));
1101
1102         *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1103         if (netfid)
1104                 *netfid = psx_rsp->Fid;   /* cifs fid stays in le */
1105         /* Let caller know file was created so we can set the mode. */
1106         /* Do we care about the CreateAction in any other cases? */
1107         if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1108                 *pOplock |= CIFS_CREATE_ACTION;
1109         /* check to make sure response data is there */
1110         if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1111                 pRetData->Type = cpu_to_le32(-1); /* unknown */
1112                 cFYI(DBG2, "unknown type");
1113         } else {
1114                 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1115                                         + sizeof(FILE_UNIX_BASIC_INFO)) {
1116                         cERROR(1, "Open response data too small");
1117                         pRetData->Type = cpu_to_le32(-1);
1118                         goto psx_create_err;
1119                 }
1120                 memcpy((char *) pRetData,
1121                         (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1122                         sizeof(FILE_UNIX_BASIC_INFO));
1123         }
1124
1125 psx_create_err:
1126         cifs_buf_release(pSMB);
1127
1128         if (posix_flags & SMB_O_DIRECTORY)
1129                 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1130         else
1131                 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1132
1133         if (rc == -EAGAIN)
1134                 goto PsxCreat;
1135
1136         return rc;
1137 }
1138
1139 static __u16 convert_disposition(int disposition)
1140 {
1141         __u16 ofun = 0;
1142
1143         switch (disposition) {
1144                 case FILE_SUPERSEDE:
1145                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1146                         break;
1147                 case FILE_OPEN:
1148                         ofun = SMBOPEN_OAPPEND;
1149                         break;
1150                 case FILE_CREATE:
1151                         ofun = SMBOPEN_OCREATE;
1152                         break;
1153                 case FILE_OPEN_IF:
1154                         ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1155                         break;
1156                 case FILE_OVERWRITE:
1157                         ofun = SMBOPEN_OTRUNC;
1158                         break;
1159                 case FILE_OVERWRITE_IF:
1160                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1161                         break;
1162                 default:
1163                         cFYI(1, "unknown disposition %d", disposition);
1164                         ofun =  SMBOPEN_OAPPEND; /* regular open */
1165         }
1166         return ofun;
1167 }
1168
1169 static int
1170 access_flags_to_smbopen_mode(const int access_flags)
1171 {
1172         int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1173
1174         if (masked_flags == GENERIC_READ)
1175                 return SMBOPEN_READ;
1176         else if (masked_flags == GENERIC_WRITE)
1177                 return SMBOPEN_WRITE;
1178
1179         /* just go for read/write */
1180         return SMBOPEN_READWRITE;
1181 }
1182
1183 int
1184 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1185             const char *fileName, const int openDisposition,
1186             const int access_flags, const int create_options, __u16 *netfid,
1187             int *pOplock, FILE_ALL_INFO *pfile_info,
1188             const struct nls_table *nls_codepage, int remap)
1189 {
1190         int rc = -EACCES;
1191         OPENX_REQ *pSMB = NULL;
1192         OPENX_RSP *pSMBr = NULL;
1193         int bytes_returned;
1194         int name_len;
1195         __u16 count;
1196
1197 OldOpenRetry:
1198         rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1199                       (void **) &pSMBr);
1200         if (rc)
1201                 return rc;
1202
1203         pSMB->AndXCommand = 0xFF;       /* none */
1204
1205         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1206                 count = 1;      /* account for one byte pad to word boundary */
1207                 name_len =
1208                    cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1209                                       fileName, PATH_MAX, nls_codepage, remap);
1210                 name_len++;     /* trailing null */
1211                 name_len *= 2;
1212         } else {                /* BB improve check for buffer overruns BB */
1213                 count = 0;      /* no pad */
1214                 name_len = strnlen(fileName, PATH_MAX);
1215                 name_len++;     /* trailing null */
1216                 strncpy(pSMB->fileName, fileName, name_len);
1217         }
1218         if (*pOplock & REQ_OPLOCK)
1219                 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1220         else if (*pOplock & REQ_BATCHOPLOCK)
1221                 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1222
1223         pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1224         pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1225         pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1226         /* set file as system file if special file such
1227            as fifo and server expecting SFU style and
1228            no Unix extensions */
1229
1230         if (create_options & CREATE_OPTION_SPECIAL)
1231                 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1232         else /* BB FIXME BB */
1233                 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1234
1235         if (create_options & CREATE_OPTION_READONLY)
1236                 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1237
1238         /* BB FIXME BB */
1239 /*      pSMB->CreateOptions = cpu_to_le32(create_options &
1240                                                  CREATE_OPTIONS_MASK); */
1241         /* BB FIXME END BB */
1242
1243         pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1244         pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1245         count += name_len;
1246         inc_rfc1001_len(pSMB, count);
1247
1248         pSMB->ByteCount = cpu_to_le16(count);
1249         /* long_op set to 1 to allow for oplock break timeouts */
1250         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1251                         (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1252         cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1253         if (rc) {
1254                 cFYI(1, "Error in Open = %d", rc);
1255         } else {
1256         /* BB verify if wct == 15 */
1257
1258 /*              *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1259
1260                 *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1261                 /* Let caller know file was created so we can set the mode. */
1262                 /* Do we care about the CreateAction in any other cases? */
1263         /* BB FIXME BB */
1264 /*              if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1265                         *pOplock |= CIFS_CREATE_ACTION; */
1266         /* BB FIXME END */
1267
1268                 if (pfile_info) {
1269                         pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1270                         pfile_info->LastAccessTime = 0; /* BB fixme */
1271                         pfile_info->LastWriteTime = 0; /* BB fixme */
1272                         pfile_info->ChangeTime = 0;  /* BB fixme */
1273                         pfile_info->Attributes =
1274                                 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1275                         /* the file_info buf is endian converted by caller */
1276                         pfile_info->AllocationSize =
1277                                 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1278                         pfile_info->EndOfFile = pfile_info->AllocationSize;
1279                         pfile_info->NumberOfLinks = cpu_to_le32(1);
1280                         pfile_info->DeletePending = 0;
1281                 }
1282         }
1283
1284         cifs_buf_release(pSMB);
1285         if (rc == -EAGAIN)
1286                 goto OldOpenRetry;
1287         return rc;
1288 }
1289
1290 int
1291 CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
1292             const char *fileName, const int openDisposition,
1293             const int access_flags, const int create_options, __u16 *netfid,
1294             int *pOplock, FILE_ALL_INFO *pfile_info,
1295             const struct nls_table *nls_codepage, int remap)
1296 {
1297         int rc = -EACCES;
1298         OPEN_REQ *pSMB = NULL;
1299         OPEN_RSP *pSMBr = NULL;
1300         int bytes_returned;
1301         int name_len;
1302         __u16 count;
1303
1304 openRetry:
1305         rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1306                       (void **) &pSMBr);
1307         if (rc)
1308                 return rc;
1309
1310         pSMB->AndXCommand = 0xFF;       /* none */
1311
1312         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1313                 count = 1;      /* account for one byte pad to word boundary */
1314                 name_len =
1315                     cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1316                                        fileName, PATH_MAX, nls_codepage, remap);
1317                 name_len++;     /* trailing null */
1318                 name_len *= 2;
1319                 pSMB->NameLength = cpu_to_le16(name_len);
1320         } else {                /* BB improve check for buffer overruns BB */
1321                 count = 0;      /* no pad */
1322                 name_len = strnlen(fileName, PATH_MAX);
1323                 name_len++;     /* trailing null */
1324                 pSMB->NameLength = cpu_to_le16(name_len);
1325                 strncpy(pSMB->fileName, fileName, name_len);
1326         }
1327         if (*pOplock & REQ_OPLOCK)
1328                 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1329         else if (*pOplock & REQ_BATCHOPLOCK)
1330                 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1331         pSMB->DesiredAccess = cpu_to_le32(access_flags);
1332         pSMB->AllocationSize = 0;
1333         /* set file as system file if special file such
1334            as fifo and server expecting SFU style and
1335            no Unix extensions */
1336         if (create_options & CREATE_OPTION_SPECIAL)
1337                 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1338         else
1339                 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1340
1341         /* XP does not handle ATTR_POSIX_SEMANTICS */
1342         /* but it helps speed up case sensitive checks for other
1343         servers such as Samba */
1344         if (tcon->ses->capabilities & CAP_UNIX)
1345                 pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1346
1347         if (create_options & CREATE_OPTION_READONLY)
1348                 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1349
1350         pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1351         pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1352         pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1353         /* BB Expirement with various impersonation levels and verify */
1354         pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1355         pSMB->SecurityFlags =
1356             SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1357
1358         count += name_len;
1359         inc_rfc1001_len(pSMB, count);
1360
1361         pSMB->ByteCount = cpu_to_le16(count);
1362         /* long_op set to 1 to allow for oplock break timeouts */
1363         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1364                         (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1365         cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1366         if (rc) {
1367                 cFYI(1, "Error in Open = %d", rc);
1368         } else {
1369                 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1370                 *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1371                 /* Let caller know file was created so we can set the mode. */
1372                 /* Do we care about the CreateAction in any other cases? */
1373                 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1374                         *pOplock |= CIFS_CREATE_ACTION;
1375                 if (pfile_info) {
1376                         memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1377                                 36 /* CreationTime to Attributes */);
1378                         /* the file_info buf is endian converted by caller */
1379                         pfile_info->AllocationSize = pSMBr->AllocationSize;
1380                         pfile_info->EndOfFile = pSMBr->EndOfFile;
1381                         pfile_info->NumberOfLinks = cpu_to_le32(1);
1382                         pfile_info->DeletePending = 0;
1383                 }
1384         }
1385
1386         cifs_buf_release(pSMB);
1387         if (rc == -EAGAIN)
1388                 goto openRetry;
1389         return rc;
1390 }
1391
1392 /*
1393  * Discard any remaining data in the current SMB. To do this, we borrow the
1394  * current bigbuf.
1395  */
1396 static int
1397 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1398 {
1399         unsigned int rfclen = get_rfc1002_length(server->smallbuf);
1400         int remaining = rfclen + 4 - server->total_read;
1401         struct cifs_readdata *rdata = mid->callback_data;
1402
1403         while (remaining > 0) {
1404                 int length;
1405
1406                 length = cifs_read_from_socket(server, server->bigbuf,
1407                                 min_t(unsigned int, remaining,
1408                                     CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1409                 if (length < 0)
1410                         return length;
1411                 server->total_read += length;
1412                 remaining -= length;
1413         }
1414
1415         dequeue_mid(mid, rdata->result);
1416         return 0;
1417 }
1418
1419 int
1420 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1421 {
1422         int length, len;
1423         unsigned int data_offset, data_len;
1424         struct cifs_readdata *rdata = mid->callback_data;
1425         char *buf = server->smallbuf;
1426         unsigned int buflen = get_rfc1002_length(buf) + 4;
1427
1428         cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__,
1429                 mid->mid, rdata->offset, rdata->bytes);
1430
1431         /*
1432          * read the rest of READ_RSP header (sans Data array), or whatever we
1433          * can if there's not enough data. At this point, we've read down to
1434          * the Mid.
1435          */
1436         len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1437                                                         HEADER_SIZE(server) + 1;
1438
1439         rdata->iov.iov_base = buf + HEADER_SIZE(server) - 1;
1440         rdata->iov.iov_len = len;
1441
1442         length = cifs_readv_from_socket(server, &rdata->iov, 1, len);
1443         if (length < 0)
1444                 return length;
1445         server->total_read += length;
1446
1447         /* Was the SMB read successful? */
1448         rdata->result = server->ops->map_error(buf, false);
1449         if (rdata->result != 0) {
1450                 cFYI(1, "%s: server returned error %d", __func__,
1451                         rdata->result);
1452                 return cifs_readv_discard(server, mid);
1453         }
1454
1455         /* Is there enough to get to the rest of the READ_RSP header? */
1456         if (server->total_read < server->vals->read_rsp_size) {
1457                 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1458                         __func__, server->total_read,
1459                         server->vals->read_rsp_size);
1460                 rdata->result = -EIO;
1461                 return cifs_readv_discard(server, mid);
1462         }
1463
1464         data_offset = server->ops->read_data_offset(buf) + 4;
1465         if (data_offset < server->total_read) {
1466                 /*
1467                  * win2k8 sometimes sends an offset of 0 when the read
1468                  * is beyond the EOF. Treat it as if the data starts just after
1469                  * the header.
1470                  */
1471                 cFYI(1, "%s: data offset (%u) inside read response header",
1472                         __func__, data_offset);
1473                 data_offset = server->total_read;
1474         } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1475                 /* data_offset is beyond the end of smallbuf */
1476                 cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
1477                         __func__, data_offset);
1478                 rdata->result = -EIO;
1479                 return cifs_readv_discard(server, mid);
1480         }
1481
1482         cFYI(1, "%s: total_read=%u data_offset=%u", __func__,
1483                 server->total_read, data_offset);
1484
1485         len = data_offset - server->total_read;
1486         if (len > 0) {
1487                 /* read any junk before data into the rest of smallbuf */
1488                 rdata->iov.iov_base = buf + server->total_read;
1489                 rdata->iov.iov_len = len;
1490                 length = cifs_readv_from_socket(server, &rdata->iov, 1, len);
1491                 if (length < 0)
1492                         return length;
1493                 server->total_read += length;
1494         }
1495
1496         /* set up first iov for signature check */
1497         rdata->iov.iov_base = buf;
1498         rdata->iov.iov_len = server->total_read;
1499         cFYI(1, "0: iov_base=%p iov_len=%zu",
1500                 rdata->iov.iov_base, rdata->iov.iov_len);
1501
1502         /* how much data is in the response? */
1503         data_len = server->ops->read_data_length(buf);
1504         if (data_offset + data_len > buflen) {
1505                 /* data_len is corrupt -- discard frame */
1506                 rdata->result = -EIO;
1507                 return cifs_readv_discard(server, mid);
1508         }
1509
1510         length = rdata->read_into_pages(server, rdata, data_len);
1511         if (length < 0)
1512                 return length;
1513
1514         server->total_read += length;
1515         rdata->bytes = length;
1516
1517         cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read,
1518                 buflen, data_len);
1519
1520         /* discard anything left over */
1521         if (server->total_read < buflen)
1522                 return cifs_readv_discard(server, mid);
1523
1524         dequeue_mid(mid, false);
1525         return length;
1526 }
1527
1528 static void
1529 cifs_readv_callback(struct mid_q_entry *mid)
1530 {
1531         struct cifs_readdata *rdata = mid->callback_data;
1532         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1533         struct TCP_Server_Info *server = tcon->ses->server;
1534         struct smb_rqst rqst = { .rq_iov = &rdata->iov,
1535                                  .rq_nvec = 1,
1536                                  .rq_pages = rdata->pages,
1537                                  .rq_npages = rdata->nr_pages,
1538                                  .rq_pagesz = rdata->pagesz,
1539                                  .rq_tailsz = rdata->tailsz };
1540
1541         cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__,
1542                 mid->mid, mid->mid_state, rdata->result, rdata->bytes);
1543
1544         switch (mid->mid_state) {
1545         case MID_RESPONSE_RECEIVED:
1546                 /* result already set, check signature */
1547                 if (server->sec_mode &
1548                     (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1549                         int rc = 0;
1550
1551                         rc = cifs_verify_signature(&rqst, server,
1552                                                   mid->sequence_number + 1);
1553                         if (rc)
1554                                 cERROR(1, "SMB signature verification returned "
1555                                        "error = %d", rc);
1556                 }
1557                 /* FIXME: should this be counted toward the initiating task? */
1558                 task_io_account_read(rdata->bytes);
1559                 cifs_stats_bytes_read(tcon, rdata->bytes);
1560                 break;
1561         case MID_REQUEST_SUBMITTED:
1562         case MID_RETRY_NEEDED:
1563                 rdata->result = -EAGAIN;
1564                 break;
1565         default:
1566                 rdata->result = -EIO;
1567         }
1568
1569         queue_work(cifsiod_wq, &rdata->work);
1570         DeleteMidQEntry(mid);
1571         add_credits(server, 1, 0);
1572 }
1573
1574 /* cifs_async_readv - send an async write, and set up mid to handle result */
1575 int
1576 cifs_async_readv(struct cifs_readdata *rdata)
1577 {
1578         int rc;
1579         READ_REQ *smb = NULL;
1580         int wct;
1581         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1582         struct smb_rqst rqst = { .rq_iov = &rdata->iov,
1583                                  .rq_nvec = 1 };
1584
1585         cFYI(1, "%s: offset=%llu bytes=%u", __func__,
1586                 rdata->offset, rdata->bytes);
1587
1588         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1589                 wct = 12;
1590         else {
1591                 wct = 10; /* old style read */
1592                 if ((rdata->offset >> 32) > 0)  {
1593                         /* can not handle this big offset for old */
1594                         return -EIO;
1595                 }
1596         }
1597
1598         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1599         if (rc)
1600                 return rc;
1601
1602         smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1603         smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1604
1605         smb->AndXCommand = 0xFF;        /* none */
1606         smb->Fid = rdata->cfile->fid.netfid;
1607         smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1608         if (wct == 12)
1609                 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1610         smb->Remaining = 0;
1611         smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1612         smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1613         if (wct == 12)
1614                 smb->ByteCount = 0;
1615         else {
1616                 /* old style read */
1617                 struct smb_com_readx_req *smbr =
1618                         (struct smb_com_readx_req *)smb;
1619                 smbr->ByteCount = 0;
1620         }
1621
1622         /* 4 for RFC1001 length + 1 for BCC */
1623         rdata->iov.iov_base = smb;
1624         rdata->iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1625
1626         kref_get(&rdata->refcount);
1627         rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1628                              cifs_readv_callback, rdata, 0);
1629
1630         if (rc == 0)
1631                 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1632         else
1633                 kref_put(&rdata->refcount, cifs_readdata_release);
1634
1635         cifs_small_buf_release(smb);
1636         return rc;
1637 }
1638
1639 int
1640 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1641             unsigned int *nbytes, char **buf, int *pbuf_type)
1642 {
1643         int rc = -EACCES;
1644         READ_REQ *pSMB = NULL;
1645         READ_RSP *pSMBr = NULL;
1646         char *pReadData = NULL;
1647         int wct;
1648         int resp_buf_type = 0;
1649         struct kvec iov[1];
1650         __u32 pid = io_parms->pid;
1651         __u16 netfid = io_parms->netfid;
1652         __u64 offset = io_parms->offset;
1653         struct cifs_tcon *tcon = io_parms->tcon;
1654         unsigned int count = io_parms->length;
1655
1656         cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1657         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1658                 wct = 12;
1659         else {
1660                 wct = 10; /* old style read */
1661                 if ((offset >> 32) > 0)  {
1662                         /* can not handle this big offset for old */
1663                         return -EIO;
1664                 }
1665         }
1666
1667         *nbytes = 0;
1668         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1669         if (rc)
1670                 return rc;
1671
1672         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1673         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1674
1675         /* tcon and ses pointer are checked in smb_init */
1676         if (tcon->ses->server == NULL)
1677                 return -ECONNABORTED;
1678
1679         pSMB->AndXCommand = 0xFF;       /* none */
1680         pSMB->Fid = netfid;
1681         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1682         if (wct == 12)
1683                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1684
1685         pSMB->Remaining = 0;
1686         pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1687         pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1688         if (wct == 12)
1689                 pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1690         else {
1691                 /* old style read */
1692                 struct smb_com_readx_req *pSMBW =
1693                         (struct smb_com_readx_req *)pSMB;
1694                 pSMBW->ByteCount = 0;
1695         }
1696
1697         iov[0].iov_base = (char *)pSMB;
1698         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1699         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1700                          &resp_buf_type, CIFS_LOG_ERROR);
1701         cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1702         pSMBr = (READ_RSP *)iov[0].iov_base;
1703         if (rc) {
1704                 cERROR(1, "Send error in read = %d", rc);
1705         } else {
1706                 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1707                 data_length = data_length << 16;
1708                 data_length += le16_to_cpu(pSMBr->DataLength);
1709                 *nbytes = data_length;
1710
1711                 /*check that DataLength would not go beyond end of SMB */
1712                 if ((data_length > CIFSMaxBufSize)
1713                                 || (data_length > count)) {
1714                         cFYI(1, "bad length %d for count %d",
1715                                  data_length, count);
1716                         rc = -EIO;
1717                         *nbytes = 0;
1718                 } else {
1719                         pReadData = (char *) (&pSMBr->hdr.Protocol) +
1720                                         le16_to_cpu(pSMBr->DataOffset);
1721 /*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
1722                                 cERROR(1, "Faulting on read rc = %d",rc);
1723                                 rc = -EFAULT;
1724                         }*/ /* can not use copy_to_user when using page cache*/
1725                         if (*buf)
1726                                 memcpy(*buf, pReadData, data_length);
1727                 }
1728         }
1729
1730 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1731         if (*buf) {
1732                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1733                         cifs_small_buf_release(iov[0].iov_base);
1734                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1735                         cifs_buf_release(iov[0].iov_base);
1736         } else if (resp_buf_type != CIFS_NO_BUFFER) {
1737                 /* return buffer to caller to free */
1738                 *buf = iov[0].iov_base;
1739                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1740                         *pbuf_type = CIFS_SMALL_BUFFER;
1741                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1742                         *pbuf_type = CIFS_LARGE_BUFFER;
1743         } /* else no valid buffer on return - leave as null */
1744
1745         /* Note: On -EAGAIN error only caller can retry on handle based calls
1746                 since file handle passed in no longer valid */
1747         return rc;
1748 }
1749
1750
1751 int
1752 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1753              unsigned int *nbytes, const char *buf,
1754              const char __user *ubuf, const int long_op)
1755 {
1756         int rc = -EACCES;
1757         WRITE_REQ *pSMB = NULL;
1758         WRITE_RSP *pSMBr = NULL;
1759         int bytes_returned, wct;
1760         __u32 bytes_sent;
1761         __u16 byte_count;
1762         __u32 pid = io_parms->pid;
1763         __u16 netfid = io_parms->netfid;
1764         __u64 offset = io_parms->offset;
1765         struct cifs_tcon *tcon = io_parms->tcon;
1766         unsigned int count = io_parms->length;
1767
1768         *nbytes = 0;
1769
1770         /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1771         if (tcon->ses == NULL)
1772                 return -ECONNABORTED;
1773
1774         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1775                 wct = 14;
1776         else {
1777                 wct = 12;
1778                 if ((offset >> 32) > 0) {
1779                         /* can not handle big offset for old srv */
1780                         return -EIO;
1781                 }
1782         }
1783
1784         rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1785                       (void **) &pSMBr);
1786         if (rc)
1787                 return rc;
1788
1789         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1790         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1791
1792         /* tcon and ses pointer are checked in smb_init */
1793         if (tcon->ses->server == NULL)
1794                 return -ECONNABORTED;
1795
1796         pSMB->AndXCommand = 0xFF;       /* none */
1797         pSMB->Fid = netfid;
1798         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1799         if (wct == 14)
1800                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1801
1802         pSMB->Reserved = 0xFFFFFFFF;
1803         pSMB->WriteMode = 0;
1804         pSMB->Remaining = 0;
1805
1806         /* Can increase buffer size if buffer is big enough in some cases ie we
1807         can send more if LARGE_WRITE_X capability returned by the server and if
1808         our buffer is big enough or if we convert to iovecs on socket writes
1809         and eliminate the copy to the CIFS buffer */
1810         if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1811                 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1812         } else {
1813                 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1814                          & ~0xFF;
1815         }
1816
1817         if (bytes_sent > count)
1818                 bytes_sent = count;
1819         pSMB->DataOffset =
1820                 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1821         if (buf)
1822                 memcpy(pSMB->Data, buf, bytes_sent);
1823         else if (ubuf) {
1824                 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1825                         cifs_buf_release(pSMB);
1826                         return -EFAULT;
1827                 }
1828         } else if (count != 0) {
1829                 /* No buffer */
1830                 cifs_buf_release(pSMB);
1831                 return -EINVAL;
1832         } /* else setting file size with write of zero bytes */
1833         if (wct == 14)
1834                 byte_count = bytes_sent + 1; /* pad */
1835         else /* wct == 12 */
1836                 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1837
1838         pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1839         pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1840         inc_rfc1001_len(pSMB, byte_count);
1841
1842         if (wct == 14)
1843                 pSMB->ByteCount = cpu_to_le16(byte_count);
1844         else { /* old style write has byte count 4 bytes earlier
1845                   so 4 bytes pad  */
1846                 struct smb_com_writex_req *pSMBW =
1847                         (struct smb_com_writex_req *)pSMB;
1848                 pSMBW->ByteCount = cpu_to_le16(byte_count);
1849         }
1850
1851         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1852                          (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1853         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1854         if (rc) {
1855                 cFYI(1, "Send error in write = %d", rc);
1856         } else {
1857                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1858                 *nbytes = (*nbytes) << 16;
1859                 *nbytes += le16_to_cpu(pSMBr->Count);
1860
1861                 /*
1862                  * Mask off high 16 bits when bytes written as returned by the
1863                  * server is greater than bytes requested by the client. Some
1864                  * OS/2 servers are known to set incorrect CountHigh values.
1865                  */
1866                 if (*nbytes > count)
1867                         *nbytes &= 0xFFFF;
1868         }
1869
1870         cifs_buf_release(pSMB);
1871
1872         /* Note: On -EAGAIN error only caller can retry on handle based calls
1873                 since file handle passed in no longer valid */
1874
1875         return rc;
1876 }
1877
1878 void
1879 cifs_writedata_release(struct kref *refcount)
1880 {
1881         struct cifs_writedata *wdata = container_of(refcount,
1882                                         struct cifs_writedata, refcount);
1883
1884         if (wdata->cfile)
1885                 cifsFileInfo_put(wdata->cfile);
1886
1887         kfree(wdata);
1888 }
1889
1890 /*
1891  * Write failed with a retryable error. Resend the write request. It's also
1892  * possible that the page was redirtied so re-clean the page.
1893  */
1894 static void
1895 cifs_writev_requeue(struct cifs_writedata *wdata)
1896 {
1897         int i, rc;
1898         struct inode *inode = wdata->cfile->dentry->d_inode;
1899         struct TCP_Server_Info *server;
1900
1901         for (i = 0; i < wdata->nr_pages; i++) {
1902                 lock_page(wdata->pages[i]);
1903                 clear_page_dirty_for_io(wdata->pages[i]);
1904         }
1905
1906         do {
1907                 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1908                 rc = server->ops->async_writev(wdata);
1909         } while (rc == -EAGAIN);
1910
1911         for (i = 0; i < wdata->nr_pages; i++) {
1912                 unlock_page(wdata->pages[i]);
1913                 if (rc != 0) {
1914                         SetPageError(wdata->pages[i]);
1915                         end_page_writeback(wdata->pages[i]);
1916                         page_cache_release(wdata->pages[i]);
1917                 }
1918         }
1919
1920         mapping_set_error(inode->i_mapping, rc);
1921         kref_put(&wdata->refcount, cifs_writedata_release);
1922 }
1923
1924 void
1925 cifs_writev_complete(struct work_struct *work)
1926 {
1927         struct cifs_writedata *wdata = container_of(work,
1928                                                 struct cifs_writedata, work);
1929         struct inode *inode = wdata->cfile->dentry->d_inode;
1930         int i = 0;
1931
1932         if (wdata->result == 0) {
1933                 spin_lock(&inode->i_lock);
1934                 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
1935                 spin_unlock(&inode->i_lock);
1936                 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
1937                                          wdata->bytes);
1938         } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
1939                 return cifs_writev_requeue(wdata);
1940
1941         for (i = 0; i < wdata->nr_pages; i++) {
1942                 struct page *page = wdata->pages[i];
1943                 if (wdata->result == -EAGAIN)
1944                         __set_page_dirty_nobuffers(page);
1945                 else if (wdata->result < 0)
1946                         SetPageError(page);
1947                 end_page_writeback(page);
1948                 page_cache_release(page);
1949         }
1950         if (wdata->result != -EAGAIN)
1951                 mapping_set_error(inode->i_mapping, wdata->result);
1952         kref_put(&wdata->refcount, cifs_writedata_release);
1953 }
1954
1955 struct cifs_writedata *
1956 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
1957 {
1958         struct cifs_writedata *wdata;
1959
1960         /* this would overflow */
1961         if (nr_pages == 0) {
1962                 cERROR(1, "%s: called with nr_pages == 0!", __func__);
1963                 return NULL;
1964         }
1965
1966         /* writedata + number of page pointers */
1967         wdata = kzalloc(sizeof(*wdata) +
1968                         sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
1969         if (wdata != NULL) {
1970                 kref_init(&wdata->refcount);
1971                 INIT_LIST_HEAD(&wdata->list);
1972                 init_completion(&wdata->done);
1973                 INIT_WORK(&wdata->work, complete);
1974         }
1975         return wdata;
1976 }
1977
1978 /*
1979  * Check the mid_state and signature on received buffer (if any), and queue the
1980  * workqueue completion task.
1981  */
1982 static void
1983 cifs_writev_callback(struct mid_q_entry *mid)
1984 {
1985         struct cifs_writedata *wdata = mid->callback_data;
1986         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1987         unsigned int written;
1988         WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1989
1990         switch (mid->mid_state) {
1991         case MID_RESPONSE_RECEIVED:
1992                 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1993                 if (wdata->result != 0)
1994                         break;
1995
1996                 written = le16_to_cpu(smb->CountHigh);
1997                 written <<= 16;
1998                 written += le16_to_cpu(smb->Count);
1999                 /*
2000                  * Mask off high 16 bits when bytes written as returned
2001                  * by the server is greater than bytes requested by the
2002                  * client. OS/2 servers are known to set incorrect
2003                  * CountHigh values.
2004                  */
2005                 if (written > wdata->bytes)
2006                         written &= 0xFFFF;
2007
2008                 if (written < wdata->bytes)
2009                         wdata->result = -ENOSPC;
2010                 else
2011                         wdata->bytes = written;
2012                 break;
2013         case MID_REQUEST_SUBMITTED:
2014         case MID_RETRY_NEEDED:
2015                 wdata->result = -EAGAIN;
2016                 break;
2017         default:
2018                 wdata->result = -EIO;
2019                 break;
2020         }
2021
2022         queue_work(cifsiod_wq, &wdata->work);
2023         DeleteMidQEntry(mid);
2024         add_credits(tcon->ses->server, 1, 0);
2025 }
2026
2027 /* cifs_async_writev - send an async write, and set up mid to handle result */
2028 int
2029 cifs_async_writev(struct cifs_writedata *wdata)
2030 {
2031         int rc = -EACCES;
2032         WRITE_REQ *smb = NULL;
2033         int wct;
2034         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2035         struct kvec iov;
2036         struct smb_rqst rqst = { };
2037
2038         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2039                 wct = 14;
2040         } else {
2041                 wct = 12;
2042                 if (wdata->offset >> 32 > 0) {
2043                         /* can not handle big offset for old srv */
2044                         return -EIO;
2045                 }
2046         }
2047
2048         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2049         if (rc)
2050                 goto async_writev_out;
2051
2052         smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2053         smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2054
2055         smb->AndXCommand = 0xFF;        /* none */
2056         smb->Fid = wdata->cfile->fid.netfid;
2057         smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2058         if (wct == 14)
2059                 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2060         smb->Reserved = 0xFFFFFFFF;
2061         smb->WriteMode = 0;
2062         smb->Remaining = 0;
2063
2064         smb->DataOffset =
2065             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2066
2067         /* 4 for RFC1001 length + 1 for BCC */
2068         iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2069         iov.iov_base = smb;
2070
2071         rqst.rq_iov = &iov;
2072         rqst.rq_nvec = 1;
2073         rqst.rq_pages = wdata->pages;
2074         rqst.rq_npages = wdata->nr_pages;
2075         rqst.rq_pagesz = wdata->pagesz;
2076         rqst.rq_tailsz = wdata->tailsz;
2077
2078         cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2079
2080         smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2081         smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2082
2083         if (wct == 14) {
2084                 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2085                 put_bcc(wdata->bytes + 1, &smb->hdr);
2086         } else {
2087                 /* wct == 12 */
2088                 struct smb_com_writex_req *smbw =
2089                                 (struct smb_com_writex_req *)smb;
2090                 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2091                 put_bcc(wdata->bytes + 5, &smbw->hdr);
2092                 iov.iov_len += 4; /* pad bigger by four bytes */
2093         }
2094
2095         kref_get(&wdata->refcount);
2096         rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2097                                 cifs_writev_callback, wdata, 0);
2098
2099         if (rc == 0)
2100                 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2101         else
2102                 kref_put(&wdata->refcount, cifs_writedata_release);
2103
2104 async_writev_out:
2105         cifs_small_buf_release(smb);
2106         return rc;
2107 }
2108
2109 int
2110 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2111               unsigned int *nbytes, struct kvec *iov, int n_vec)
2112 {
2113         int rc = -EACCES;
2114         WRITE_REQ *pSMB = NULL;
2115         int wct;
2116         int smb_hdr_len;
2117         int resp_buf_type = 0;
2118         __u32 pid = io_parms->pid;
2119         __u16 netfid = io_parms->netfid;
2120         __u64 offset = io_parms->offset;
2121         struct cifs_tcon *tcon = io_parms->tcon;
2122         unsigned int count = io_parms->length;
2123
2124         *nbytes = 0;
2125
2126         cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
2127
2128         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2129                 wct = 14;
2130         } else {
2131                 wct = 12;
2132                 if ((offset >> 32) > 0) {
2133                         /* can not handle big offset for old srv */
2134                         return -EIO;
2135                 }
2136         }
2137         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2138         if (rc)
2139                 return rc;
2140
2141         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2142         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2143
2144         /* tcon and ses pointer are checked in smb_init */
2145         if (tcon->ses->server == NULL)
2146                 return -ECONNABORTED;
2147
2148         pSMB->AndXCommand = 0xFF;       /* none */
2149         pSMB->Fid = netfid;
2150         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2151         if (wct == 14)
2152                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2153         pSMB->Reserved = 0xFFFFFFFF;
2154         pSMB->WriteMode = 0;
2155         pSMB->Remaining = 0;
2156
2157         pSMB->DataOffset =
2158             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2159
2160         pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2161         pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2162         /* header + 1 byte pad */
2163         smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2164         if (wct == 14)
2165                 inc_rfc1001_len(pSMB, count + 1);
2166         else /* wct == 12 */
2167                 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2168         if (wct == 14)
2169                 pSMB->ByteCount = cpu_to_le16(count + 1);
2170         else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2171                 struct smb_com_writex_req *pSMBW =
2172                                 (struct smb_com_writex_req *)pSMB;
2173                 pSMBW->ByteCount = cpu_to_le16(count + 5);
2174         }
2175         iov[0].iov_base = pSMB;
2176         if (wct == 14)
2177                 iov[0].iov_len = smb_hdr_len + 4;
2178         else /* wct == 12 pad bigger by four bytes */
2179                 iov[0].iov_len = smb_hdr_len + 8;
2180
2181
2182         rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0);
2183         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2184         if (rc) {
2185                 cFYI(1, "Send error Write2 = %d", rc);
2186         } else if (resp_buf_type == 0) {
2187                 /* presumably this can not happen, but best to be safe */
2188                 rc = -EIO;
2189         } else {
2190                 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2191                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2192                 *nbytes = (*nbytes) << 16;
2193                 *nbytes += le16_to_cpu(pSMBr->Count);
2194
2195                 /*
2196                  * Mask off high 16 bits when bytes written as returned by the
2197                  * server is greater than bytes requested by the client. OS/2
2198                  * servers are known to set incorrect CountHigh values.
2199                  */
2200                 if (*nbytes > count)
2201                         *nbytes &= 0xFFFF;
2202         }
2203
2204 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2205         if (resp_buf_type == CIFS_SMALL_BUFFER)
2206                 cifs_small_buf_release(iov[0].iov_base);
2207         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2208                 cifs_buf_release(iov[0].iov_base);
2209
2210         /* Note: On -EAGAIN error only caller can retry on handle based calls
2211                 since file handle passed in no longer valid */
2212
2213         return rc;
2214 }
2215
2216 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2217                const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2218                const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2219 {
2220         int rc = 0;
2221         LOCK_REQ *pSMB = NULL;
2222         struct kvec iov[2];
2223         int resp_buf_type;
2224         __u16 count;
2225
2226         cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2227
2228         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2229         if (rc)
2230                 return rc;
2231
2232         pSMB->Timeout = 0;
2233         pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2234         pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2235         pSMB->LockType = lock_type;
2236         pSMB->AndXCommand = 0xFF; /* none */
2237         pSMB->Fid = netfid; /* netfid stays le */
2238
2239         count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2240         inc_rfc1001_len(pSMB, count);
2241         pSMB->ByteCount = cpu_to_le16(count);
2242
2243         iov[0].iov_base = (char *)pSMB;
2244         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2245                          (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2246         iov[1].iov_base = (char *)buf;
2247         iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2248
2249         cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2250         rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2251         if (rc)
2252                 cFYI(1, "Send error in cifs_lockv = %d", rc);
2253
2254         return rc;
2255 }
2256
2257 int
2258 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2259             const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2260             const __u64 offset, const __u32 numUnlock,
2261             const __u32 numLock, const __u8 lockType,
2262             const bool waitFlag, const __u8 oplock_level)
2263 {
2264         int rc = 0;
2265         LOCK_REQ *pSMB = NULL;
2266 /*      LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2267         int bytes_returned;
2268         int flags = 0;
2269         __u16 count;
2270
2271         cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2272         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2273
2274         if (rc)
2275                 return rc;
2276
2277         if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2278                 /* no response expected */
2279                 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2280                 pSMB->Timeout = 0;
2281         } else if (waitFlag) {
2282                 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2283                 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2284         } else {
2285                 pSMB->Timeout = 0;
2286         }
2287
2288         pSMB->NumberOfLocks = cpu_to_le16(numLock);
2289         pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2290         pSMB->LockType = lockType;
2291         pSMB->OplockLevel = oplock_level;
2292         pSMB->AndXCommand = 0xFF;       /* none */
2293         pSMB->Fid = smb_file_id; /* netfid stays le */
2294
2295         if ((numLock != 0) || (numUnlock != 0)) {
2296                 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2297                 /* BB where to store pid high? */
2298                 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2299                 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2300                 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2301                 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2302                 count = sizeof(LOCKING_ANDX_RANGE);
2303         } else {
2304                 /* oplock break */
2305                 count = 0;
2306         }
2307         inc_rfc1001_len(pSMB, count);
2308         pSMB->ByteCount = cpu_to_le16(count);
2309
2310         if (waitFlag) {
2311                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2312                         (struct smb_hdr *) pSMB, &bytes_returned);
2313                 cifs_small_buf_release(pSMB);
2314         } else {
2315                 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2316                 /* SMB buffer freed by function above */
2317         }
2318         cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2319         if (rc)
2320                 cFYI(1, "Send error in Lock = %d", rc);
2321
2322         /* Note: On -EAGAIN error only caller can retry on handle based calls
2323         since file handle passed in no longer valid */
2324         return rc;
2325 }
2326
2327 int
2328 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2329                 const __u16 smb_file_id, const __u32 netpid,
2330                 const loff_t start_offset, const __u64 len,
2331                 struct file_lock *pLockData, const __u16 lock_type,
2332                 const bool waitFlag)
2333 {
2334         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2335         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2336         struct cifs_posix_lock *parm_data;
2337         int rc = 0;
2338         int timeout = 0;
2339         int bytes_returned = 0;
2340         int resp_buf_type = 0;
2341         __u16 params, param_offset, offset, byte_count, count;
2342         struct kvec iov[1];
2343
2344         cFYI(1, "Posix Lock");
2345
2346         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2347
2348         if (rc)
2349                 return rc;
2350
2351         pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2352
2353         params = 6;
2354         pSMB->MaxSetupCount = 0;
2355         pSMB->Reserved = 0;
2356         pSMB->Flags = 0;
2357         pSMB->Reserved2 = 0;
2358         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2359         offset = param_offset + params;
2360
2361         count = sizeof(struct cifs_posix_lock);
2362         pSMB->MaxParameterCount = cpu_to_le16(2);
2363         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2364         pSMB->SetupCount = 1;
2365         pSMB->Reserved3 = 0;
2366         if (pLockData)
2367                 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2368         else
2369                 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2370         byte_count = 3 /* pad */  + params + count;
2371         pSMB->DataCount = cpu_to_le16(count);
2372         pSMB->ParameterCount = cpu_to_le16(params);
2373         pSMB->TotalDataCount = pSMB->DataCount;
2374         pSMB->TotalParameterCount = pSMB->ParameterCount;
2375         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2376         parm_data = (struct cifs_posix_lock *)
2377                         (((char *) &pSMB->hdr.Protocol) + offset);
2378
2379         parm_data->lock_type = cpu_to_le16(lock_type);
2380         if (waitFlag) {
2381                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2382                 parm_data->lock_flags = cpu_to_le16(1);
2383                 pSMB->Timeout = cpu_to_le32(-1);
2384         } else
2385                 pSMB->Timeout = 0;
2386
2387         parm_data->pid = cpu_to_le32(netpid);
2388         parm_data->start = cpu_to_le64(start_offset);
2389         parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2390
2391         pSMB->DataOffset = cpu_to_le16(offset);
2392         pSMB->Fid = smb_file_id;
2393         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2394         pSMB->Reserved4 = 0;
2395         inc_rfc1001_len(pSMB, byte_count);
2396         pSMB->ByteCount = cpu_to_le16(byte_count);
2397         if (waitFlag) {
2398                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2399                         (struct smb_hdr *) pSMBr, &bytes_returned);
2400         } else {
2401                 iov[0].iov_base = (char *)pSMB;
2402                 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2403                 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2404                                 &resp_buf_type, timeout);
2405                 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2406                                 not try to free it twice below on exit */
2407                 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2408         }
2409
2410         if (rc) {
2411                 cFYI(1, "Send error in Posix Lock = %d", rc);
2412         } else if (pLockData) {
2413                 /* lock structure can be returned on get */
2414                 __u16 data_offset;
2415                 __u16 data_count;
2416                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2417
2418                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2419                         rc = -EIO;      /* bad smb */
2420                         goto plk_err_exit;
2421                 }
2422                 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2423                 data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2424                 if (data_count < sizeof(struct cifs_posix_lock)) {
2425                         rc = -EIO;
2426                         goto plk_err_exit;
2427                 }
2428                 parm_data = (struct cifs_posix_lock *)
2429                         ((char *)&pSMBr->hdr.Protocol + data_offset);
2430                 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2431                         pLockData->fl_type = F_UNLCK;
2432                 else {
2433                         if (parm_data->lock_type ==
2434                                         __constant_cpu_to_le16(CIFS_RDLCK))
2435                                 pLockData->fl_type = F_RDLCK;
2436                         else if (parm_data->lock_type ==
2437                                         __constant_cpu_to_le16(CIFS_WRLCK))
2438                                 pLockData->fl_type = F_WRLCK;
2439
2440                         pLockData->fl_start = le64_to_cpu(parm_data->start);
2441                         pLockData->fl_end = pLockData->fl_start +
2442                                         le64_to_cpu(parm_data->length) - 1;
2443                         pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2444                 }
2445         }
2446
2447 plk_err_exit:
2448         if (pSMB)
2449                 cifs_small_buf_release(pSMB);
2450
2451         if (resp_buf_type == CIFS_SMALL_BUFFER)
2452                 cifs_small_buf_release(iov[0].iov_base);
2453         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2454                 cifs_buf_release(iov[0].iov_base);
2455
2456         /* Note: On -EAGAIN error only caller can retry on handle based calls
2457            since file handle passed in no longer valid */
2458
2459         return rc;
2460 }
2461
2462
2463 int
2464 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2465 {
2466         int rc = 0;
2467         CLOSE_REQ *pSMB = NULL;
2468         cFYI(1, "In CIFSSMBClose");
2469
2470 /* do not retry on dead session on close */
2471         rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2472         if (rc == -EAGAIN)
2473                 return 0;
2474         if (rc)
2475                 return rc;
2476
2477         pSMB->FileID = (__u16) smb_file_id;
2478         pSMB->LastWriteTime = 0xFFFFFFFF;
2479         pSMB->ByteCount = 0;
2480         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2481         cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2482         if (rc) {
2483                 if (rc != -EINTR) {
2484                         /* EINTR is expected when user ctl-c to kill app */
2485                         cERROR(1, "Send error in Close = %d", rc);
2486                 }
2487         }
2488
2489         /* Since session is dead, file will be closed on server already */
2490         if (rc == -EAGAIN)
2491                 rc = 0;
2492
2493         return rc;
2494 }
2495
2496 int
2497 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2498 {
2499         int rc = 0;
2500         FLUSH_REQ *pSMB = NULL;
2501         cFYI(1, "In CIFSSMBFlush");
2502
2503         rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2504         if (rc)
2505                 return rc;
2506
2507         pSMB->FileID = (__u16) smb_file_id;
2508         pSMB->ByteCount = 0;
2509         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2510         cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2511         if (rc)
2512                 cERROR(1, "Send error in Flush = %d", rc);
2513
2514         return rc;
2515 }
2516
2517 int
2518 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2519               const char *from_name, const char *to_name,
2520               struct cifs_sb_info *cifs_sb)
2521 {
2522         int rc = 0;
2523         RENAME_REQ *pSMB = NULL;
2524         RENAME_RSP *pSMBr = NULL;
2525         int bytes_returned;
2526         int name_len, name_len2;
2527         __u16 count;
2528         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
2529
2530         cFYI(1, "In CIFSSMBRename");
2531 renameRetry:
2532         rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2533                       (void **) &pSMBr);
2534         if (rc)
2535                 return rc;
2536
2537         pSMB->BufferFormat = 0x04;
2538         pSMB->SearchAttributes =
2539             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2540                         ATTR_DIRECTORY);
2541
2542         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2543                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2544                                               from_name, PATH_MAX,
2545                                               cifs_sb->local_nls, remap);
2546                 name_len++;     /* trailing null */
2547                 name_len *= 2;
2548                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2549         /* protocol requires ASCII signature byte on Unicode string */
2550                 pSMB->OldFileName[name_len + 1] = 0x00;
2551                 name_len2 =
2552                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2553                                        to_name, PATH_MAX, cifs_sb->local_nls,
2554                                        remap);
2555                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2556                 name_len2 *= 2; /* convert to bytes */
2557         } else {        /* BB improve the check for buffer overruns BB */
2558                 name_len = strnlen(from_name, PATH_MAX);
2559                 name_len++;     /* trailing null */
2560                 strncpy(pSMB->OldFileName, from_name, name_len);
2561                 name_len2 = strnlen(to_name, PATH_MAX);
2562                 name_len2++;    /* trailing null */
2563                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2564                 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2565                 name_len2++;    /* trailing null */
2566                 name_len2++;    /* signature byte */
2567         }
2568
2569         count = 1 /* 1st signature byte */  + name_len + name_len2;
2570         inc_rfc1001_len(pSMB, count);
2571         pSMB->ByteCount = cpu_to_le16(count);
2572
2573         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2574                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2575         cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2576         if (rc)
2577                 cFYI(1, "Send error in rename = %d", rc);
2578
2579         cifs_buf_release(pSMB);
2580
2581         if (rc == -EAGAIN)
2582                 goto renameRetry;
2583
2584         return rc;
2585 }
2586
2587 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2588                 int netfid, const char *target_name,
2589                 const struct nls_table *nls_codepage, int remap)
2590 {
2591         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2592         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2593         struct set_file_rename *rename_info;
2594         char *data_offset;
2595         char dummy_string[30];
2596         int rc = 0;
2597         int bytes_returned = 0;
2598         int len_of_str;
2599         __u16 params, param_offset, offset, count, byte_count;
2600
2601         cFYI(1, "Rename to File by handle");
2602         rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2603                         (void **) &pSMBr);
2604         if (rc)
2605                 return rc;
2606
2607         params = 6;
2608         pSMB->MaxSetupCount = 0;
2609         pSMB->Reserved = 0;
2610         pSMB->Flags = 0;
2611         pSMB->Timeout = 0;
2612         pSMB->Reserved2 = 0;
2613         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2614         offset = param_offset + params;
2615
2616         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2617         rename_info = (struct set_file_rename *) data_offset;
2618         pSMB->MaxParameterCount = cpu_to_le16(2);
2619         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2620         pSMB->SetupCount = 1;
2621         pSMB->Reserved3 = 0;
2622         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2623         byte_count = 3 /* pad */  + params;
2624         pSMB->ParameterCount = cpu_to_le16(params);
2625         pSMB->TotalParameterCount = pSMB->ParameterCount;
2626         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2627         pSMB->DataOffset = cpu_to_le16(offset);
2628         /* construct random name ".cifs_tmp<inodenum><mid>" */
2629         rename_info->overwrite = cpu_to_le32(1);
2630         rename_info->root_fid  = 0;
2631         /* unicode only call */
2632         if (target_name == NULL) {
2633                 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2634                 len_of_str =
2635                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2636                                         dummy_string, 24, nls_codepage, remap);
2637         } else {
2638                 len_of_str =
2639                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2640                                         target_name, PATH_MAX, nls_codepage,
2641                                         remap);
2642         }
2643         rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2644         count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2645         byte_count += count;
2646         pSMB->DataCount = cpu_to_le16(count);
2647         pSMB->TotalDataCount = pSMB->DataCount;
2648         pSMB->Fid = netfid;
2649         pSMB->InformationLevel =
2650                 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2651         pSMB->Reserved4 = 0;
2652         inc_rfc1001_len(pSMB, byte_count);
2653         pSMB->ByteCount = cpu_to_le16(byte_count);
2654         rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2655                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2656         cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2657         if (rc)
2658                 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2659
2660         cifs_buf_release(pSMB);
2661
2662         /* Note: On -EAGAIN error only caller can retry on handle based calls
2663                 since file handle passed in no longer valid */
2664
2665         return rc;
2666 }
2667
2668 int
2669 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2670             const char *fromName, const __u16 target_tid, const char *toName,
2671             const int flags, const struct nls_table *nls_codepage, int remap)
2672 {
2673         int rc = 0;
2674         COPY_REQ *pSMB = NULL;
2675         COPY_RSP *pSMBr = NULL;
2676         int bytes_returned;
2677         int name_len, name_len2;
2678         __u16 count;
2679
2680         cFYI(1, "In CIFSSMBCopy");
2681 copyRetry:
2682         rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2683                         (void **) &pSMBr);
2684         if (rc)
2685                 return rc;
2686
2687         pSMB->BufferFormat = 0x04;
2688         pSMB->Tid2 = target_tid;
2689
2690         pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2691
2692         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2693                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2694                                               fromName, PATH_MAX, nls_codepage,
2695                                               remap);
2696                 name_len++;     /* trailing null */
2697                 name_len *= 2;
2698                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2699                 /* protocol requires ASCII signature byte on Unicode string */
2700                 pSMB->OldFileName[name_len + 1] = 0x00;
2701                 name_len2 =
2702                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2703                                        toName, PATH_MAX, nls_codepage, remap);
2704                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2705                 name_len2 *= 2; /* convert to bytes */
2706         } else {        /* BB improve the check for buffer overruns BB */
2707                 name_len = strnlen(fromName, PATH_MAX);
2708                 name_len++;     /* trailing null */
2709                 strncpy(pSMB->OldFileName, fromName, name_len);
2710                 name_len2 = strnlen(toName, PATH_MAX);
2711                 name_len2++;    /* trailing null */
2712                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2713                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2714                 name_len2++;    /* trailing null */
2715                 name_len2++;    /* signature byte */
2716         }
2717
2718         count = 1 /* 1st signature byte */  + name_len + name_len2;
2719         inc_rfc1001_len(pSMB, count);
2720         pSMB->ByteCount = cpu_to_le16(count);
2721
2722         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2723                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2724         if (rc) {
2725                 cFYI(1, "Send error in copy = %d with %d files copied",
2726                         rc, le16_to_cpu(pSMBr->CopyCount));
2727         }
2728         cifs_buf_release(pSMB);
2729
2730         if (rc == -EAGAIN)
2731                 goto copyRetry;
2732
2733         return rc;
2734 }
2735
2736 int
2737 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2738                       const char *fromName, const char *toName,
2739                       const struct nls_table *nls_codepage)
2740 {
2741         TRANSACTION2_SPI_REQ *pSMB = NULL;
2742         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2743         char *data_offset;
2744         int name_len;
2745         int name_len_target;
2746         int rc = 0;
2747         int bytes_returned = 0;
2748         __u16 params, param_offset, offset, byte_count;
2749
2750         cFYI(1, "In Symlink Unix style");
2751 createSymLinkRetry:
2752         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2753                       (void **) &pSMBr);
2754         if (rc)
2755                 return rc;
2756
2757         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2758                 name_len =
2759                     cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2760                                     /* find define for this maxpathcomponent */
2761                                     PATH_MAX, nls_codepage);
2762                 name_len++;     /* trailing null */
2763                 name_len *= 2;
2764
2765         } else {        /* BB improve the check for buffer overruns BB */
2766                 name_len = strnlen(fromName, PATH_MAX);
2767                 name_len++;     /* trailing null */
2768                 strncpy(pSMB->FileName, fromName, name_len);
2769         }
2770         params = 6 + name_len;
2771         pSMB->MaxSetupCount = 0;
2772         pSMB->Reserved = 0;
2773         pSMB->Flags = 0;
2774         pSMB->Timeout = 0;
2775         pSMB->Reserved2 = 0;
2776         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2777                                 InformationLevel) - 4;
2778         offset = param_offset + params;
2779
2780         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2781         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2782                 name_len_target =
2783                     cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2784                                     /* find define for this maxpathcomponent */
2785                                     , nls_codepage);
2786                 name_len_target++;      /* trailing null */
2787                 name_len_target *= 2;
2788         } else {        /* BB improve the check for buffer overruns BB */
2789                 name_len_target = strnlen(toName, PATH_MAX);
2790                 name_len_target++;      /* trailing null */
2791                 strncpy(data_offset, toName, name_len_target);
2792         }
2793
2794         pSMB->MaxParameterCount = cpu_to_le16(2);
2795         /* BB find exact max on data count below from sess */
2796         pSMB->MaxDataCount = cpu_to_le16(1000);
2797         pSMB->SetupCount = 1;
2798         pSMB->Reserved3 = 0;
2799         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2800         byte_count = 3 /* pad */  + params + name_len_target;
2801         pSMB->DataCount = cpu_to_le16(name_len_target);
2802         pSMB->ParameterCount = cpu_to_le16(params);
2803         pSMB->TotalDataCount = pSMB->DataCount;
2804         pSMB->TotalParameterCount = pSMB->ParameterCount;
2805         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2806         pSMB->DataOffset = cpu_to_le16(offset);
2807         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2808         pSMB->Reserved4 = 0;
2809         inc_rfc1001_len(pSMB, byte_count);
2810         pSMB->ByteCount = cpu_to_le16(byte_count);
2811         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2812                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2813         cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2814         if (rc)
2815                 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2816
2817         cifs_buf_release(pSMB);
2818
2819         if (rc == -EAGAIN)
2820                 goto createSymLinkRetry;
2821
2822         return rc;
2823 }
2824
2825 int
2826 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2827                        const char *fromName, const char *toName,
2828                        const struct nls_table *nls_codepage, int remap)
2829 {
2830         TRANSACTION2_SPI_REQ *pSMB = NULL;
2831         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2832         char *data_offset;
2833         int name_len;
2834         int name_len_target;
2835         int rc = 0;
2836         int bytes_returned = 0;
2837         __u16 params, param_offset, offset, byte_count;
2838
2839         cFYI(1, "In Create Hard link Unix style");
2840 createHardLinkRetry:
2841         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2842                       (void **) &pSMBr);
2843         if (rc)
2844                 return rc;
2845
2846         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2847                 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2848                                               PATH_MAX, nls_codepage, remap);
2849                 name_len++;     /* trailing null */
2850                 name_len *= 2;
2851
2852         } else {        /* BB improve the check for buffer overruns BB */
2853                 name_len = strnlen(toName, PATH_MAX);
2854                 name_len++;     /* trailing null */
2855                 strncpy(pSMB->FileName, toName, name_len);
2856         }
2857         params = 6 + name_len;
2858         pSMB->MaxSetupCount = 0;
2859         pSMB->Reserved = 0;
2860         pSMB->Flags = 0;
2861         pSMB->Timeout = 0;
2862         pSMB->Reserved2 = 0;
2863         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2864                                 InformationLevel) - 4;
2865         offset = param_offset + params;
2866
2867         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2868         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2869                 name_len_target =
2870                     cifsConvertToUTF16((__le16 *) data_offset, fromName,
2871                                        PATH_MAX, nls_codepage, remap);
2872                 name_len_target++;      /* trailing null */
2873                 name_len_target *= 2;
2874         } else {        /* BB improve the check for buffer overruns BB */
2875                 name_len_target = strnlen(fromName, PATH_MAX);
2876                 name_len_target++;      /* trailing null */
2877                 strncpy(data_offset, fromName, name_len_target);
2878         }
2879
2880         pSMB->MaxParameterCount = cpu_to_le16(2);
2881         /* BB find exact max on data count below from sess*/
2882         pSMB->MaxDataCount = cpu_to_le16(1000);
2883         pSMB->SetupCount = 1;
2884         pSMB->Reserved3 = 0;
2885         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2886         byte_count = 3 /* pad */  + params + name_len_target;
2887         pSMB->ParameterCount = cpu_to_le16(params);
2888         pSMB->TotalParameterCount = pSMB->ParameterCount;
2889         pSMB->DataCount = cpu_to_le16(name_len_target);
2890         pSMB->TotalDataCount = pSMB->DataCount;
2891         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2892         pSMB->DataOffset = cpu_to_le16(offset);
2893         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2894         pSMB->Reserved4 = 0;
2895         inc_rfc1001_len(pSMB, byte_count);
2896         pSMB->ByteCount = cpu_to_le16(byte_count);
2897         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2898                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2899         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2900         if (rc)
2901                 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
2902
2903         cifs_buf_release(pSMB);
2904         if (rc == -EAGAIN)
2905                 goto createHardLinkRetry;
2906
2907         return rc;
2908 }
2909
2910 int
2911 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2912                    const char *from_name, const char *to_name,
2913                    struct cifs_sb_info *cifs_sb)
2914 {
2915         int rc = 0;
2916         NT_RENAME_REQ *pSMB = NULL;
2917         RENAME_RSP *pSMBr = NULL;
2918         int bytes_returned;
2919         int name_len, name_len2;
2920         __u16 count;
2921         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
2922
2923         cFYI(1, "In CIFSCreateHardLink");
2924 winCreateHardLinkRetry:
2925
2926         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2927                       (void **) &pSMBr);
2928         if (rc)
2929                 return rc;
2930
2931         pSMB->SearchAttributes =
2932             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2933                         ATTR_DIRECTORY);
2934         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2935         pSMB->ClusterCount = 0;
2936
2937         pSMB->BufferFormat = 0x04;
2938
2939         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2940                 name_len =
2941                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2942                                        PATH_MAX, cifs_sb->local_nls, remap);
2943                 name_len++;     /* trailing null */
2944                 name_len *= 2;
2945
2946                 /* protocol specifies ASCII buffer format (0x04) for unicode */
2947                 pSMB->OldFileName[name_len] = 0x04;
2948                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2949                 name_len2 =
2950                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2951                                        to_name, PATH_MAX, cifs_sb->local_nls,
2952                                        remap);
2953                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2954                 name_len2 *= 2; /* convert to bytes */
2955         } else {        /* BB improve the check for buffer overruns BB */
2956                 name_len = strnlen(from_name, PATH_MAX);
2957                 name_len++;     /* trailing null */
2958                 strncpy(pSMB->OldFileName, from_name, name_len);
2959                 name_len2 = strnlen(to_name, PATH_MAX);
2960                 name_len2++;    /* trailing null */
2961                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
2962                 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2963                 name_len2++;    /* trailing null */
2964                 name_len2++;    /* signature byte */
2965         }
2966
2967         count = 1 /* string type byte */  + name_len + name_len2;
2968         inc_rfc1001_len(pSMB, count);
2969         pSMB->ByteCount = cpu_to_le16(count);
2970
2971         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2972                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2973         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2974         if (rc)
2975                 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
2976
2977         cifs_buf_release(pSMB);
2978         if (rc == -EAGAIN)
2979                 goto winCreateHardLinkRetry;
2980
2981         return rc;
2982 }
2983
2984 int
2985 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2986                         const unsigned char *searchName, char **symlinkinfo,
2987                         const struct nls_table *nls_codepage)
2988 {
2989 /* SMB_QUERY_FILE_UNIX_LINK */
2990         TRANSACTION2_QPI_REQ *pSMB = NULL;
2991         TRANSACTION2_QPI_RSP *pSMBr = NULL;
2992         int rc = 0;
2993         int bytes_returned;
2994         int name_len;
2995         __u16 params, byte_count;
2996         char *data_start;
2997
2998         cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
2999
3000 querySymLinkRetry:
3001         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3002                       (void **) &pSMBr);
3003         if (rc)
3004                 return rc;
3005
3006         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3007                 name_len =
3008                         cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3009                                         PATH_MAX, nls_codepage);
3010                 name_len++;     /* trailing null */
3011                 name_len *= 2;
3012         } else {        /* BB improve the check for buffer overruns BB */
3013                 name_len = strnlen(searchName, PATH_MAX);
3014                 name_len++;     /* trailing null */
3015                 strncpy(pSMB->FileName, searchName, name_len);
3016         }
3017
3018         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3019         pSMB->TotalDataCount = 0;
3020         pSMB->MaxParameterCount = cpu_to_le16(2);
3021         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3022         pSMB->MaxSetupCount = 0;
3023         pSMB->Reserved = 0;
3024         pSMB->Flags = 0;
3025         pSMB->Timeout = 0;
3026         pSMB->Reserved2 = 0;
3027         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3028         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3029         pSMB->DataCount = 0;
3030         pSMB->DataOffset = 0;
3031         pSMB->SetupCount = 1;
3032         pSMB->Reserved3 = 0;
3033         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3034         byte_count = params + 1 /* pad */ ;
3035         pSMB->TotalParameterCount = cpu_to_le16(params);
3036         pSMB->ParameterCount = pSMB->TotalParameterCount;
3037         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3038         pSMB->Reserved4 = 0;
3039         inc_rfc1001_len(pSMB, byte_count);
3040         pSMB->ByteCount = cpu_to_le16(byte_count);
3041
3042         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3043                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3044         if (rc) {
3045                 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3046         } else {
3047                 /* decode response */
3048
3049                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3050                 /* BB also check enough total bytes returned */
3051                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3052                         rc = -EIO;
3053                 else {
3054                         bool is_unicode;
3055                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3056
3057                         data_start = ((char *) &pSMBr->hdr.Protocol) +
3058                                            le16_to_cpu(pSMBr->t2.DataOffset);
3059
3060                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3061                                 is_unicode = true;
3062                         else
3063                                 is_unicode = false;
3064
3065                         /* BB FIXME investigate remapping reserved chars here */
3066                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
3067                                         count, is_unicode, nls_codepage);
3068                         if (!*symlinkinfo)
3069                                 rc = -ENOMEM;
3070                 }
3071         }
3072         cifs_buf_release(pSMB);
3073         if (rc == -EAGAIN)
3074                 goto querySymLinkRetry;
3075         return rc;
3076 }
3077
3078 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3079 /*
3080  *      Recent Windows versions now create symlinks more frequently
3081  *      and they use the "reparse point" mechanism below.  We can of course
3082  *      do symlinks nicely to Samba and other servers which support the
3083  *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3084  *      "MF" symlinks optionally, but for recent Windows we really need to
3085  *      reenable the code below and fix the cifs_symlink callers to handle this.
3086  *      In the interim this code has been moved to its own config option so
3087  *      it is not compiled in by default until callers fixed up and more tested.
3088  */
3089 int
3090 CIFSSMBQueryReparseLinkInfo(const unsigned int xid, struct cifs_tcon *tcon,
3091                         const unsigned char *searchName,
3092                         char *symlinkinfo, const int buflen, __u16 fid,
3093                         const struct nls_table *nls_codepage)
3094 {
3095         int rc = 0;
3096         int bytes_returned;
3097         struct smb_com_transaction_ioctl_req *pSMB;
3098         struct smb_com_transaction_ioctl_rsp *pSMBr;
3099
3100         cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3101         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3102                       (void **) &pSMBr);
3103         if (rc)
3104                 return rc;
3105
3106         pSMB->TotalParameterCount = 0 ;
3107         pSMB->TotalDataCount = 0;
3108         pSMB->MaxParameterCount = cpu_to_le32(2);
3109         /* BB find exact data count max from sess structure BB */
3110         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3111         pSMB->MaxSetupCount = 4;
3112         pSMB->Reserved = 0;
3113         pSMB->ParameterOffset = 0;
3114         pSMB->DataCount = 0;
3115         pSMB->DataOffset = 0;
3116         pSMB->SetupCount = 4;
3117         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3118         pSMB->ParameterCount = pSMB->TotalParameterCount;
3119         pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3120         pSMB->IsFsctl = 1; /* FSCTL */
3121         pSMB->IsRootFlag = 0;
3122         pSMB->Fid = fid; /* file handle always le */
3123         pSMB->ByteCount = 0;
3124
3125         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3126                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3127         if (rc) {
3128                 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3129         } else {                /* decode response */
3130                 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3131                 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3132                 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3133                         /* BB also check enough total bytes returned */
3134                         rc = -EIO;      /* bad smb */
3135                         goto qreparse_out;
3136                 }
3137                 if (data_count && (data_count < 2048)) {
3138                         char *end_of_smb = 2 /* sizeof byte count */ +
3139                                get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3140
3141                         struct reparse_data *reparse_buf =
3142                                                 (struct reparse_data *)
3143                                                 ((char *)&pSMBr->hdr.Protocol
3144                                                                  + data_offset);
3145                         if ((char *)reparse_buf >= end_of_smb) {
3146                                 rc = -EIO;
3147                                 goto qreparse_out;
3148                         }
3149                         if ((reparse_buf->LinkNamesBuf +
3150                                 reparse_buf->TargetNameOffset +
3151                                 reparse_buf->TargetNameLen) > end_of_smb) {
3152                                 cFYI(1, "reparse buf beyond SMB");
3153                                 rc = -EIO;
3154                                 goto qreparse_out;
3155                         }
3156
3157                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3158                                 cifs_from_ucs2(symlinkinfo, (__le16 *)
3159                                                 (reparse_buf->LinkNamesBuf +
3160                                                 reparse_buf->TargetNameOffset),
3161                                                 buflen,
3162                                                 reparse_buf->TargetNameLen,
3163                                                 nls_codepage, 0);
3164                         } else { /* ASCII names */
3165                                 strncpy(symlinkinfo,
3166                                         reparse_buf->LinkNamesBuf +
3167                                         reparse_buf->TargetNameOffset,
3168                                         min_t(const int, buflen,
3169                                            reparse_buf->TargetNameLen));
3170                         }
3171                 } else {
3172                         rc = -EIO;
3173                         cFYI(1, "Invalid return data count on "
3174                                  "get reparse info ioctl");
3175                 }
3176                 symlinkinfo[buflen] = 0; /* just in case so the caller
3177                                         does not go off the end of the buffer */
3178                 cFYI(1, "readlink result - %s", symlinkinfo);
3179         }
3180
3181 qreparse_out:
3182         cifs_buf_release(pSMB);
3183
3184         /* Note: On -EAGAIN error only caller can retry on handle based calls
3185                 since file handle passed in no longer valid */
3186
3187         return rc;
3188 }
3189 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3190
3191 #ifdef CONFIG_CIFS_POSIX
3192
3193 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3194 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3195                              struct cifs_posix_ace *cifs_ace)
3196 {
3197         /* u8 cifs fields do not need le conversion */
3198         ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3199         ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3200         ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3201         /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3202
3203         return;
3204 }
3205
3206 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3207 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3208                                const int acl_type, const int size_of_data_area)
3209 {
3210         int size =  0;
3211         int i;
3212         __u16 count;
3213         struct cifs_posix_ace *pACE;
3214         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3215         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3216
3217         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3218                 return -EOPNOTSUPP;
3219
3220         if (acl_type & ACL_TYPE_ACCESS) {
3221                 count = le16_to_cpu(cifs_acl->access_entry_count);
3222                 pACE = &cifs_acl->ace_array[0];
3223                 size = sizeof(struct cifs_posix_acl);
3224                 size += sizeof(struct cifs_posix_ace) * count;
3225                 /* check if we would go beyond end of SMB */
3226                 if (size_of_data_area < size) {
3227                         cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3228                                 size_of_data_area, size);
3229                         return -EINVAL;
3230                 }
3231         } else if (acl_type & ACL_TYPE_DEFAULT) {
3232                 count = le16_to_cpu(cifs_acl->access_entry_count);
3233                 size = sizeof(struct cifs_posix_acl);
3234                 size += sizeof(struct cifs_posix_ace) * count;
3235 /* skip past access ACEs to get to default ACEs */
3236                 pACE = &cifs_acl->ace_array[count];
3237                 count = le16_to_cpu(cifs_acl->default_entry_count);
3238                 size += sizeof(struct cifs_posix_ace) * count;
3239                 /* check if we would go beyond end of SMB */
3240                 if (size_of_data_area < size)
3241                         return -EINVAL;
3242         } else {
3243                 /* illegal type */
3244                 return -EINVAL;
3245         }
3246
3247         size = posix_acl_xattr_size(count);
3248         if ((buflen == 0) || (local_acl == NULL)) {
3249                 /* used to query ACL EA size */
3250         } else if (size > buflen) {
3251                 return -ERANGE;
3252         } else /* buffer big enough */ {
3253                 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3254                 for (i = 0; i < count ; i++) {
3255                         cifs_convert_ace(&local_acl->a_entries[i], pACE);
3256                         pACE++;
3257                 }
3258         }
3259         return size;
3260 }
3261
3262 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3263                                      const posix_acl_xattr_entry *local_ace)
3264 {
3265         __u16 rc = 0; /* 0 = ACL converted ok */
3266
3267         cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3268         cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
3269         /* BB is there a better way to handle the large uid? */
3270         if (local_ace->e_id == cpu_to_le32(-1)) {
3271         /* Probably no need to le convert -1 on any arch but can not hurt */
3272                 cifs_ace->cifs_uid = cpu_to_le64(-1);
3273         } else
3274                 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3275         /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3276         return rc;
3277 }
3278
3279 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3280 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3281                                const int buflen, const int acl_type)
3282 {
3283         __u16 rc = 0;
3284         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3285         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3286         int count;
3287         int i;
3288
3289         if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3290                 return 0;
3291
3292         count = posix_acl_xattr_count((size_t)buflen);
3293         cFYI(1, "setting acl with %d entries from buf of length %d and "
3294                 "version of %d",
3295                 count, buflen, le32_to_cpu(local_acl->a_version));
3296         if (le32_to_cpu(local_acl->a_version) != 2) {
3297                 cFYI(1, "unknown POSIX ACL version %d",
3298                      le32_to_cpu(local_acl->a_version));
3299                 return 0;
3300         }
3301         cifs_acl->version = cpu_to_le16(1);
3302         if (acl_type == ACL_TYPE_ACCESS)
3303                 cifs_acl->access_entry_count = cpu_to_le16(count);
3304         else if (acl_type == ACL_TYPE_DEFAULT)
3305                 cifs_acl->default_entry_count = cpu_to_le16(count);
3306         else {
3307                 cFYI(1, "unknown ACL type %d", acl_type);
3308                 return 0;
3309         }
3310         for (i = 0; i < count; i++) {
3311                 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3312                                         &local_acl->a_entries[i]);
3313                 if (rc != 0) {
3314                         /* ACE not converted */
3315                         break;
3316                 }
3317         }
3318         if (rc == 0) {
3319                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3320                 rc += sizeof(struct cifs_posix_acl);
3321                 /* BB add check to make sure ACL does not overflow SMB */
3322         }
3323         return rc;
3324 }
3325
3326 int
3327 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3328                    const unsigned char *searchName,
3329                    char *acl_inf, const int buflen, const int acl_type,
3330                    const struct nls_table *nls_codepage, int remap)
3331 {
3332 /* SMB_QUERY_POSIX_ACL */
3333         TRANSACTION2_QPI_REQ *pSMB = NULL;
3334         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3335         int rc = 0;
3336         int bytes_returned;
3337         int name_len;
3338         __u16 params, byte_count;
3339
3340         cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3341
3342 queryAclRetry:
3343         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3344                 (void **) &pSMBr);
3345         if (rc)
3346                 return rc;
3347
3348         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3349                 name_len =
3350                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3351                                            searchName, PATH_MAX, nls_codepage,
3352                                            remap);
3353                 name_len++;     /* trailing null */
3354                 name_len *= 2;
3355                 pSMB->FileName[name_len] = 0;
3356                 pSMB->FileName[name_len+1] = 0;
3357         } else {        /* BB improve the check for buffer overruns BB */
3358                 name_len = strnlen(searchName, PATH_MAX);
3359                 name_len++;     /* trailing null */
3360                 strncpy(pSMB->FileName, searchName, name_len);
3361         }
3362
3363         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3364         pSMB->TotalDataCount = 0;
3365         pSMB->MaxParameterCount = cpu_to_le16(2);
3366         /* BB find exact max data count below from sess structure BB */
3367         pSMB->MaxDataCount = cpu_to_le16(4000);
3368         pSMB->MaxSetupCount = 0;
3369         pSMB->Reserved = 0;
3370         pSMB->Flags = 0;
3371         pSMB->Timeout = 0;
3372         pSMB->Reserved2 = 0;
3373         pSMB->ParameterOffset = cpu_to_le16(
3374                 offsetof(struct smb_com_transaction2_qpi_req,
3375                          InformationLevel) - 4);
3376         pSMB->DataCount = 0;
3377         pSMB->DataOffset = 0;
3378         pSMB->SetupCount = 1;
3379         pSMB->Reserved3 = 0;
3380         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3381         byte_count = params + 1 /* pad */ ;
3382         pSMB->TotalParameterCount = cpu_to_le16(params);
3383         pSMB->ParameterCount = pSMB->TotalParameterCount;
3384         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3385         pSMB->Reserved4 = 0;
3386         inc_rfc1001_len(pSMB, byte_count);
3387         pSMB->ByteCount = cpu_to_le16(byte_count);
3388
3389         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3390                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3391         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3392         if (rc) {
3393                 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3394         } else {
3395                 /* decode response */
3396
3397                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3398                 /* BB also check enough total bytes returned */
3399                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3400                         rc = -EIO;      /* bad smb */
3401                 else {
3402                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3403                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3404                         rc = cifs_copy_posix_acl(acl_inf,
3405                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3406                                 buflen, acl_type, count);
3407                 }
3408         }
3409         cifs_buf_release(pSMB);
3410         if (rc == -EAGAIN)
3411                 goto queryAclRetry;
3412         return rc;
3413 }
3414
3415 int
3416 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3417                    const unsigned char *fileName,
3418                    const char *local_acl, const int buflen,
3419                    const int acl_type,
3420                    const struct nls_table *nls_codepage, int remap)
3421 {
3422         struct smb_com_transaction2_spi_req *pSMB = NULL;
3423         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3424         char *parm_data;
3425         int name_len;
3426         int rc = 0;
3427         int bytes_returned = 0;
3428         __u16 params, byte_count, data_count, param_offset, offset;
3429
3430         cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3431 setAclRetry:
3432         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3433                       (void **) &pSMBr);
3434         if (rc)
3435                 return rc;
3436         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3437                 name_len =
3438                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3439                                            PATH_MAX, nls_codepage, remap);
3440                 name_len++;     /* trailing null */
3441                 name_len *= 2;
3442         } else {        /* BB improve the check for buffer overruns BB */
3443                 name_len = strnlen(fileName, PATH_MAX);
3444                 name_len++;     /* trailing null */
3445                 strncpy(pSMB->FileName, fileName, name_len);
3446         }
3447         params = 6 + name_len;
3448         pSMB->MaxParameterCount = cpu_to_le16(2);
3449         /* BB find max SMB size from sess */
3450         pSMB->MaxDataCount = cpu_to_le16(1000);
3451         pSMB->MaxSetupCount = 0;
3452         pSMB->Reserved = 0;
3453         pSMB->Flags = 0;
3454         pSMB->Timeout = 0;
3455         pSMB->Reserved2 = 0;
3456         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3457                                 InformationLevel) - 4;
3458         offset = param_offset + params;
3459         parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3460         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3461
3462         /* convert to on the wire format for POSIX ACL */
3463         data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3464
3465         if (data_count == 0) {
3466                 rc = -EOPNOTSUPP;
3467                 goto setACLerrorExit;
3468         }
3469         pSMB->DataOffset = cpu_to_le16(offset);
3470         pSMB->SetupCount = 1;
3471         pSMB->Reserved3 = 0;
3472         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3473         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3474         byte_count = 3 /* pad */  + params + data_count;
3475         pSMB->DataCount = cpu_to_le16(data_count);
3476         pSMB->TotalDataCount = pSMB->DataCount;
3477         pSMB->ParameterCount = cpu_to_le16(params);
3478         pSMB->TotalParameterCount = pSMB->ParameterCount;
3479         pSMB->Reserved4 = 0;
3480         inc_rfc1001_len(pSMB, byte_count);
3481         pSMB->ByteCount = cpu_to_le16(byte_count);
3482         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3483                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3484         if (rc)
3485                 cFYI(1, "Set POSIX ACL returned %d", rc);
3486
3487 setACLerrorExit:
3488         cifs_buf_release(pSMB);
3489         if (rc == -EAGAIN)
3490                 goto setAclRetry;
3491         return rc;
3492 }
3493
3494 /* BB fix tabs in this function FIXME BB */
3495 int
3496 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3497                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3498 {
3499         int rc = 0;
3500         struct smb_t2_qfi_req *pSMB = NULL;
3501         struct smb_t2_qfi_rsp *pSMBr = NULL;
3502         int bytes_returned;
3503         __u16 params, byte_count;
3504
3505         cFYI(1, "In GetExtAttr");
3506         if (tcon == NULL)
3507                 return -ENODEV;
3508
3509 GetExtAttrRetry:
3510         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3511                         (void **) &pSMBr);
3512         if (rc)
3513                 return rc;
3514
3515         params = 2 /* level */ + 2 /* fid */;
3516         pSMB->t2.TotalDataCount = 0;
3517         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3518         /* BB find exact max data count below from sess structure BB */
3519         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3520         pSMB->t2.MaxSetupCount = 0;
3521         pSMB->t2.Reserved = 0;
3522         pSMB->t2.Flags = 0;
3523         pSMB->t2.Timeout = 0;
3524         pSMB->t2.Reserved2 = 0;
3525         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3526                                                Fid) - 4);
3527         pSMB->t2.DataCount = 0;
3528         pSMB->t2.DataOffset = 0;
3529         pSMB->t2.SetupCount = 1;
3530         pSMB->t2.Reserved3 = 0;
3531         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3532         byte_count = params + 1 /* pad */ ;
3533         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3534         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3535         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3536         pSMB->Pad = 0;
3537         pSMB->Fid = netfid;
3538         inc_rfc1001_len(pSMB, byte_count);
3539         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3540
3541         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3542                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3543         if (rc) {
3544                 cFYI(1, "error %d in GetExtAttr", rc);
3545         } else {
3546                 /* decode response */
3547                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3548                 /* BB also check enough total bytes returned */
3549                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3550                         /* If rc should we check for EOPNOSUPP and
3551                            disable the srvino flag? or in caller? */
3552                         rc = -EIO;      /* bad smb */
3553                 else {
3554                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3555                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3556                         struct file_chattr_info *pfinfo;
3557                         /* BB Do we need a cast or hash here ? */
3558                         if (count != 16) {
3559                                 cFYI(1, "Illegal size ret in GetExtAttr");
3560                                 rc = -EIO;
3561                                 goto GetExtAttrOut;
3562                         }
3563                         pfinfo = (struct file_chattr_info *)
3564                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3565                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3566                         *pMask = le64_to_cpu(pfinfo->mask);
3567                 }
3568         }
3569 GetExtAttrOut:
3570         cifs_buf_release(pSMB);
3571         if (rc == -EAGAIN)
3572                 goto GetExtAttrRetry;
3573         return rc;
3574 }
3575
3576 #endif /* CONFIG_POSIX */
3577
3578 #ifdef CONFIG_CIFS_ACL
3579 /*
3580  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3581  * all NT TRANSACTS that we init here have total parm and data under about 400
3582  * bytes (to fit in small cifs buffer size), which is the case so far, it
3583  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3584  * returned setup area) and MaxParameterCount (returned parms size) must be set
3585  * by caller
3586  */
3587 static int
3588 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3589                    const int parm_len, struct cifs_tcon *tcon,
3590                    void **ret_buf)
3591 {
3592         int rc;
3593         __u32 temp_offset;
3594         struct smb_com_ntransact_req *pSMB;
3595
3596         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3597                                 (void **)&pSMB);
3598         if (rc)
3599                 return rc;
3600         *ret_buf = (void *)pSMB;
3601         pSMB->Reserved = 0;
3602         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3603         pSMB->TotalDataCount  = 0;
3604         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3605         pSMB->ParameterCount = pSMB->TotalParameterCount;
3606         pSMB->DataCount  = pSMB->TotalDataCount;
3607         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3608                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3609         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3610         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3611         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3612         pSMB->SubCommand = cpu_to_le16(sub_command);
3613         return 0;
3614 }
3615
3616 static int
3617 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3618                    __u32 *pparmlen, __u32 *pdatalen)
3619 {
3620         char *end_of_smb;
3621         __u32 data_count, data_offset, parm_count, parm_offset;
3622         struct smb_com_ntransact_rsp *pSMBr;
3623         u16 bcc;
3624
3625         *pdatalen = 0;
3626         *pparmlen = 0;
3627
3628         if (buf == NULL)
3629                 return -EINVAL;
3630
3631         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3632
3633         bcc = get_bcc(&pSMBr->hdr);
3634         end_of_smb = 2 /* sizeof byte count */ + bcc +
3635                         (char *)&pSMBr->ByteCount;
3636
3637         data_offset = le32_to_cpu(pSMBr->DataOffset);
3638         data_count = le32_to_cpu(pSMBr->DataCount);
3639         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3640         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3641
3642         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3643         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3644
3645         /* should we also check that parm and data areas do not overlap? */
3646         if (*ppparm > end_of_smb) {
3647                 cFYI(1, "parms start after end of smb");
3648                 return -EINVAL;
3649         } else if (parm_count + *ppparm > end_of_smb) {
3650                 cFYI(1, "parm end after end of smb");
3651                 return -EINVAL;
3652         } else if (*ppdata > end_of_smb) {
3653                 cFYI(1, "data starts after end of smb");
3654                 return -EINVAL;
3655         } else if (data_count + *ppdata > end_of_smb) {
3656                 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3657                         *ppdata, data_count, (data_count + *ppdata),
3658                         end_of_smb, pSMBr);
3659                 return -EINVAL;
3660         } else if (parm_count + data_count > bcc) {
3661                 cFYI(1, "parm count and data count larger than SMB");
3662                 return -EINVAL;
3663         }
3664         *pdatalen = data_count;
3665         *pparmlen = parm_count;
3666         return 0;
3667 }
3668
3669 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3670 int
3671 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3672                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3673 {
3674         int rc = 0;
3675         int buf_type = 0;
3676         QUERY_SEC_DESC_REQ *pSMB;
3677         struct kvec iov[1];
3678
3679         cFYI(1, "GetCifsACL");
3680
3681         *pbuflen = 0;
3682         *acl_inf = NULL;
3683
3684         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3685                         8 /* parm len */, tcon, (void **) &pSMB);
3686         if (rc)
3687                 return rc;
3688
3689         pSMB->MaxParameterCount = cpu_to_le32(4);
3690         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3691         pSMB->MaxSetupCount = 0;
3692         pSMB->Fid = fid; /* file handle always le */
3693         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3694                                      CIFS_ACL_DACL);
3695         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3696         inc_rfc1001_len(pSMB, 11);
3697         iov[0].iov_base = (char *)pSMB;
3698         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3699
3700         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3701                          0);
3702         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3703         if (rc) {
3704                 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3705         } else {                /* decode response */
3706                 __le32 *parm;
3707                 __u32 parm_len;
3708                 __u32 acl_len;
3709                 struct smb_com_ntransact_rsp *pSMBr;
3710                 char *pdata;
3711
3712 /* validate_nttransact */
3713                 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3714                                         &pdata, &parm_len, pbuflen);
3715                 if (rc)
3716                         goto qsec_out;
3717                 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3718
3719                 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3720
3721                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3722                         rc = -EIO;      /* bad smb */
3723                         *pbuflen = 0;
3724                         goto qsec_out;
3725                 }
3726
3727 /* BB check that data area is minimum length and as big as acl_len */
3728
3729                 acl_len = le32_to_cpu(*parm);
3730                 if (acl_len != *pbuflen) {
3731                         cERROR(1, "acl length %d does not match %d",
3732                                    acl_len, *pbuflen);
3733                         if (*pbuflen > acl_len)
3734                                 *pbuflen = acl_len;
3735                 }
3736
3737                 /* check if buffer is big enough for the acl
3738                    header followed by the smallest SID */
3739                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3740                     (*pbuflen >= 64 * 1024)) {
3741                         cERROR(1, "bad acl length %d", *pbuflen);
3742                         rc = -EINVAL;
3743                         *pbuflen = 0;
3744                 } else {
3745                         *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3746                         if (*acl_inf == NULL) {
3747                                 *pbuflen = 0;
3748                                 rc = -ENOMEM;
3749                         }
3750                         memcpy(*acl_inf, pdata, *pbuflen);
3751                 }
3752         }
3753 qsec_out:
3754         if (buf_type == CIFS_SMALL_BUFFER)
3755                 cifs_small_buf_release(iov[0].iov_base);
3756         else if (buf_type == CIFS_LARGE_BUFFER)
3757                 cifs_buf_release(iov[0].iov_base);
3758 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3759         return rc;
3760 }
3761
3762 int
3763 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3764                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3765 {
3766         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3767         int rc = 0;
3768         int bytes_returned = 0;
3769         SET_SEC_DESC_REQ *pSMB = NULL;
3770         void *pSMBr;
3771
3772 setCifsAclRetry:
3773         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3774         if (rc)
3775                 return rc;
3776
3777         pSMB->MaxSetupCount = 0;
3778         pSMB->Reserved = 0;
3779
3780         param_count = 8;
3781         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3782         data_count = acllen;
3783         data_offset = param_offset + param_count;
3784         byte_count = 3 /* pad */  + param_count;
3785
3786         pSMB->DataCount = cpu_to_le32(data_count);
3787         pSMB->TotalDataCount = pSMB->DataCount;
3788         pSMB->MaxParameterCount = cpu_to_le32(4);
3789         pSMB->MaxDataCount = cpu_to_le32(16384);
3790         pSMB->ParameterCount = cpu_to_le32(param_count);
3791         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3792         pSMB->TotalParameterCount = pSMB->ParameterCount;
3793         pSMB->DataOffset = cpu_to_le32(data_offset);
3794         pSMB->SetupCount = 0;
3795         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3796         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3797
3798         pSMB->Fid = fid; /* file handle always le */
3799         pSMB->Reserved2 = 0;
3800         pSMB->AclFlags = cpu_to_le32(aclflag);
3801
3802         if (pntsd && acllen) {
3803                 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3804                                 data_offset, pntsd, acllen);
3805                 inc_rfc1001_len(pSMB, byte_count + data_count);
3806         } else
3807                 inc_rfc1001_len(pSMB, byte_count);
3808
3809         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3810                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3811
3812         cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3813         if (rc)
3814                 cFYI(1, "Set CIFS ACL returned %d", rc);
3815         cifs_buf_release(pSMB);
3816
3817         if (rc == -EAGAIN)
3818                 goto setCifsAclRetry;
3819
3820         return (rc);
3821 }
3822
3823 #endif /* CONFIG_CIFS_ACL */
3824
3825 /* Legacy Query Path Information call for lookup to old servers such
3826    as Win9x/WinME */
3827 int
3828 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3829                     const char *search_name, FILE_ALL_INFO *data,
3830                     const struct nls_table *nls_codepage, int remap)
3831 {
3832         QUERY_INFORMATION_REQ *pSMB;
3833         QUERY_INFORMATION_RSP *pSMBr;
3834         int rc = 0;
3835         int bytes_returned;
3836         int name_len;
3837
3838         cFYI(1, "In SMBQPath path %s", search_name);
3839 QInfRetry:
3840         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3841                       (void **) &pSMBr);
3842         if (rc)
3843                 return rc;
3844
3845         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3846                 name_len =
3847                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3848                                            search_name, PATH_MAX, nls_codepage,
3849                                            remap);
3850                 name_len++;     /* trailing null */
3851                 name_len *= 2;
3852         } else {
3853                 name_len = strnlen(search_name, PATH_MAX);
3854                 name_len++;     /* trailing null */
3855                 strncpy(pSMB->FileName, search_name, name_len);
3856         }
3857         pSMB->BufferFormat = 0x04;
3858         name_len++; /* account for buffer type byte */
3859         inc_rfc1001_len(pSMB, (__u16)name_len);
3860         pSMB->ByteCount = cpu_to_le16(name_len);
3861
3862         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3863                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3864         if (rc) {
3865                 cFYI(1, "Send error in QueryInfo = %d", rc);
3866         } else if (data) {
3867                 struct timespec ts;
3868                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3869
3870                 /* decode response */
3871                 /* BB FIXME - add time zone adjustment BB */
3872                 memset(data, 0, sizeof(FILE_ALL_INFO));
3873                 ts.tv_nsec = 0;
3874                 ts.tv_sec = time;
3875                 /* decode time fields */
3876                 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3877                 data->LastWriteTime = data->ChangeTime;
3878                 data->LastAccessTime = 0;
3879                 data->AllocationSize =
3880                         cpu_to_le64(le32_to_cpu(pSMBr->size));
3881                 data->EndOfFile = data->AllocationSize;
3882                 data->Attributes =
3883                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
3884         } else
3885                 rc = -EIO; /* bad buffer passed in */
3886
3887         cifs_buf_release(pSMB);
3888
3889         if (rc == -EAGAIN)
3890                 goto QInfRetry;
3891
3892         return rc;
3893 }
3894
3895 int
3896 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3897                  u16 netfid, FILE_ALL_INFO *pFindData)
3898 {
3899         struct smb_t2_qfi_req *pSMB = NULL;
3900         struct smb_t2_qfi_rsp *pSMBr = NULL;
3901         int rc = 0;
3902         int bytes_returned;
3903         __u16 params, byte_count;
3904
3905 QFileInfoRetry:
3906         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3907                       (void **) &pSMBr);
3908         if (rc)
3909                 return rc;
3910
3911         params = 2 /* level */ + 2 /* fid */;
3912         pSMB->t2.TotalDataCount = 0;
3913         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3914         /* BB find exact max data count below from sess structure BB */
3915         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3916         pSMB->t2.MaxSetupCount = 0;
3917         pSMB->t2.Reserved = 0;
3918         pSMB->t2.Flags = 0;
3919         pSMB->t2.Timeout = 0;
3920         pSMB->t2.Reserved2 = 0;
3921         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3922                                                Fid) - 4);
3923         pSMB->t2.DataCount = 0;
3924         pSMB->t2.DataOffset = 0;
3925         pSMB->t2.SetupCount = 1;
3926         pSMB->t2.Reserved3 = 0;
3927         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3928         byte_count = params + 1 /* pad */ ;
3929         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3930         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3931         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3932         pSMB->Pad = 0;
3933         pSMB->Fid = netfid;
3934         inc_rfc1001_len(pSMB, byte_count);
3935
3936         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3937                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3938         if (rc) {
3939                 cFYI(1, "Send error in QPathInfo = %d", rc);
3940         } else {                /* decode response */
3941                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3942
3943                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3944                         rc = -EIO;
3945                 else if (get_bcc(&pSMBr->hdr) < 40)
3946                         rc = -EIO;      /* bad smb */
3947                 else if (pFindData) {
3948                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3949                         memcpy((char *) pFindData,
3950                                (char *) &pSMBr->hdr.Protocol +
3951                                data_offset, sizeof(FILE_ALL_INFO));
3952                 } else
3953                     rc = -ENOMEM;
3954         }
3955         cifs_buf_release(pSMB);
3956         if (rc == -EAGAIN)
3957                 goto QFileInfoRetry;
3958
3959         return rc;
3960 }
3961
3962 int
3963 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3964                  const char *search_name, FILE_ALL_INFO *data,
3965                  int legacy /* old style infolevel */,
3966                  const struct nls_table *nls_codepage, int remap)
3967 {
3968         /* level 263 SMB_QUERY_FILE_ALL_INFO */
3969         TRANSACTION2_QPI_REQ *pSMB = NULL;
3970         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3971         int rc = 0;
3972         int bytes_returned;
3973         int name_len;
3974         __u16 params, byte_count;
3975
3976         /* cFYI(1, "In QPathInfo path %s", search_name); */
3977 QPathInfoRetry:
3978         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3979                       (void **) &pSMBr);
3980         if (rc)
3981                 return rc;
3982
3983         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3984                 name_len =
3985                     cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3986                                        PATH_MAX, nls_codepage, remap);
3987                 name_len++;     /* trailing null */
3988                 name_len *= 2;
3989         } else {        /* BB improve the check for buffer overruns BB */
3990                 name_len = strnlen(search_name, PATH_MAX);
3991                 name_len++;     /* trailing null */
3992                 strncpy(pSMB->FileName, search_name, name_len);
3993         }
3994
3995         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3996         pSMB->TotalDataCount = 0;
3997         pSMB->MaxParameterCount = cpu_to_le16(2);
3998         /* BB find exact max SMB PDU from sess structure BB */
3999         pSMB->MaxDataCount = cpu_to_le16(4000);
4000         pSMB->MaxSetupCount = 0;
4001         pSMB->Reserved = 0;
4002         pSMB->Flags = 0;
4003         pSMB->Timeout = 0;
4004         pSMB->Reserved2 = 0;
4005         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4006         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4007         pSMB->DataCount = 0;
4008         pSMB->DataOffset = 0;
4009         pSMB->SetupCount = 1;
4010         pSMB->Reserved3 = 0;
4011         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4012         byte_count = params + 1 /* pad */ ;
4013         pSMB->TotalParameterCount = cpu_to_le16(params);
4014         pSMB->ParameterCount = pSMB->TotalParameterCount;
4015         if (legacy)
4016                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4017         else
4018                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4019         pSMB->Reserved4 = 0;
4020         inc_rfc1001_len(pSMB, byte_count);
4021         pSMB->ByteCount = cpu_to_le16(byte_count);
4022
4023         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4024                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4025         if (rc) {
4026                 cFYI(1, "Send error in QPathInfo = %d", rc);
4027         } else {                /* decode response */
4028                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4029
4030                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4031                         rc = -EIO;
4032                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4033                         rc = -EIO;      /* bad smb */
4034                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4035                         rc = -EIO;  /* 24 or 26 expected but we do not read
4036                                         last field */
4037                 else if (data) {
4038                         int size;
4039                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4040
4041                         /*
4042                          * On legacy responses we do not read the last field,
4043                          * EAsize, fortunately since it varies by subdialect and
4044                          * also note it differs on Set vs Get, ie two bytes or 4
4045                          * bytes depending but we don't care here.
4046                          */
4047                         if (legacy)
4048                                 size = sizeof(FILE_INFO_STANDARD);
4049                         else
4050                                 size = sizeof(FILE_ALL_INFO);
4051                         memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4052                                data_offset, size);
4053                 } else
4054                     rc = -ENOMEM;
4055         }
4056         cifs_buf_release(pSMB);
4057         if (rc == -EAGAIN)
4058                 goto QPathInfoRetry;
4059
4060         return rc;
4061 }
4062
4063 int
4064 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4065                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4066 {
4067         struct smb_t2_qfi_req *pSMB = NULL;
4068         struct smb_t2_qfi_rsp *pSMBr = NULL;
4069         int rc = 0;
4070         int bytes_returned;
4071         __u16 params, byte_count;
4072
4073 UnixQFileInfoRetry:
4074         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4075                       (void **) &pSMBr);
4076         if (rc)
4077                 return rc;
4078
4079         params = 2 /* level */ + 2 /* fid */;
4080         pSMB->t2.TotalDataCount = 0;
4081         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4082         /* BB find exact max data count below from sess structure BB */
4083         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4084         pSMB->t2.MaxSetupCount = 0;
4085         pSMB->t2.Reserved = 0;
4086         pSMB->t2.Flags = 0;
4087         pSMB->t2.Timeout = 0;
4088         pSMB->t2.Reserved2 = 0;
4089         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4090                                                Fid) - 4);
4091         pSMB->t2.DataCount = 0;
4092         pSMB->t2.DataOffset = 0;
4093         pSMB->t2.SetupCount = 1;
4094         pSMB->t2.Reserved3 = 0;
4095         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4096         byte_count = params + 1 /* pad */ ;
4097         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4098         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4099         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4100         pSMB->Pad = 0;
4101         pSMB->Fid = netfid;
4102         inc_rfc1001_len(pSMB, byte_count);
4103
4104         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4105                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4106         if (rc) {
4107                 cFYI(1, "Send error in QPathInfo = %d", rc);
4108         } else {                /* decode response */
4109                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4110
4111                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4112                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4113                                    "Unix Extensions can be disabled on mount "
4114                                    "by specifying the nosfu mount option.");
4115                         rc = -EIO;      /* bad smb */
4116                 } else {
4117                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4118                         memcpy((char *) pFindData,
4119                                (char *) &pSMBr->hdr.Protocol +
4120                                data_offset,
4121                                sizeof(FILE_UNIX_BASIC_INFO));
4122                 }
4123         }
4124
4125         cifs_buf_release(pSMB);
4126         if (rc == -EAGAIN)
4127                 goto UnixQFileInfoRetry;
4128
4129         return rc;
4130 }
4131
4132 int
4133 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4134                      const unsigned char *searchName,
4135                      FILE_UNIX_BASIC_INFO *pFindData,
4136                      const struct nls_table *nls_codepage, int remap)
4137 {
4138 /* SMB_QUERY_FILE_UNIX_BASIC */
4139         TRANSACTION2_QPI_REQ *pSMB = NULL;
4140         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4141         int rc = 0;
4142         int bytes_returned = 0;
4143         int name_len;
4144         __u16 params, byte_count;
4145
4146         cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4147 UnixQPathInfoRetry:
4148         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4149                       (void **) &pSMBr);
4150         if (rc)
4151                 return rc;
4152
4153         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4154                 name_len =
4155                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4156                                        PATH_MAX, nls_codepage, remap);
4157                 name_len++;     /* trailing null */
4158                 name_len *= 2;
4159         } else {        /* BB improve the check for buffer overruns BB */
4160                 name_len = strnlen(searchName, PATH_MAX);
4161                 name_len++;     /* trailing null */
4162                 strncpy(pSMB->FileName, searchName, name_len);
4163         }
4164
4165         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4166         pSMB->TotalDataCount = 0;
4167         pSMB->MaxParameterCount = cpu_to_le16(2);
4168         /* BB find exact max SMB PDU from sess structure BB */
4169         pSMB->MaxDataCount = cpu_to_le16(4000);
4170         pSMB->MaxSetupCount = 0;
4171         pSMB->Reserved = 0;
4172         pSMB->Flags = 0;
4173         pSMB->Timeout = 0;
4174         pSMB->Reserved2 = 0;
4175         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4176         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4177         pSMB->DataCount = 0;
4178         pSMB->DataOffset = 0;
4179         pSMB->SetupCount = 1;
4180         pSMB->Reserved3 = 0;
4181         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4182         byte_count = params + 1 /* pad */ ;
4183         pSMB->TotalParameterCount = cpu_to_le16(params);
4184         pSMB->ParameterCount = pSMB->TotalParameterCount;
4185         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4186         pSMB->Reserved4 = 0;
4187         inc_rfc1001_len(pSMB, byte_count);
4188         pSMB->ByteCount = cpu_to_le16(byte_count);
4189
4190         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4191                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4192         if (rc) {
4193                 cFYI(1, "Send error in QPathInfo = %d", rc);
4194         } else {                /* decode response */
4195                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4196
4197                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4198                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4199                                    "Unix Extensions can be disabled on mount "
4200                                    "by specifying the nosfu mount option.");
4201                         rc = -EIO;      /* bad smb */
4202                 } else {
4203                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4204                         memcpy((char *) pFindData,
4205                                (char *) &pSMBr->hdr.Protocol +
4206                                data_offset,
4207                                sizeof(FILE_UNIX_BASIC_INFO));
4208                 }
4209         }
4210         cifs_buf_release(pSMB);
4211         if (rc == -EAGAIN)
4212                 goto UnixQPathInfoRetry;
4213
4214         return rc;
4215 }
4216
4217 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4218 int
4219 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4220               const char *searchName, struct cifs_sb_info *cifs_sb,
4221               __u16 *pnetfid, __u16 search_flags,
4222               struct cifs_search_info *psrch_inf, bool msearch)
4223 {
4224 /* level 257 SMB_ */
4225         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4226         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4227         T2_FFIRST_RSP_PARMS *parms;
4228         int rc = 0;
4229         int bytes_returned = 0;
4230         int name_len, remap;
4231         __u16 params, byte_count;
4232         struct nls_table *nls_codepage;
4233
4234         cFYI(1, "In FindFirst for %s", searchName);
4235
4236 findFirstRetry:
4237         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4238                       (void **) &pSMBr);
4239         if (rc)
4240                 return rc;
4241
4242         nls_codepage = cifs_sb->local_nls;
4243         remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
4244
4245         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4246                 name_len =
4247                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4248                                        PATH_MAX, nls_codepage, remap);
4249                 /* We can not add the asterik earlier in case
4250                 it got remapped to 0xF03A as if it were part of the
4251                 directory name instead of a wildcard */
4252                 name_len *= 2;
4253                 if (msearch) {
4254                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4255                         pSMB->FileName[name_len+1] = 0;
4256                         pSMB->FileName[name_len+2] = '*';
4257                         pSMB->FileName[name_len+3] = 0;
4258                         name_len += 4; /* now the trailing null */
4259                         /* null terminate just in case */
4260                         pSMB->FileName[name_len] = 0;
4261                         pSMB->FileName[name_len+1] = 0;
4262                         name_len += 2;
4263                 }
4264         } else {        /* BB add check for overrun of SMB buf BB */
4265                 name_len = strnlen(searchName, PATH_MAX);
4266 /* BB fix here and in unicode clause above ie
4267                 if (name_len > buffersize-header)
4268                         free buffer exit; BB */
4269                 strncpy(pSMB->FileName, searchName, name_len);
4270                 if (msearch) {
4271                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4272                         pSMB->FileName[name_len+1] = '*';
4273                         pSMB->FileName[name_len+2] = 0;
4274                         name_len += 3;
4275                 }
4276         }
4277
4278         params = 12 + name_len /* includes null */ ;
4279         pSMB->TotalDataCount = 0;       /* no EAs */
4280         pSMB->MaxParameterCount = cpu_to_le16(10);
4281         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4282         pSMB->MaxSetupCount = 0;
4283         pSMB->Reserved = 0;
4284         pSMB->Flags = 0;
4285         pSMB->Timeout = 0;
4286         pSMB->Reserved2 = 0;
4287         byte_count = params + 1 /* pad */ ;
4288         pSMB->TotalParameterCount = cpu_to_le16(params);
4289         pSMB->ParameterCount = pSMB->TotalParameterCount;
4290         pSMB->ParameterOffset = cpu_to_le16(
4291               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4292                 - 4);
4293         pSMB->DataCount = 0;
4294         pSMB->DataOffset = 0;
4295         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4296         pSMB->Reserved3 = 0;
4297         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4298         pSMB->SearchAttributes =
4299             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4300                         ATTR_DIRECTORY);
4301         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4302         pSMB->SearchFlags = cpu_to_le16(search_flags);
4303         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4304
4305         /* BB what should we set StorageType to? Does it matter? BB */
4306         pSMB->SearchStorageType = 0;
4307         inc_rfc1001_len(pSMB, byte_count);
4308         pSMB->ByteCount = cpu_to_le16(byte_count);
4309
4310         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4311                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4312         cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4313
4314         if (rc) {/* BB add logic to retry regular search if Unix search
4315                         rejected unexpectedly by server */
4316                 /* BB Add code to handle unsupported level rc */
4317                 cFYI(1, "Error in FindFirst = %d", rc);
4318
4319                 cifs_buf_release(pSMB);
4320
4321                 /* BB eventually could optimize out free and realloc of buf */
4322                 /*    for this case */
4323                 if (rc == -EAGAIN)
4324                         goto findFirstRetry;
4325         } else { /* decode response */
4326                 /* BB remember to free buffer if error BB */
4327                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4328                 if (rc == 0) {
4329                         unsigned int lnoff;
4330
4331                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4332                                 psrch_inf->unicode = true;
4333                         else
4334                                 psrch_inf->unicode = false;
4335
4336                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4337                         psrch_inf->smallBuf = 0;
4338                         psrch_inf->srch_entries_start =
4339                                 (char *) &pSMBr->hdr.Protocol +
4340                                         le16_to_cpu(pSMBr->t2.DataOffset);
4341                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4342                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4343
4344                         if (parms->EndofSearch)
4345                                 psrch_inf->endOfSearch = true;
4346                         else
4347                                 psrch_inf->endOfSearch = false;
4348
4349                         psrch_inf->entries_in_buffer =
4350                                         le16_to_cpu(parms->SearchCount);
4351                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4352                                 psrch_inf->entries_in_buffer;
4353                         lnoff = le16_to_cpu(parms->LastNameOffset);
4354                         if (CIFSMaxBufSize < lnoff) {
4355                                 cERROR(1, "ignoring corrupt resume name");
4356                                 psrch_inf->last_entry = NULL;
4357                                 return rc;
4358                         }
4359
4360                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4361                                                         lnoff;
4362
4363                         if (pnetfid)
4364                                 *pnetfid = parms->SearchHandle;
4365                 } else {
4366                         cifs_buf_release(pSMB);
4367                 }
4368         }
4369
4370         return rc;
4371 }
4372
4373 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4374                  __u16 searchHandle, __u16 search_flags,
4375                  struct cifs_search_info *psrch_inf)
4376 {
4377         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4378         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4379         T2_FNEXT_RSP_PARMS *parms;
4380         char *response_data;
4381         int rc = 0;
4382         int bytes_returned;
4383         unsigned int name_len;
4384         __u16 params, byte_count;
4385
4386         cFYI(1, "In FindNext");
4387
4388         if (psrch_inf->endOfSearch)
4389                 return -ENOENT;
4390
4391         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4392                 (void **) &pSMBr);
4393         if (rc)
4394                 return rc;
4395
4396         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4397         byte_count = 0;
4398         pSMB->TotalDataCount = 0;       /* no EAs */
4399         pSMB->MaxParameterCount = cpu_to_le16(8);
4400         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4401         pSMB->MaxSetupCount = 0;
4402         pSMB->Reserved = 0;
4403         pSMB->Flags = 0;
4404         pSMB->Timeout = 0;
4405         pSMB->Reserved2 = 0;
4406         pSMB->ParameterOffset =  cpu_to_le16(
4407               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4408         pSMB->DataCount = 0;
4409         pSMB->DataOffset = 0;
4410         pSMB->SetupCount = 1;
4411         pSMB->Reserved3 = 0;
4412         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4413         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4414         pSMB->SearchCount =
4415                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4416         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4417         pSMB->ResumeKey = psrch_inf->resume_key;
4418         pSMB->SearchFlags = cpu_to_le16(search_flags);
4419
4420         name_len = psrch_inf->resume_name_len;
4421         params += name_len;
4422         if (name_len < PATH_MAX) {
4423                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4424                 byte_count += name_len;
4425                 /* 14 byte parm len above enough for 2 byte null terminator */
4426                 pSMB->ResumeFileName[name_len] = 0;
4427                 pSMB->ResumeFileName[name_len+1] = 0;
4428         } else {
4429                 rc = -EINVAL;
4430                 goto FNext2_err_exit;
4431         }
4432         byte_count = params + 1 /* pad */ ;
4433         pSMB->TotalParameterCount = cpu_to_le16(params);
4434         pSMB->ParameterCount = pSMB->TotalParameterCount;
4435         inc_rfc1001_len(pSMB, byte_count);
4436         pSMB->ByteCount = cpu_to_le16(byte_count);
4437
4438         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4439                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4440         cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4441         if (rc) {
4442                 if (rc == -EBADF) {
4443                         psrch_inf->endOfSearch = true;
4444                         cifs_buf_release(pSMB);
4445                         rc = 0; /* search probably was closed at end of search*/
4446                 } else
4447                         cFYI(1, "FindNext returned = %d", rc);
4448         } else {                /* decode response */
4449                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4450
4451                 if (rc == 0) {
4452                         unsigned int lnoff;
4453
4454                         /* BB fixme add lock for file (srch_info) struct here */
4455                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4456                                 psrch_inf->unicode = true;
4457                         else
4458                                 psrch_inf->unicode = false;
4459                         response_data = (char *) &pSMBr->hdr.Protocol +
4460                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4461                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4462                         response_data = (char *)&pSMBr->hdr.Protocol +
4463                                 le16_to_cpu(pSMBr->t2.DataOffset);
4464                         if (psrch_inf->smallBuf)
4465                                 cifs_small_buf_release(
4466                                         psrch_inf->ntwrk_buf_start);
4467                         else
4468                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4469                         psrch_inf->srch_entries_start = response_data;
4470                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4471                         psrch_inf->smallBuf = 0;
4472                         if (parms->EndofSearch)
4473                                 psrch_inf->endOfSearch = true;
4474                         else
4475                                 psrch_inf->endOfSearch = false;
4476                         psrch_inf->entries_in_buffer =
4477                                                 le16_to_cpu(parms->SearchCount);
4478                         psrch_inf->index_of_last_entry +=
4479                                 psrch_inf->entries_in_buffer;
4480                         lnoff = le16_to_cpu(parms->LastNameOffset);
4481                         if (CIFSMaxBufSize < lnoff) {
4482                                 cERROR(1, "ignoring corrupt resume name");
4483                                 psrch_inf->last_entry = NULL;
4484                                 return rc;
4485                         } else
4486                                 psrch_inf->last_entry =
4487                                         psrch_inf->srch_entries_start + lnoff;
4488
4489 /*  cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4490             psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4491
4492                         /* BB fixme add unlock here */
4493                 }
4494
4495         }
4496
4497         /* BB On error, should we leave previous search buf (and count and
4498         last entry fields) intact or free the previous one? */
4499
4500         /* Note: On -EAGAIN error only caller can retry on handle based calls
4501         since file handle passed in no longer valid */
4502 FNext2_err_exit:
4503         if (rc != 0)
4504                 cifs_buf_release(pSMB);
4505         return rc;
4506 }
4507
4508 int
4509 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4510               const __u16 searchHandle)
4511 {
4512         int rc = 0;
4513         FINDCLOSE_REQ *pSMB = NULL;
4514
4515         cFYI(1, "In CIFSSMBFindClose");
4516         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4517
4518         /* no sense returning error if session restarted
4519                 as file handle has been closed */
4520         if (rc == -EAGAIN)
4521                 return 0;
4522         if (rc)
4523                 return rc;
4524
4525         pSMB->FileID = searchHandle;
4526         pSMB->ByteCount = 0;
4527         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4528         if (rc)
4529                 cERROR(1, "Send error in FindClose = %d", rc);
4530
4531         cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4532
4533         /* Since session is dead, search handle closed on server already */
4534         if (rc == -EAGAIN)
4535                 rc = 0;
4536
4537         return rc;
4538 }
4539
4540 int
4541 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4542                       const char *search_name, __u64 *inode_number,
4543                       const struct nls_table *nls_codepage, int remap)
4544 {
4545         int rc = 0;
4546         TRANSACTION2_QPI_REQ *pSMB = NULL;
4547         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4548         int name_len, bytes_returned;
4549         __u16 params, byte_count;
4550
4551         cFYI(1, "In GetSrvInodeNum for %s", search_name);
4552         if (tcon == NULL)
4553                 return -ENODEV;
4554
4555 GetInodeNumberRetry:
4556         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4557                       (void **) &pSMBr);
4558         if (rc)
4559                 return rc;
4560
4561         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4562                 name_len =
4563                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4564                                            search_name, PATH_MAX, nls_codepage,
4565                                            remap);
4566                 name_len++;     /* trailing null */
4567                 name_len *= 2;
4568         } else {        /* BB improve the check for buffer overruns BB */
4569                 name_len = strnlen(search_name, PATH_MAX);
4570                 name_len++;     /* trailing null */
4571                 strncpy(pSMB->FileName, search_name, name_len);
4572         }
4573
4574         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4575         pSMB->TotalDataCount = 0;
4576         pSMB->MaxParameterCount = cpu_to_le16(2);
4577         /* BB find exact max data count below from sess structure BB */
4578         pSMB->MaxDataCount = cpu_to_le16(4000);
4579         pSMB->MaxSetupCount = 0;
4580         pSMB->Reserved = 0;
4581         pSMB->Flags = 0;
4582         pSMB->Timeout = 0;
4583         pSMB->Reserved2 = 0;
4584         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4585                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4586         pSMB->DataCount = 0;
4587         pSMB->DataOffset = 0;
4588         pSMB->SetupCount = 1;
4589         pSMB->Reserved3 = 0;
4590         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4591         byte_count = params + 1 /* pad */ ;
4592         pSMB->TotalParameterCount = cpu_to_le16(params);
4593         pSMB->ParameterCount = pSMB->TotalParameterCount;
4594         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4595         pSMB->Reserved4 = 0;
4596         inc_rfc1001_len(pSMB, byte_count);
4597         pSMB->ByteCount = cpu_to_le16(byte_count);
4598
4599         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4600                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4601         if (rc) {
4602                 cFYI(1, "error %d in QueryInternalInfo", rc);
4603         } else {
4604                 /* decode response */
4605                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4606                 /* BB also check enough total bytes returned */
4607                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4608                         /* If rc should we check for EOPNOSUPP and
4609                         disable the srvino flag? or in caller? */
4610                         rc = -EIO;      /* bad smb */
4611                 else {
4612                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4613                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4614                         struct file_internal_info *pfinfo;
4615                         /* BB Do we need a cast or hash here ? */
4616                         if (count < 8) {
4617                                 cFYI(1, "Illegal size ret in QryIntrnlInf");
4618                                 rc = -EIO;
4619                                 goto GetInodeNumOut;
4620                         }
4621                         pfinfo = (struct file_internal_info *)
4622                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4623                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4624                 }
4625         }
4626 GetInodeNumOut:
4627         cifs_buf_release(pSMB);
4628         if (rc == -EAGAIN)
4629                 goto GetInodeNumberRetry;
4630         return rc;
4631 }
4632
4633 /* parses DFS refferal V3 structure
4634  * caller is responsible for freeing target_nodes
4635  * returns:
4636  *      on success - 0
4637  *      on failure - errno
4638  */
4639 static int
4640 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4641                 unsigned int *num_of_nodes,
4642                 struct dfs_info3_param **target_nodes,
4643                 const struct nls_table *nls_codepage, int remap,
4644                 const char *searchName)
4645 {
4646         int i, rc = 0;
4647         char *data_end;
4648         bool is_unicode;
4649         struct dfs_referral_level_3 *ref;
4650
4651         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4652                 is_unicode = true;
4653         else
4654                 is_unicode = false;
4655         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4656
4657         if (*num_of_nodes < 1) {
4658                 cERROR(1, "num_referrals: must be at least > 0,"
4659                         "but we get num_referrals = %d", *num_of_nodes);
4660                 rc = -EINVAL;
4661                 goto parse_DFS_referrals_exit;
4662         }
4663
4664         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4665         if (ref->VersionNumber != cpu_to_le16(3)) {
4666                 cERROR(1, "Referrals of V%d version are not supported,"
4667                         "should be V3", le16_to_cpu(ref->VersionNumber));
4668                 rc = -EINVAL;
4669                 goto parse_DFS_referrals_exit;
4670         }
4671
4672         /* get the upper boundary of the resp buffer */
4673         data_end = (char *)(&(pSMBr->PathConsumed)) +
4674                                 le16_to_cpu(pSMBr->t2.DataCount);
4675
4676         cFYI(1, "num_referrals: %d dfs flags: 0x%x ...",
4677                         *num_of_nodes,
4678                         le32_to_cpu(pSMBr->DFSFlags));
4679
4680         *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4681                         *num_of_nodes, GFP_KERNEL);
4682         if (*target_nodes == NULL) {
4683                 cERROR(1, "Failed to allocate buffer for target_nodes");
4684                 rc = -ENOMEM;
4685                 goto parse_DFS_referrals_exit;
4686         }
4687
4688         /* collect necessary data from referrals */
4689         for (i = 0; i < *num_of_nodes; i++) {
4690                 char *temp;
4691                 int max_len;
4692                 struct dfs_info3_param *node = (*target_nodes)+i;
4693
4694                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4695                 if (is_unicode) {
4696                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4697                                                 GFP_KERNEL);
4698                         if (tmp == NULL) {
4699                                 rc = -ENOMEM;
4700                                 goto parse_DFS_referrals_exit;
4701                         }
4702                         cifsConvertToUTF16((__le16 *) tmp, searchName,
4703                                            PATH_MAX, nls_codepage, remap);
4704                         node->path_consumed = cifs_utf16_bytes(tmp,
4705                                         le16_to_cpu(pSMBr->PathConsumed),
4706                                         nls_codepage);
4707                         kfree(tmp);
4708                 } else
4709                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4710
4711                 node->server_type = le16_to_cpu(ref->ServerType);
4712                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4713
4714                 /* copy DfsPath */
4715                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4716                 max_len = data_end - temp;
4717                 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4718                                                 is_unicode, nls_codepage);
4719                 if (!node->path_name) {
4720                         rc = -ENOMEM;
4721                         goto parse_DFS_referrals_exit;
4722                 }
4723
4724                 /* copy link target UNC */
4725                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4726                 max_len = data_end - temp;
4727                 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4728                                                 is_unicode, nls_codepage);
4729                 if (!node->node_name) {
4730                         rc = -ENOMEM;
4731                         goto parse_DFS_referrals_exit;
4732                 }
4733
4734                 ref++;
4735         }
4736
4737 parse_DFS_referrals_exit:
4738         if (rc) {
4739                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4740                 *target_nodes = NULL;
4741                 *num_of_nodes = 0;
4742         }
4743         return rc;
4744 }
4745
4746 int
4747 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4748                 const char *search_name, struct dfs_info3_param **target_nodes,
4749                 unsigned int *num_of_nodes,
4750                 const struct nls_table *nls_codepage, int remap)
4751 {
4752 /* TRANS2_GET_DFS_REFERRAL */
4753         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4754         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4755         int rc = 0;
4756         int bytes_returned;
4757         int name_len;
4758         __u16 params, byte_count;
4759         *num_of_nodes = 0;
4760         *target_nodes = NULL;
4761
4762         cFYI(1, "In GetDFSRefer the path %s", search_name);
4763         if (ses == NULL)
4764                 return -ENODEV;
4765 getDFSRetry:
4766         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4767                       (void **) &pSMBr);
4768         if (rc)
4769                 return rc;
4770
4771         /* server pointer checked in called function,
4772         but should never be null here anyway */
4773         pSMB->hdr.Mid = get_next_mid(ses->server);
4774         pSMB->hdr.Tid = ses->ipc_tid;
4775         pSMB->hdr.Uid = ses->Suid;
4776         if (ses->capabilities & CAP_STATUS32)
4777                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4778         if (ses->capabilities & CAP_DFS)
4779                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4780
4781         if (ses->capabilities & CAP_UNICODE) {
4782                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4783                 name_len =
4784                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4785                                        search_name, PATH_MAX, nls_codepage,
4786                                        remap);
4787                 name_len++;     /* trailing null */
4788                 name_len *= 2;
4789         } else {        /* BB improve the check for buffer overruns BB */
4790                 name_len = strnlen(search_name, PATH_MAX);
4791                 name_len++;     /* trailing null */
4792                 strncpy(pSMB->RequestFileName, search_name, name_len);
4793         }
4794
4795         if (ses->server) {
4796                 if (ses->server->sec_mode &
4797                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4798                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4799         }
4800
4801         pSMB->hdr.Uid = ses->Suid;
4802
4803         params = 2 /* level */  + name_len /*includes null */ ;
4804         pSMB->TotalDataCount = 0;
4805         pSMB->DataCount = 0;
4806         pSMB->DataOffset = 0;
4807         pSMB->MaxParameterCount = 0;
4808         /* BB find exact max SMB PDU from sess structure BB */
4809         pSMB->MaxDataCount = cpu_to_le16(4000);
4810         pSMB->MaxSetupCount = 0;
4811         pSMB->Reserved = 0;
4812         pSMB->Flags = 0;
4813         pSMB->Timeout = 0;
4814         pSMB->Reserved2 = 0;
4815         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4816           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4817         pSMB->SetupCount = 1;
4818         pSMB->Reserved3 = 0;
4819         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4820         byte_count = params + 3 /* pad */ ;
4821         pSMB->ParameterCount = cpu_to_le16(params);
4822         pSMB->TotalParameterCount = pSMB->ParameterCount;
4823         pSMB->MaxReferralLevel = cpu_to_le16(3);
4824         inc_rfc1001_len(pSMB, byte_count);
4825         pSMB->ByteCount = cpu_to_le16(byte_count);
4826
4827         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4828                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4829         if (rc) {
4830                 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4831                 goto GetDFSRefExit;
4832         }
4833         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4834
4835         /* BB Also check if enough total bytes returned? */
4836         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4837                 rc = -EIO;      /* bad smb */
4838                 goto GetDFSRefExit;
4839         }
4840
4841         cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
4842                                 get_bcc(&pSMBr->hdr),
4843                                 le16_to_cpu(pSMBr->t2.DataOffset));
4844
4845         /* parse returned result into more usable form */
4846         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4847                                  target_nodes, nls_codepage, remap,
4848                                  search_name);
4849
4850 GetDFSRefExit:
4851         cifs_buf_release(pSMB);
4852
4853         if (rc == -EAGAIN)
4854                 goto getDFSRetry;
4855
4856         return rc;
4857 }
4858
4859 /* Query File System Info such as free space to old servers such as Win 9x */
4860 int
4861 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4862               struct kstatfs *FSData)
4863 {
4864 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4865         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4866         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4867         FILE_SYSTEM_ALLOC_INFO *response_data;
4868         int rc = 0;
4869         int bytes_returned = 0;
4870         __u16 params, byte_count;
4871
4872         cFYI(1, "OldQFSInfo");
4873 oldQFSInfoRetry:
4874         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4875                 (void **) &pSMBr);
4876         if (rc)
4877                 return rc;
4878
4879         params = 2;     /* level */
4880         pSMB->TotalDataCount = 0;
4881         pSMB->MaxParameterCount = cpu_to_le16(2);
4882         pSMB->MaxDataCount = cpu_to_le16(1000);
4883         pSMB->MaxSetupCount = 0;
4884         pSMB->Reserved = 0;
4885         pSMB->Flags = 0;
4886         pSMB->Timeout = 0;
4887         pSMB->Reserved2 = 0;
4888         byte_count = params + 1 /* pad */ ;
4889         pSMB->TotalParameterCount = cpu_to_le16(params);
4890         pSMB->ParameterCount = pSMB->TotalParameterCount;
4891         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4892         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4893         pSMB->DataCount = 0;
4894         pSMB->DataOffset = 0;
4895         pSMB->SetupCount = 1;
4896         pSMB->Reserved3 = 0;
4897         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4898         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4899         inc_rfc1001_len(pSMB, byte_count);
4900         pSMB->ByteCount = cpu_to_le16(byte_count);
4901
4902         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4903                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4904         if (rc) {
4905                 cFYI(1, "Send error in QFSInfo = %d", rc);
4906         } else {                /* decode response */
4907                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4908
4909                 if (rc || get_bcc(&pSMBr->hdr) < 18)
4910                         rc = -EIO;      /* bad smb */
4911                 else {
4912                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4913                         cFYI(1, "qfsinf resp BCC: %d  Offset %d",
4914                                  get_bcc(&pSMBr->hdr), data_offset);
4915
4916                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
4917                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4918                         FSData->f_bsize =
4919                                 le16_to_cpu(response_data->BytesPerSector) *
4920                                 le32_to_cpu(response_data->
4921                                         SectorsPerAllocationUnit);
4922                         FSData->f_blocks =
4923                                le32_to_cpu(response_data->TotalAllocationUnits);
4924                         FSData->f_bfree = FSData->f_bavail =
4925                                 le32_to_cpu(response_data->FreeAllocationUnits);
4926                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
4927                              (unsigned long long)FSData->f_blocks,
4928                              (unsigned long long)FSData->f_bfree,
4929                              FSData->f_bsize);
4930                 }
4931         }
4932         cifs_buf_release(pSMB);
4933
4934         if (rc == -EAGAIN)
4935                 goto oldQFSInfoRetry;
4936
4937         return rc;
4938 }
4939
4940 int
4941 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4942                struct kstatfs *FSData)
4943 {
4944 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4945         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4946         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4947         FILE_SYSTEM_INFO *response_data;
4948         int rc = 0;
4949         int bytes_returned = 0;
4950         __u16 params, byte_count;
4951
4952         cFYI(1, "In QFSInfo");
4953 QFSInfoRetry:
4954         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4955                       (void **) &pSMBr);
4956         if (rc)
4957                 return rc;
4958
4959         params = 2;     /* level */
4960         pSMB->TotalDataCount = 0;
4961         pSMB->MaxParameterCount = cpu_to_le16(2);
4962         pSMB->MaxDataCount = cpu_to_le16(1000);
4963         pSMB->MaxSetupCount = 0;
4964         pSMB->Reserved = 0;
4965         pSMB->Flags = 0;
4966         pSMB->Timeout = 0;
4967         pSMB->Reserved2 = 0;
4968         byte_count = params + 1 /* pad */ ;
4969         pSMB->TotalParameterCount = cpu_to_le16(params);
4970         pSMB->ParameterCount = pSMB->TotalParameterCount;
4971         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4972                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4973         pSMB->DataCount = 0;
4974         pSMB->DataOffset = 0;
4975         pSMB->SetupCount = 1;
4976         pSMB->Reserved3 = 0;
4977         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4978         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4979         inc_rfc1001_len(pSMB, byte_count);
4980         pSMB->ByteCount = cpu_to_le16(byte_count);
4981
4982         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4983                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4984         if (rc) {
4985                 cFYI(1, "Send error in QFSInfo = %d", rc);
4986         } else {                /* decode response */
4987                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4988
4989                 if (rc || get_bcc(&pSMBr->hdr) < 24)
4990                         rc = -EIO;      /* bad smb */
4991                 else {
4992                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4993
4994                         response_data =
4995                             (FILE_SYSTEM_INFO
4996                              *) (((char *) &pSMBr->hdr.Protocol) +
4997                                  data_offset);
4998                         FSData->f_bsize =
4999                             le32_to_cpu(response_data->BytesPerSector) *
5000                             le32_to_cpu(response_data->
5001                                         SectorsPerAllocationUnit);
5002                         FSData->f_blocks =
5003                             le64_to_cpu(response_data->TotalAllocationUnits);
5004                         FSData->f_bfree = FSData->f_bavail =
5005                             le64_to_cpu(response_data->FreeAllocationUnits);
5006                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5007                              (unsigned long long)FSData->f_blocks,
5008                              (unsigned long long)FSData->f_bfree,
5009                              FSData->f_bsize);
5010                 }
5011         }
5012         cifs_buf_release(pSMB);
5013
5014         if (rc == -EAGAIN)
5015                 goto QFSInfoRetry;
5016
5017         return rc;
5018 }
5019
5020 int
5021 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5022 {
5023 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5024         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5025         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5026         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5027         int rc = 0;
5028         int bytes_returned = 0;
5029         __u16 params, byte_count;
5030
5031         cFYI(1, "In QFSAttributeInfo");
5032 QFSAttributeRetry:
5033         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5034                       (void **) &pSMBr);
5035         if (rc)
5036                 return rc;
5037
5038         params = 2;     /* level */
5039         pSMB->TotalDataCount = 0;
5040         pSMB->MaxParameterCount = cpu_to_le16(2);
5041         /* BB find exact max SMB PDU from sess structure BB */
5042         pSMB->MaxDataCount = cpu_to_le16(1000);
5043         pSMB->MaxSetupCount = 0;
5044         pSMB->Reserved = 0;
5045         pSMB->Flags = 0;
5046         pSMB->Timeout = 0;
5047         pSMB->Reserved2 = 0;
5048         byte_count = params + 1 /* pad */ ;
5049         pSMB->TotalParameterCount = cpu_to_le16(params);
5050         pSMB->ParameterCount = pSMB->TotalParameterCount;
5051         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5052                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5053         pSMB->DataCount = 0;
5054         pSMB->DataOffset = 0;
5055         pSMB->SetupCount = 1;
5056         pSMB->Reserved3 = 0;
5057         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5058         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5059         inc_rfc1001_len(pSMB, byte_count);
5060         pSMB->ByteCount = cpu_to_le16(byte_count);
5061
5062         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5063                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5064         if (rc) {
5065                 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5066         } else {                /* decode response */
5067                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5068
5069                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5070                         /* BB also check if enough bytes returned */
5071                         rc = -EIO;      /* bad smb */
5072                 } else {
5073                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5074                         response_data =
5075                             (FILE_SYSTEM_ATTRIBUTE_INFO
5076                              *) (((char *) &pSMBr->hdr.Protocol) +
5077                                  data_offset);
5078                         memcpy(&tcon->fsAttrInfo, response_data,
5079                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5080                 }
5081         }
5082         cifs_buf_release(pSMB);
5083
5084         if (rc == -EAGAIN)
5085                 goto QFSAttributeRetry;
5086
5087         return rc;
5088 }
5089
5090 int
5091 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5092 {
5093 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5094         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5095         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5096         FILE_SYSTEM_DEVICE_INFO *response_data;
5097         int rc = 0;
5098         int bytes_returned = 0;
5099         __u16 params, byte_count;
5100
5101         cFYI(1, "In QFSDeviceInfo");
5102 QFSDeviceRetry:
5103         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5104                       (void **) &pSMBr);
5105         if (rc)
5106                 return rc;
5107
5108         params = 2;     /* level */
5109         pSMB->TotalDataCount = 0;
5110         pSMB->MaxParameterCount = cpu_to_le16(2);
5111         /* BB find exact max SMB PDU from sess structure BB */
5112         pSMB->MaxDataCount = cpu_to_le16(1000);
5113         pSMB->MaxSetupCount = 0;
5114         pSMB->Reserved = 0;
5115         pSMB->Flags = 0;
5116         pSMB->Timeout = 0;
5117         pSMB->Reserved2 = 0;
5118         byte_count = params + 1 /* pad */ ;
5119         pSMB->TotalParameterCount = cpu_to_le16(params);
5120         pSMB->ParameterCount = pSMB->TotalParameterCount;
5121         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5122                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5123
5124         pSMB->DataCount = 0;
5125         pSMB->DataOffset = 0;
5126         pSMB->SetupCount = 1;
5127         pSMB->Reserved3 = 0;
5128         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5129         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5130         inc_rfc1001_len(pSMB, byte_count);
5131         pSMB->ByteCount = cpu_to_le16(byte_count);
5132
5133         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5134                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5135         if (rc) {
5136                 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5137         } else {                /* decode response */
5138                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5139
5140                 if (rc || get_bcc(&pSMBr->hdr) <
5141                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5142                         rc = -EIO;      /* bad smb */
5143                 else {
5144                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5145                         response_data =
5146                             (FILE_SYSTEM_DEVICE_INFO *)
5147                                 (((char *) &pSMBr->hdr.Protocol) +
5148                                  data_offset);
5149                         memcpy(&tcon->fsDevInfo, response_data,
5150                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5151                 }
5152         }
5153         cifs_buf_release(pSMB);
5154
5155         if (rc == -EAGAIN)
5156                 goto QFSDeviceRetry;
5157
5158         return rc;
5159 }
5160
5161 int
5162 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5163 {
5164 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5165         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5166         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5167         FILE_SYSTEM_UNIX_INFO *response_data;
5168         int rc = 0;
5169         int bytes_returned = 0;
5170         __u16 params, byte_count;
5171
5172         cFYI(1, "In QFSUnixInfo");
5173 QFSUnixRetry:
5174         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5175                                    (void **) &pSMB, (void **) &pSMBr);
5176         if (rc)
5177                 return rc;
5178
5179         params = 2;     /* level */
5180         pSMB->TotalDataCount = 0;
5181         pSMB->DataCount = 0;
5182         pSMB->DataOffset = 0;
5183         pSMB->MaxParameterCount = cpu_to_le16(2);
5184         /* BB find exact max SMB PDU from sess structure BB */
5185         pSMB->MaxDataCount = cpu_to_le16(100);
5186         pSMB->MaxSetupCount = 0;
5187         pSMB->Reserved = 0;
5188         pSMB->Flags = 0;
5189         pSMB->Timeout = 0;
5190         pSMB->Reserved2 = 0;
5191         byte_count = params + 1 /* pad */ ;
5192         pSMB->ParameterCount = cpu_to_le16(params);
5193         pSMB->TotalParameterCount = pSMB->ParameterCount;
5194         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5195                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5196         pSMB->SetupCount = 1;
5197         pSMB->Reserved3 = 0;
5198         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5199         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5200         inc_rfc1001_len(pSMB, byte_count);
5201         pSMB->ByteCount = cpu_to_le16(byte_count);
5202
5203         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5204                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5205         if (rc) {
5206                 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5207         } else {                /* decode response */
5208                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5209
5210                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5211                         rc = -EIO;      /* bad smb */
5212                 } else {
5213                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5214                         response_data =
5215                             (FILE_SYSTEM_UNIX_INFO
5216                              *) (((char *) &pSMBr->hdr.Protocol) +
5217                                  data_offset);
5218                         memcpy(&tcon->fsUnixInfo, response_data,
5219                                sizeof(FILE_SYSTEM_UNIX_INFO));
5220                 }
5221         }
5222         cifs_buf_release(pSMB);
5223
5224         if (rc == -EAGAIN)
5225                 goto QFSUnixRetry;
5226
5227
5228         return rc;
5229 }
5230
5231 int
5232 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5233 {
5234 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5235         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5236         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5237         int rc = 0;
5238         int bytes_returned = 0;
5239         __u16 params, param_offset, offset, byte_count;
5240
5241         cFYI(1, "In SETFSUnixInfo");
5242 SETFSUnixRetry:
5243         /* BB switch to small buf init to save memory */
5244         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5245                                         (void **) &pSMB, (void **) &pSMBr);
5246         if (rc)
5247                 return rc;
5248
5249         params = 4;     /* 2 bytes zero followed by info level. */
5250         pSMB->MaxSetupCount = 0;
5251         pSMB->Reserved = 0;
5252         pSMB->Flags = 0;
5253         pSMB->Timeout = 0;
5254         pSMB->Reserved2 = 0;
5255         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5256                                 - 4;
5257         offset = param_offset + params;
5258
5259         pSMB->MaxParameterCount = cpu_to_le16(4);
5260         /* BB find exact max SMB PDU from sess structure BB */
5261         pSMB->MaxDataCount = cpu_to_le16(100);
5262         pSMB->SetupCount = 1;
5263         pSMB->Reserved3 = 0;
5264         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5265         byte_count = 1 /* pad */ + params + 12;
5266
5267         pSMB->DataCount = cpu_to_le16(12);
5268         pSMB->ParameterCount = cpu_to_le16(params);
5269         pSMB->TotalDataCount = pSMB->DataCount;
5270         pSMB->TotalParameterCount = pSMB->ParameterCount;
5271         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5272         pSMB->DataOffset = cpu_to_le16(offset);
5273
5274         /* Params. */
5275         pSMB->FileNum = 0;
5276         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5277
5278         /* Data. */
5279         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5280         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5281         pSMB->ClientUnixCap = cpu_to_le64(cap);
5282
5283         inc_rfc1001_len(pSMB, byte_count);
5284         pSMB->ByteCount = cpu_to_le16(byte_count);
5285
5286         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5287                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5288         if (rc) {
5289                 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5290         } else {                /* decode response */
5291                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5292                 if (rc)
5293                         rc = -EIO;      /* bad smb */
5294         }
5295         cifs_buf_release(pSMB);
5296
5297         if (rc == -EAGAIN)
5298                 goto SETFSUnixRetry;
5299
5300         return rc;
5301 }
5302
5303
5304
5305 int
5306 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5307                    struct kstatfs *FSData)
5308 {
5309 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5310         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5311         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5312         FILE_SYSTEM_POSIX_INFO *response_data;
5313         int rc = 0;
5314         int bytes_returned = 0;
5315         __u16 params, byte_count;
5316
5317         cFYI(1, "In QFSPosixInfo");
5318 QFSPosixRetry:
5319         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5320                       (void **) &pSMBr);
5321         if (rc)
5322                 return rc;
5323
5324         params = 2;     /* level */
5325         pSMB->TotalDataCount = 0;
5326         pSMB->DataCount = 0;
5327         pSMB->DataOffset = 0;
5328         pSMB->MaxParameterCount = cpu_to_le16(2);
5329         /* BB find exact max SMB PDU from sess structure BB */
5330         pSMB->MaxDataCount = cpu_to_le16(100);
5331         pSMB->MaxSetupCount = 0;
5332         pSMB->Reserved = 0;
5333         pSMB->Flags = 0;
5334         pSMB->Timeout = 0;
5335         pSMB->Reserved2 = 0;
5336         byte_count = params + 1 /* pad */ ;
5337         pSMB->ParameterCount = cpu_to_le16(params);
5338         pSMB->TotalParameterCount = pSMB->ParameterCount;
5339         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5340                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5341         pSMB->SetupCount = 1;
5342         pSMB->Reserved3 = 0;
5343         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5344         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5345         inc_rfc1001_len(pSMB, byte_count);
5346         pSMB->ByteCount = cpu_to_le16(byte_count);
5347
5348         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5349                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5350         if (rc) {
5351                 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5352         } else {                /* decode response */
5353                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5354
5355                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5356                         rc = -EIO;      /* bad smb */
5357                 } else {
5358                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5359                         response_data =
5360                             (FILE_SYSTEM_POSIX_INFO
5361                              *) (((char *) &pSMBr->hdr.Protocol) +
5362                                  data_offset);
5363                         FSData->f_bsize =
5364                                         le32_to_cpu(response_data->BlockSize);
5365                         FSData->f_blocks =
5366                                         le64_to_cpu(response_data->TotalBlocks);
5367                         FSData->f_bfree =
5368                             le64_to_cpu(response_data->BlocksAvail);
5369                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5370                                 FSData->f_bavail = FSData->f_bfree;
5371                         } else {
5372                                 FSData->f_bavail =
5373                                     le64_to_cpu(response_data->UserBlocksAvail);
5374                         }
5375                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5376                                 FSData->f_files =
5377                                      le64_to_cpu(response_data->TotalFileNodes);
5378                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5379                                 FSData->f_ffree =
5380                                       le64_to_cpu(response_data->FreeFileNodes);
5381                 }
5382         }
5383         cifs_buf_release(pSMB);
5384
5385         if (rc == -EAGAIN)
5386                 goto QFSPosixRetry;
5387
5388         return rc;
5389 }
5390
5391
5392 /*
5393  * We can not use write of zero bytes trick to set file size due to need for
5394  * large file support. Also note that this SetPathInfo is preferred to
5395  * SetFileInfo based method in next routine which is only needed to work around
5396  * a sharing violation bugin Samba which this routine can run into.
5397  */
5398 int
5399 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5400               const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5401               bool set_allocation)
5402 {
5403         struct smb_com_transaction2_spi_req *pSMB = NULL;
5404         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5405         struct file_end_of_file_info *parm_data;
5406         int name_len;
5407         int rc = 0;
5408         int bytes_returned = 0;
5409         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
5410
5411         __u16 params, byte_count, data_count, param_offset, offset;
5412
5413         cFYI(1, "In SetEOF");
5414 SetEOFRetry:
5415         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5416                       (void **) &pSMBr);
5417         if (rc)
5418                 return rc;
5419
5420         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5421                 name_len =
5422                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5423                                        PATH_MAX, cifs_sb->local_nls, remap);
5424                 name_len++;     /* trailing null */
5425                 name_len *= 2;
5426         } else {        /* BB improve the check for buffer overruns BB */
5427                 name_len = strnlen(file_name, PATH_MAX);
5428                 name_len++;     /* trailing null */
5429                 strncpy(pSMB->FileName, file_name, name_len);
5430         }
5431         params = 6 + name_len;
5432         data_count = sizeof(struct file_end_of_file_info);
5433         pSMB->MaxParameterCount = cpu_to_le16(2);
5434         pSMB->MaxDataCount = cpu_to_le16(4100);
5435         pSMB->MaxSetupCount = 0;
5436         pSMB->Reserved = 0;
5437         pSMB->Flags = 0;
5438         pSMB->Timeout = 0;
5439         pSMB->Reserved2 = 0;
5440         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5441                                 InformationLevel) - 4;
5442         offset = param_offset + params;
5443         if (set_allocation) {
5444                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5445                         pSMB->InformationLevel =
5446                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5447                 else
5448                         pSMB->InformationLevel =
5449                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5450         } else /* Set File Size */  {
5451             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5452                     pSMB->InformationLevel =
5453                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5454             else
5455                     pSMB->InformationLevel =
5456                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5457         }
5458
5459         parm_data =
5460             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5461                                        offset);
5462         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5463         pSMB->DataOffset = cpu_to_le16(offset);
5464         pSMB->SetupCount = 1;
5465         pSMB->Reserved3 = 0;
5466         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5467         byte_count = 3 /* pad */  + params + data_count;
5468         pSMB->DataCount = cpu_to_le16(data_count);
5469         pSMB->TotalDataCount = pSMB->DataCount;
5470         pSMB->ParameterCount = cpu_to_le16(params);
5471         pSMB->TotalParameterCount = pSMB->ParameterCount;
5472         pSMB->Reserved4 = 0;
5473         inc_rfc1001_len(pSMB, byte_count);
5474         parm_data->FileSize = cpu_to_le64(size);
5475         pSMB->ByteCount = cpu_to_le16(byte_count);
5476         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5477                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5478         if (rc)
5479                 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5480
5481         cifs_buf_release(pSMB);
5482
5483         if (rc == -EAGAIN)
5484                 goto SetEOFRetry;
5485
5486         return rc;
5487 }
5488
5489 int
5490 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5491                    struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5492 {
5493         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5494         struct file_end_of_file_info *parm_data;
5495         int rc = 0;
5496         __u16 params, param_offset, offset, byte_count, count;
5497
5498         cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5499                         (long long)size);
5500         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5501
5502         if (rc)
5503                 return rc;
5504
5505         pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5506         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5507
5508         params = 6;
5509         pSMB->MaxSetupCount = 0;
5510         pSMB->Reserved = 0;
5511         pSMB->Flags = 0;
5512         pSMB->Timeout = 0;
5513         pSMB->Reserved2 = 0;
5514         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5515         offset = param_offset + params;
5516
5517         count = sizeof(struct file_end_of_file_info);
5518         pSMB->MaxParameterCount = cpu_to_le16(2);
5519         /* BB find exact max SMB PDU from sess structure BB */
5520         pSMB->MaxDataCount = cpu_to_le16(1000);
5521         pSMB->SetupCount = 1;
5522         pSMB->Reserved3 = 0;
5523         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5524         byte_count = 3 /* pad */  + params + count;
5525         pSMB->DataCount = cpu_to_le16(count);
5526         pSMB->ParameterCount = cpu_to_le16(params);
5527         pSMB->TotalDataCount = pSMB->DataCount;
5528         pSMB->TotalParameterCount = pSMB->ParameterCount;
5529         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5530         parm_data =
5531                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5532                                 + offset);
5533         pSMB->DataOffset = cpu_to_le16(offset);
5534         parm_data->FileSize = cpu_to_le64(size);
5535         pSMB->Fid = cfile->fid.netfid;
5536         if (set_allocation) {
5537                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5538                         pSMB->InformationLevel =
5539                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5540                 else
5541                         pSMB->InformationLevel =
5542                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5543         } else /* Set File Size */  {
5544             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5545                     pSMB->InformationLevel =
5546                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5547             else
5548                     pSMB->InformationLevel =
5549                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5550         }
5551         pSMB->Reserved4 = 0;
5552         inc_rfc1001_len(pSMB, byte_count);
5553         pSMB->ByteCount = cpu_to_le16(byte_count);
5554         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5555         if (rc) {
5556                 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5557         }
5558
5559         /* Note: On -EAGAIN error only caller can retry on handle based calls
5560                 since file handle passed in no longer valid */
5561
5562         return rc;
5563 }
5564
5565 /* Some legacy servers such as NT4 require that the file times be set on
5566    an open handle, rather than by pathname - this is awkward due to
5567    potential access conflicts on the open, but it is unavoidable for these
5568    old servers since the only other choice is to go from 100 nanosecond DCE
5569    time and resort to the original setpathinfo level which takes the ancient
5570    DOS time format with 2 second granularity */
5571 int
5572 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5573                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5574 {
5575         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5576         char *data_offset;
5577         int rc = 0;
5578         __u16 params, param_offset, offset, byte_count, count;
5579
5580         cFYI(1, "Set Times (via SetFileInfo)");
5581         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5582
5583         if (rc)
5584                 return rc;
5585
5586         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5587         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5588
5589         params = 6;
5590         pSMB->MaxSetupCount = 0;
5591         pSMB->Reserved = 0;
5592         pSMB->Flags = 0;
5593         pSMB->Timeout = 0;
5594         pSMB->Reserved2 = 0;
5595         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5596         offset = param_offset + params;
5597
5598         data_offset = (char *)pSMB +
5599                         offsetof(struct smb_hdr, Protocol) + offset;
5600
5601         count = sizeof(FILE_BASIC_INFO);
5602         pSMB->MaxParameterCount = cpu_to_le16(2);
5603         /* BB find max SMB PDU from sess */
5604         pSMB->MaxDataCount = cpu_to_le16(1000);
5605         pSMB->SetupCount = 1;
5606         pSMB->Reserved3 = 0;
5607         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5608         byte_count = 3 /* pad */  + params + count;
5609         pSMB->DataCount = cpu_to_le16(count);
5610         pSMB->ParameterCount = cpu_to_le16(params);
5611         pSMB->TotalDataCount = pSMB->DataCount;
5612         pSMB->TotalParameterCount = pSMB->ParameterCount;
5613         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5614         pSMB->DataOffset = cpu_to_le16(offset);
5615         pSMB->Fid = fid;
5616         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5617                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5618         else
5619                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5620         pSMB->Reserved4 = 0;
5621         inc_rfc1001_len(pSMB, byte_count);
5622         pSMB->ByteCount = cpu_to_le16(byte_count);
5623         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5624         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5625         if (rc)
5626                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5627
5628         /* Note: On -EAGAIN error only caller can retry on handle based calls
5629                 since file handle passed in no longer valid */
5630
5631         return rc;
5632 }
5633
5634 int
5635 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5636                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5637 {
5638         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5639         char *data_offset;
5640         int rc = 0;
5641         __u16 params, param_offset, offset, byte_count, count;
5642
5643         cFYI(1, "Set File Disposition (via SetFileInfo)");
5644         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5645
5646         if (rc)
5647                 return rc;
5648
5649         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5650         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5651
5652         params = 6;
5653         pSMB->MaxSetupCount = 0;
5654         pSMB->Reserved = 0;
5655         pSMB->Flags = 0;
5656         pSMB->Timeout = 0;
5657         pSMB->Reserved2 = 0;
5658         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5659         offset = param_offset + params;
5660
5661         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5662
5663         count = 1;
5664         pSMB->MaxParameterCount = cpu_to_le16(2);
5665         /* BB find max SMB PDU from sess */
5666         pSMB->MaxDataCount = cpu_to_le16(1000);
5667         pSMB->SetupCount = 1;
5668         pSMB->Reserved3 = 0;
5669         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5670         byte_count = 3 /* pad */  + params + count;
5671         pSMB->DataCount = cpu_to_le16(count);
5672         pSMB->ParameterCount = cpu_to_le16(params);
5673         pSMB->TotalDataCount = pSMB->DataCount;
5674         pSMB->TotalParameterCount = pSMB->ParameterCount;
5675         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5676         pSMB->DataOffset = cpu_to_le16(offset);
5677         pSMB->Fid = fid;
5678         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5679         pSMB->Reserved4 = 0;
5680         inc_rfc1001_len(pSMB, byte_count);
5681         pSMB->ByteCount = cpu_to_le16(byte_count);
5682         *data_offset = delete_file ? 1 : 0;
5683         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5684         if (rc)
5685                 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5686
5687         return rc;
5688 }
5689
5690 int
5691 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5692                    const char *fileName, const FILE_BASIC_INFO *data,
5693                    const struct nls_table *nls_codepage, int remap)
5694 {
5695         TRANSACTION2_SPI_REQ *pSMB = NULL;
5696         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5697         int name_len;
5698         int rc = 0;
5699         int bytes_returned = 0;
5700         char *data_offset;
5701         __u16 params, param_offset, offset, byte_count, count;
5702
5703         cFYI(1, "In SetTimes");
5704
5705 SetTimesRetry:
5706         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5707                       (void **) &pSMBr);
5708         if (rc)
5709                 return rc;
5710
5711         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5712                 name_len =
5713                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5714                                        PATH_MAX, nls_codepage, remap);
5715                 name_len++;     /* trailing null */
5716                 name_len *= 2;
5717         } else {        /* BB improve the check for buffer overruns BB */
5718                 name_len = strnlen(fileName, PATH_MAX);
5719                 name_len++;     /* trailing null */
5720                 strncpy(pSMB->FileName, fileName, name_len);
5721         }
5722
5723         params = 6 + name_len;
5724         count = sizeof(FILE_BASIC_INFO);
5725         pSMB->MaxParameterCount = cpu_to_le16(2);
5726         /* BB find max SMB PDU from sess structure BB */
5727         pSMB->MaxDataCount = cpu_to_le16(1000);
5728         pSMB->MaxSetupCount = 0;
5729         pSMB->Reserved = 0;
5730         pSMB->Flags = 0;
5731         pSMB->Timeout = 0;
5732         pSMB->Reserved2 = 0;
5733         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5734                                 InformationLevel) - 4;
5735         offset = param_offset + params;
5736         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5737         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5738         pSMB->DataOffset = cpu_to_le16(offset);
5739         pSMB->SetupCount = 1;
5740         pSMB->Reserved3 = 0;
5741         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5742         byte_count = 3 /* pad */  + params + count;
5743
5744         pSMB->DataCount = cpu_to_le16(count);
5745         pSMB->ParameterCount = cpu_to_le16(params);
5746         pSMB->TotalDataCount = pSMB->DataCount;
5747         pSMB->TotalParameterCount = pSMB->ParameterCount;
5748         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5749                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5750         else
5751                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5752         pSMB->Reserved4 = 0;
5753         inc_rfc1001_len(pSMB, byte_count);
5754         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5755         pSMB->ByteCount = cpu_to_le16(byte_count);
5756         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5757                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5758         if (rc)
5759                 cFYI(1, "SetPathInfo (times) returned %d", rc);
5760
5761         cifs_buf_release(pSMB);
5762
5763         if (rc == -EAGAIN)
5764                 goto SetTimesRetry;
5765
5766         return rc;
5767 }
5768
5769 /* Can not be used to set time stamps yet (due to old DOS time format) */
5770 /* Can be used to set attributes */
5771 #if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
5772           handling it anyway and NT4 was what we thought it would be needed for
5773           Do not delete it until we prove whether needed for Win9x though */
5774 int
5775 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5776                 __u16 dos_attrs, const struct nls_table *nls_codepage)
5777 {
5778         SETATTR_REQ *pSMB = NULL;
5779         SETATTR_RSP *pSMBr = NULL;
5780         int rc = 0;
5781         int bytes_returned;
5782         int name_len;
5783
5784         cFYI(1, "In SetAttrLegacy");
5785
5786 SetAttrLgcyRetry:
5787         rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5788                       (void **) &pSMBr);
5789         if (rc)
5790                 return rc;
5791
5792         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5793                 name_len =
5794                         ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5795                                        PATH_MAX, nls_codepage);
5796                 name_len++;     /* trailing null */
5797                 name_len *= 2;
5798         } else {        /* BB improve the check for buffer overruns BB */
5799                 name_len = strnlen(fileName, PATH_MAX);
5800                 name_len++;     /* trailing null */
5801                 strncpy(pSMB->fileName, fileName, name_len);
5802         }
5803         pSMB->attr = cpu_to_le16(dos_attrs);
5804         pSMB->BufferFormat = 0x04;
5805         inc_rfc1001_len(pSMB, name_len + 1);
5806         pSMB->ByteCount = cpu_to_le16(name_len + 1);
5807         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5808                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5809         if (rc)
5810                 cFYI(1, "Error in LegacySetAttr = %d", rc);
5811
5812         cifs_buf_release(pSMB);
5813
5814         if (rc == -EAGAIN)
5815                 goto SetAttrLgcyRetry;
5816
5817         return rc;
5818 }
5819 #endif /* temporarily unneeded SetAttr legacy function */
5820
5821 static void
5822 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5823                         const struct cifs_unix_set_info_args *args)
5824 {
5825         u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5826         u64 mode = args->mode;
5827
5828         if (uid_valid(args->uid))
5829                 uid = from_kuid(&init_user_ns, args->uid);
5830         if (gid_valid(args->gid))
5831                 gid = from_kgid(&init_user_ns, args->gid);
5832
5833         /*
5834          * Samba server ignores set of file size to zero due to bugs in some
5835          * older clients, but we should be precise - we use SetFileSize to
5836          * set file size and do not want to truncate file size to zero
5837          * accidentally as happened on one Samba server beta by putting
5838          * zero instead of -1 here
5839          */
5840         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5841         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5842         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5843         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5844         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5845         data_offset->Uid = cpu_to_le64(uid);
5846         data_offset->Gid = cpu_to_le64(gid);
5847         /* better to leave device as zero when it is  */
5848         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5849         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5850         data_offset->Permissions = cpu_to_le64(mode);
5851
5852         if (S_ISREG(mode))
5853                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5854         else if (S_ISDIR(mode))
5855                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5856         else if (S_ISLNK(mode))
5857                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5858         else if (S_ISCHR(mode))
5859                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5860         else if (S_ISBLK(mode))
5861                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5862         else if (S_ISFIFO(mode))
5863                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5864         else if (S_ISSOCK(mode))
5865                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5866 }
5867
5868 int
5869 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5870                        const struct cifs_unix_set_info_args *args,
5871                        u16 fid, u32 pid_of_opener)
5872 {
5873         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5874         char *data_offset;
5875         int rc = 0;
5876         u16 params, param_offset, offset, byte_count, count;
5877
5878         cFYI(1, "Set Unix Info (via SetFileInfo)");
5879         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5880
5881         if (rc)
5882                 return rc;
5883
5884         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5885         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5886
5887         params = 6;
5888         pSMB->MaxSetupCount = 0;
5889         pSMB->Reserved = 0;
5890         pSMB->Flags = 0;
5891         pSMB->Timeout = 0;
5892         pSMB->Reserved2 = 0;
5893         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5894         offset = param_offset + params;
5895
5896         data_offset = (char *)pSMB +
5897                         offsetof(struct smb_hdr, Protocol) + offset;
5898
5899         count = sizeof(FILE_UNIX_BASIC_INFO);
5900
5901         pSMB->MaxParameterCount = cpu_to_le16(2);
5902         /* BB find max SMB PDU from sess */
5903         pSMB->MaxDataCount = cpu_to_le16(1000);
5904         pSMB->SetupCount = 1;
5905         pSMB->Reserved3 = 0;
5906         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5907         byte_count = 3 /* pad */  + params + count;
5908         pSMB->DataCount = cpu_to_le16(count);
5909         pSMB->ParameterCount = cpu_to_le16(params);
5910         pSMB->TotalDataCount = pSMB->DataCount;
5911         pSMB->TotalParameterCount = pSMB->ParameterCount;
5912         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5913         pSMB->DataOffset = cpu_to_le16(offset);
5914         pSMB->Fid = fid;
5915         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5916         pSMB->Reserved4 = 0;
5917         inc_rfc1001_len(pSMB, byte_count);
5918         pSMB->ByteCount = cpu_to_le16(byte_count);
5919
5920         cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5921
5922         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5923         if (rc)
5924                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5925
5926         /* Note: On -EAGAIN error only caller can retry on handle based calls
5927                 since file handle passed in no longer valid */
5928
5929         return rc;
5930 }
5931
5932 int
5933 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5934                        const char *file_name,
5935                        const struct cifs_unix_set_info_args *args,
5936                        const struct nls_table *nls_codepage, int remap)
5937 {
5938         TRANSACTION2_SPI_REQ *pSMB = NULL;
5939         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5940         int name_len;
5941         int rc = 0;
5942         int bytes_returned = 0;
5943         FILE_UNIX_BASIC_INFO *data_offset;
5944         __u16 params, param_offset, offset, count, byte_count;
5945
5946         cFYI(1, "In SetUID/GID/Mode");
5947 setPermsRetry:
5948         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5949                       (void **) &pSMBr);
5950         if (rc)
5951                 return rc;
5952
5953         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5954                 name_len =
5955                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5956                                        PATH_MAX, nls_codepage, remap);
5957                 name_len++;     /* trailing null */
5958                 name_len *= 2;
5959         } else {        /* BB improve the check for buffer overruns BB */
5960                 name_len = strnlen(file_name, PATH_MAX);
5961                 name_len++;     /* trailing null */
5962                 strncpy(pSMB->FileName, file_name, name_len);
5963         }
5964
5965         params = 6 + name_len;
5966         count = sizeof(FILE_UNIX_BASIC_INFO);
5967         pSMB->MaxParameterCount = cpu_to_le16(2);
5968         /* BB find max SMB PDU from sess structure BB */
5969         pSMB->MaxDataCount = cpu_to_le16(1000);
5970         pSMB->MaxSetupCount = 0;
5971         pSMB->Reserved = 0;
5972         pSMB->Flags = 0;
5973         pSMB->Timeout = 0;
5974         pSMB->Reserved2 = 0;
5975         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5976                                 InformationLevel) - 4;
5977         offset = param_offset + params;
5978         data_offset =
5979             (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
5980                                       offset);
5981         memset(data_offset, 0, count);
5982         pSMB->DataOffset = cpu_to_le16(offset);
5983         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5984         pSMB->SetupCount = 1;
5985         pSMB->Reserved3 = 0;
5986         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5987         byte_count = 3 /* pad */  + params + count;
5988         pSMB->ParameterCount = cpu_to_le16(params);
5989         pSMB->DataCount = cpu_to_le16(count);
5990         pSMB->TotalParameterCount = pSMB->ParameterCount;
5991         pSMB->TotalDataCount = pSMB->DataCount;
5992         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5993         pSMB->Reserved4 = 0;
5994         inc_rfc1001_len(pSMB, byte_count);
5995
5996         cifs_fill_unix_set_info(data_offset, args);
5997
5998         pSMB->ByteCount = cpu_to_le16(byte_count);
5999         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6000                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6001         if (rc)
6002                 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6003
6004         cifs_buf_release(pSMB);
6005         if (rc == -EAGAIN)
6006                 goto setPermsRetry;
6007         return rc;
6008 }
6009
6010 #ifdef CONFIG_CIFS_XATTR
6011 /*
6012  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6013  * function used by listxattr and getxattr type calls. When ea_name is set,
6014  * it looks for that attribute name and stuffs that value into the EAData
6015  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6016  * buffer. In both cases, the return value is either the length of the
6017  * resulting data or a negative error code. If EAData is a NULL pointer then
6018  * the data isn't copied to it, but the length is returned.
6019  */
6020 ssize_t
6021 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6022                 const unsigned char *searchName, const unsigned char *ea_name,
6023                 char *EAData, size_t buf_size,
6024                 const struct nls_table *nls_codepage, int remap)
6025 {
6026                 /* BB assumes one setup word */
6027         TRANSACTION2_QPI_REQ *pSMB = NULL;
6028         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6029         int rc = 0;
6030         int bytes_returned;
6031         int list_len;
6032         struct fealist *ea_response_data;
6033         struct fea *temp_fea;
6034         char *temp_ptr;
6035         char *end_of_smb;
6036         __u16 params, byte_count, data_offset;
6037         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6038
6039         cFYI(1, "In Query All EAs path %s", searchName);
6040 QAllEAsRetry:
6041         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6042                       (void **) &pSMBr);
6043         if (rc)
6044                 return rc;
6045
6046         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6047                 list_len =
6048                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6049                                        PATH_MAX, nls_codepage, remap);
6050                 list_len++;     /* trailing null */
6051                 list_len *= 2;
6052         } else {        /* BB improve the check for buffer overruns BB */
6053                 list_len = strnlen(searchName, PATH_MAX);
6054                 list_len++;     /* trailing null */
6055                 strncpy(pSMB->FileName, searchName, list_len);
6056         }
6057
6058         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6059         pSMB->TotalDataCount = 0;
6060         pSMB->MaxParameterCount = cpu_to_le16(2);
6061         /* BB find exact max SMB PDU from sess structure BB */
6062         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6063         pSMB->MaxSetupCount = 0;
6064         pSMB->Reserved = 0;
6065         pSMB->Flags = 0;
6066         pSMB->Timeout = 0;
6067         pSMB->Reserved2 = 0;
6068         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6069         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6070         pSMB->DataCount = 0;
6071         pSMB->DataOffset = 0;
6072         pSMB->SetupCount = 1;
6073         pSMB->Reserved3 = 0;
6074         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6075         byte_count = params + 1 /* pad */ ;
6076         pSMB->TotalParameterCount = cpu_to_le16(params);
6077         pSMB->ParameterCount = pSMB->TotalParameterCount;
6078         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6079         pSMB->Reserved4 = 0;
6080         inc_rfc1001_len(pSMB, byte_count);
6081         pSMB->ByteCount = cpu_to_le16(byte_count);
6082
6083         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6084                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6085         if (rc) {
6086                 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6087                 goto QAllEAsOut;
6088         }
6089
6090
6091         /* BB also check enough total bytes returned */
6092         /* BB we need to improve the validity checking
6093         of these trans2 responses */
6094
6095         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6096         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6097                 rc = -EIO;      /* bad smb */
6098                 goto QAllEAsOut;
6099         }
6100
6101         /* check that length of list is not more than bcc */
6102         /* check that each entry does not go beyond length
6103            of list */
6104         /* check that each element of each entry does not
6105            go beyond end of list */
6106         /* validate_trans2_offsets() */
6107         /* BB check if start of smb + data_offset > &bcc+ bcc */
6108
6109         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6110         ea_response_data = (struct fealist *)
6111                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6112
6113         list_len = le32_to_cpu(ea_response_data->list_len);
6114         cFYI(1, "ea length %d", list_len);
6115         if (list_len <= 8) {
6116                 cFYI(1, "empty EA list returned from server");
6117                 goto QAllEAsOut;
6118         }
6119
6120         /* make sure list_len doesn't go past end of SMB */
6121         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6122         if ((char *)ea_response_data + list_len > end_of_smb) {
6123                 cFYI(1, "EA list appears to go beyond SMB");
6124                 rc = -EIO;
6125                 goto QAllEAsOut;
6126         }
6127
6128         /* account for ea list len */
6129         list_len -= 4;
6130         temp_fea = ea_response_data->list;
6131         temp_ptr = (char *)temp_fea;
6132         while (list_len > 0) {
6133                 unsigned int name_len;
6134                 __u16 value_len;
6135
6136                 list_len -= 4;
6137                 temp_ptr += 4;
6138                 /* make sure we can read name_len and value_len */
6139                 if (list_len < 0) {
6140                         cFYI(1, "EA entry goes beyond length of list");
6141                         rc = -EIO;
6142                         goto QAllEAsOut;
6143                 }
6144
6145                 name_len = temp_fea->name_len;
6146                 value_len = le16_to_cpu(temp_fea->value_len);
6147                 list_len -= name_len + 1 + value_len;
6148                 if (list_len < 0) {
6149                         cFYI(1, "EA entry goes beyond length of list");
6150                         rc = -EIO;
6151                         goto QAllEAsOut;
6152                 }
6153
6154                 if (ea_name) {
6155                         if (ea_name_len == name_len &&
6156                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6157                                 temp_ptr += name_len + 1;
6158                                 rc = value_len;
6159                                 if (buf_size == 0)
6160                                         goto QAllEAsOut;
6161                                 if ((size_t)value_len > buf_size) {
6162                                         rc = -ERANGE;
6163                                         goto QAllEAsOut;
6164                                 }
6165                                 memcpy(EAData, temp_ptr, value_len);
6166                                 goto QAllEAsOut;
6167                         }
6168                 } else {
6169                         /* account for prefix user. and trailing null */
6170                         rc += (5 + 1 + name_len);
6171                         if (rc < (int) buf_size) {
6172                                 memcpy(EAData, "user.", 5);
6173                                 EAData += 5;
6174                                 memcpy(EAData, temp_ptr, name_len);
6175                                 EAData += name_len;
6176                                 /* null terminate name */
6177                                 *EAData = 0;
6178                                 ++EAData;
6179                         } else if (buf_size == 0) {
6180                                 /* skip copy - calc size only */
6181                         } else {
6182                                 /* stop before overrun buffer */
6183                                 rc = -ERANGE;
6184                                 break;
6185                         }
6186                 }
6187                 temp_ptr += name_len + 1 + value_len;
6188                 temp_fea = (struct fea *)temp_ptr;
6189         }
6190
6191         /* didn't find the named attribute */
6192         if (ea_name)
6193                 rc = -ENODATA;
6194
6195 QAllEAsOut:
6196         cifs_buf_release(pSMB);
6197         if (rc == -EAGAIN)
6198                 goto QAllEAsRetry;
6199
6200         return (ssize_t)rc;
6201 }
6202
6203 int
6204 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6205              const char *fileName, const char *ea_name, const void *ea_value,
6206              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6207              int remap)
6208 {
6209         struct smb_com_transaction2_spi_req *pSMB = NULL;
6210         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6211         struct fealist *parm_data;
6212         int name_len;
6213         int rc = 0;
6214         int bytes_returned = 0;
6215         __u16 params, param_offset, byte_count, offset, count;
6216
6217         cFYI(1, "In SetEA");
6218 SetEARetry:
6219         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6220                       (void **) &pSMBr);
6221         if (rc)
6222                 return rc;
6223
6224         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6225                 name_len =
6226                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6227                                        PATH_MAX, nls_codepage, remap);
6228                 name_len++;     /* trailing null */
6229                 name_len *= 2;
6230         } else {        /* BB improve the check for buffer overruns BB */
6231                 name_len = strnlen(fileName, PATH_MAX);
6232                 name_len++;     /* trailing null */
6233                 strncpy(pSMB->FileName, fileName, name_len);
6234         }
6235
6236         params = 6 + name_len;
6237
6238         /* done calculating parms using name_len of file name,
6239         now use name_len to calculate length of ea name
6240         we are going to create in the inode xattrs */
6241         if (ea_name == NULL)
6242                 name_len = 0;
6243         else
6244                 name_len = strnlen(ea_name, 255);
6245
6246         count = sizeof(*parm_data) + ea_value_len + name_len;
6247         pSMB->MaxParameterCount = cpu_to_le16(2);
6248         /* BB find max SMB PDU from sess */
6249         pSMB->MaxDataCount = cpu_to_le16(1000);
6250         pSMB->MaxSetupCount = 0;
6251         pSMB->Reserved = 0;
6252         pSMB->Flags = 0;
6253         pSMB->Timeout = 0;
6254         pSMB->Reserved2 = 0;
6255         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6256                                 InformationLevel) - 4;
6257         offset = param_offset + params;
6258         pSMB->InformationLevel =
6259                 cpu_to_le16(SMB_SET_FILE_EA);
6260
6261         parm_data =
6262                 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6263                                        offset);
6264         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6265         pSMB->DataOffset = cpu_to_le16(offset);
6266         pSMB->SetupCount = 1;
6267         pSMB->Reserved3 = 0;
6268         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6269         byte_count = 3 /* pad */  + params + count;
6270         pSMB->DataCount = cpu_to_le16(count);
6271         parm_data->list_len = cpu_to_le32(count);
6272         parm_data->list[0].EA_flags = 0;
6273         /* we checked above that name len is less than 255 */
6274         parm_data->list[0].name_len = (__u8)name_len;
6275         /* EA names are always ASCII */
6276         if (ea_name)
6277                 strncpy(parm_data->list[0].name, ea_name, name_len);
6278         parm_data->list[0].name[name_len] = 0;
6279         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6280         /* caller ensures that ea_value_len is less than 64K but
6281         we need to ensure that it fits within the smb */
6282
6283         /*BB add length check to see if it would fit in
6284              negotiated SMB buffer size BB */
6285         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6286         if (ea_value_len)
6287                 memcpy(parm_data->list[0].name+name_len+1,
6288                        ea_value, ea_value_len);
6289
6290         pSMB->TotalDataCount = pSMB->DataCount;
6291         pSMB->ParameterCount = cpu_to_le16(params);
6292         pSMB->TotalParameterCount = pSMB->ParameterCount;
6293         pSMB->Reserved4 = 0;
6294         inc_rfc1001_len(pSMB, byte_count);
6295         pSMB->ByteCount = cpu_to_le16(byte_count);
6296         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6297                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6298         if (rc)
6299                 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6300
6301         cifs_buf_release(pSMB);
6302
6303         if (rc == -EAGAIN)
6304                 goto SetEARetry;
6305
6306         return rc;
6307 }
6308 #endif
6309
6310 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6311 /*
6312  *      Years ago the kernel added a "dnotify" function for Samba server,
6313  *      to allow network clients (such as Windows) to display updated
6314  *      lists of files in directory listings automatically when
6315  *      files are added by one user when another user has the
6316  *      same directory open on their desktop.  The Linux cifs kernel
6317  *      client hooked into the kernel side of this interface for
6318  *      the same reason, but ironically when the VFS moved from
6319  *      "dnotify" to "inotify" it became harder to plug in Linux
6320  *      network file system clients (the most obvious use case
6321  *      for notify interfaces is when multiple users can update
6322  *      the contents of the same directory - exactly what network
6323  *      file systems can do) although the server (Samba) could
6324  *      still use it.  For the short term we leave the worker
6325  *      function ifdeffed out (below) until inotify is fixed
6326  *      in the VFS to make it easier to plug in network file
6327  *      system clients.  If inotify turns out to be permanently
6328  *      incompatible for network fs clients, we could instead simply
6329  *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
6330  */
6331 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6332                   const int notify_subdirs, const __u16 netfid,
6333                   __u32 filter, struct file *pfile, int multishot,
6334                   const struct nls_table *nls_codepage)
6335 {
6336         int rc = 0;
6337         struct smb_com_transaction_change_notify_req *pSMB = NULL;
6338         struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6339         struct dir_notify_req *dnotify_req;
6340         int bytes_returned;
6341
6342         cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6343         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6344                       (void **) &pSMBr);
6345         if (rc)
6346                 return rc;
6347
6348         pSMB->TotalParameterCount = 0 ;
6349         pSMB->TotalDataCount = 0;
6350         pSMB->MaxParameterCount = cpu_to_le32(2);
6351         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6352         pSMB->MaxSetupCount = 4;
6353         pSMB->Reserved = 0;
6354         pSMB->ParameterOffset = 0;
6355         pSMB->DataCount = 0;
6356         pSMB->DataOffset = 0;
6357         pSMB->SetupCount = 4; /* single byte does not need le conversion */
6358         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6359         pSMB->ParameterCount = pSMB->TotalParameterCount;
6360         if (notify_subdirs)
6361                 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6362         pSMB->Reserved2 = 0;
6363         pSMB->CompletionFilter = cpu_to_le32(filter);
6364         pSMB->Fid = netfid; /* file handle always le */
6365         pSMB->ByteCount = 0;
6366
6367         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6368                          (struct smb_hdr *)pSMBr, &bytes_returned,
6369                          CIFS_ASYNC_OP);
6370         if (rc) {
6371                 cFYI(1, "Error in Notify = %d", rc);
6372         } else {
6373                 /* Add file to outstanding requests */
6374                 /* BB change to kmem cache alloc */
6375                 dnotify_req = kmalloc(
6376                                                 sizeof(struct dir_notify_req),
6377                                                  GFP_KERNEL);
6378                 if (dnotify_req) {
6379                         dnotify_req->Pid = pSMB->hdr.Pid;
6380                         dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6381                         dnotify_req->Mid = pSMB->hdr.Mid;
6382                         dnotify_req->Tid = pSMB->hdr.Tid;
6383                         dnotify_req->Uid = pSMB->hdr.Uid;
6384                         dnotify_req->netfid = netfid;
6385                         dnotify_req->pfile = pfile;
6386                         dnotify_req->filter = filter;
6387                         dnotify_req->multishot = multishot;
6388                         spin_lock(&GlobalMid_Lock);
6389                         list_add_tail(&dnotify_req->lhead,
6390                                         &GlobalDnotifyReqList);
6391                         spin_unlock(&GlobalMid_Lock);
6392                 } else
6393                         rc = -ENOMEM;
6394         }
6395         cifs_buf_release(pSMB);
6396         return rc;
6397 }
6398 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */