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