Merge branch 'stable-3.2' into pandora-3.2
[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, __u16 search_flags,
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(search_flags);
4403         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4404
4405         /* BB what should we set StorageType to? Does it matter? BB */
4406         pSMB->SearchStorageType = 0;
4407         inc_rfc1001_len(pSMB, byte_count);
4408         pSMB->ByteCount = cpu_to_le16(byte_count);
4409
4410         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4411                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4412         cifs_stats_inc(&tcon->num_ffirst);
4413
4414         if (rc) {/* BB add logic to retry regular search if Unix search
4415                         rejected unexpectedly by server */
4416                 /* BB Add code to handle unsupported level rc */
4417                 cFYI(1, "Error in FindFirst = %d", rc);
4418
4419                 cifs_buf_release(pSMB);
4420
4421                 /* BB eventually could optimize out free and realloc of buf */
4422                 /*    for this case */
4423                 if (rc == -EAGAIN)
4424                         goto findFirstRetry;
4425         } else { /* decode response */
4426                 /* BB remember to free buffer if error BB */
4427                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4428                 if (rc == 0) {
4429                         unsigned int lnoff;
4430
4431                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4432                                 psrch_inf->unicode = true;
4433                         else
4434                                 psrch_inf->unicode = false;
4435
4436                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4437                         psrch_inf->smallBuf = 0;
4438                         psrch_inf->srch_entries_start =
4439                                 (char *) &pSMBr->hdr.Protocol +
4440                                         le16_to_cpu(pSMBr->t2.DataOffset);
4441                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4442                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4443
4444                         if (parms->EndofSearch)
4445                                 psrch_inf->endOfSearch = true;
4446                         else
4447                                 psrch_inf->endOfSearch = false;
4448
4449                         psrch_inf->entries_in_buffer =
4450                                         le16_to_cpu(parms->SearchCount);
4451                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4452                                 psrch_inf->entries_in_buffer;
4453                         lnoff = le16_to_cpu(parms->LastNameOffset);
4454                         if (CIFSMaxBufSize < lnoff) {
4455                                 cERROR(1, "ignoring corrupt resume name");
4456                                 psrch_inf->last_entry = NULL;
4457                                 return rc;
4458                         }
4459
4460                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4461                                                         lnoff;
4462
4463                         *pnetfid = parms->SearchHandle;
4464                 } else {
4465                         cifs_buf_release(pSMB);
4466                 }
4467         }
4468
4469         return rc;
4470 }
4471
4472 int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle,
4473                  __u16 search_flags, struct cifs_search_info *psrch_inf)
4474 {
4475         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4476         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4477         T2_FNEXT_RSP_PARMS *parms;
4478         char *response_data;
4479         int rc = 0;
4480         int bytes_returned;
4481         unsigned int name_len;
4482         __u16 params, byte_count;
4483
4484         cFYI(1, "In FindNext");
4485
4486         if (psrch_inf->endOfSearch)
4487                 return -ENOENT;
4488
4489         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4490                 (void **) &pSMBr);
4491         if (rc)
4492                 return rc;
4493
4494         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4495         byte_count = 0;
4496         pSMB->TotalDataCount = 0;       /* no EAs */
4497         pSMB->MaxParameterCount = cpu_to_le16(8);
4498         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4499         pSMB->MaxSetupCount = 0;
4500         pSMB->Reserved = 0;
4501         pSMB->Flags = 0;
4502         pSMB->Timeout = 0;
4503         pSMB->Reserved2 = 0;
4504         pSMB->ParameterOffset =  cpu_to_le16(
4505               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4506         pSMB->DataCount = 0;
4507         pSMB->DataOffset = 0;
4508         pSMB->SetupCount = 1;
4509         pSMB->Reserved3 = 0;
4510         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4511         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4512         pSMB->SearchCount =
4513                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4514         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4515         pSMB->ResumeKey = psrch_inf->resume_key;
4516         pSMB->SearchFlags = cpu_to_le16(search_flags);
4517
4518         name_len = psrch_inf->resume_name_len;
4519         params += name_len;
4520         if (name_len < PATH_MAX) {
4521                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4522                 byte_count += name_len;
4523                 /* 14 byte parm len above enough for 2 byte null terminator */
4524                 pSMB->ResumeFileName[name_len] = 0;
4525                 pSMB->ResumeFileName[name_len+1] = 0;
4526         } else {
4527                 rc = -EINVAL;
4528                 goto FNext2_err_exit;
4529         }
4530         byte_count = params + 1 /* pad */ ;
4531         pSMB->TotalParameterCount = cpu_to_le16(params);
4532         pSMB->ParameterCount = pSMB->TotalParameterCount;
4533         inc_rfc1001_len(pSMB, byte_count);
4534         pSMB->ByteCount = cpu_to_le16(byte_count);
4535
4536         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4537                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4538         cifs_stats_inc(&tcon->num_fnext);
4539         if (rc) {
4540                 if (rc == -EBADF) {
4541                         psrch_inf->endOfSearch = true;
4542                         cifs_buf_release(pSMB);
4543                         rc = 0; /* search probably was closed at end of search*/
4544                 } else
4545                         cFYI(1, "FindNext returned = %d", rc);
4546         } else {                /* decode response */
4547                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4548
4549                 if (rc == 0) {
4550                         unsigned int lnoff;
4551
4552                         /* BB fixme add lock for file (srch_info) struct here */
4553                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4554                                 psrch_inf->unicode = true;
4555                         else
4556                                 psrch_inf->unicode = false;
4557                         response_data = (char *) &pSMBr->hdr.Protocol +
4558                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4559                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4560                         response_data = (char *)&pSMBr->hdr.Protocol +
4561                                 le16_to_cpu(pSMBr->t2.DataOffset);
4562                         if (psrch_inf->smallBuf)
4563                                 cifs_small_buf_release(
4564                                         psrch_inf->ntwrk_buf_start);
4565                         else
4566                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4567                         psrch_inf->srch_entries_start = response_data;
4568                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4569                         psrch_inf->smallBuf = 0;
4570                         if (parms->EndofSearch)
4571                                 psrch_inf->endOfSearch = true;
4572                         else
4573                                 psrch_inf->endOfSearch = false;
4574                         psrch_inf->entries_in_buffer =
4575                                                 le16_to_cpu(parms->SearchCount);
4576                         psrch_inf->index_of_last_entry +=
4577                                 psrch_inf->entries_in_buffer;
4578                         lnoff = le16_to_cpu(parms->LastNameOffset);
4579                         if (CIFSMaxBufSize < lnoff) {
4580                                 cERROR(1, "ignoring corrupt resume name");
4581                                 psrch_inf->last_entry = NULL;
4582                                 return rc;
4583                         } else
4584                                 psrch_inf->last_entry =
4585                                         psrch_inf->srch_entries_start + lnoff;
4586
4587 /*  cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4588             psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4589
4590                         /* BB fixme add unlock here */
4591                 }
4592
4593         }
4594
4595         /* BB On error, should we leave previous search buf (and count and
4596         last entry fields) intact or free the previous one? */
4597
4598         /* Note: On -EAGAIN error only caller can retry on handle based calls
4599         since file handle passed in no longer valid */
4600 FNext2_err_exit:
4601         if (rc != 0)
4602                 cifs_buf_release(pSMB);
4603         return rc;
4604 }
4605
4606 int
4607 CIFSFindClose(const int xid, struct cifs_tcon *tcon,
4608               const __u16 searchHandle)
4609 {
4610         int rc = 0;
4611         FINDCLOSE_REQ *pSMB = NULL;
4612
4613         cFYI(1, "In CIFSSMBFindClose");
4614         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4615
4616         /* no sense returning error if session restarted
4617                 as file handle has been closed */
4618         if (rc == -EAGAIN)
4619                 return 0;
4620         if (rc)
4621                 return rc;
4622
4623         pSMB->FileID = searchHandle;
4624         pSMB->ByteCount = 0;
4625         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4626         if (rc)
4627                 cERROR(1, "Send error in FindClose = %d", rc);
4628
4629         cifs_stats_inc(&tcon->num_fclose);
4630
4631         /* Since session is dead, search handle closed on server already */
4632         if (rc == -EAGAIN)
4633                 rc = 0;
4634
4635         return rc;
4636 }
4637
4638 int
4639 CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
4640                       const unsigned char *searchName,
4641                       __u64 *inode_number,
4642                       const struct nls_table *nls_codepage, int remap)
4643 {
4644         int rc = 0;
4645         TRANSACTION2_QPI_REQ *pSMB = NULL;
4646         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4647         int name_len, bytes_returned;
4648         __u16 params, byte_count;
4649
4650         cFYI(1, "In GetSrvInodeNum for %s", searchName);
4651         if (tcon == NULL)
4652                 return -ENODEV;
4653
4654 GetInodeNumberRetry:
4655         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4656                       (void **) &pSMBr);
4657         if (rc)
4658                 return rc;
4659
4660         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4661                 name_len =
4662                         cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4663                                          PATH_MAX, nls_codepage, remap);
4664                 name_len++;     /* trailing null */
4665                 name_len *= 2;
4666         } else {        /* BB improve the check for buffer overruns BB */
4667                 name_len = strnlen(searchName, PATH_MAX);
4668                 name_len++;     /* trailing null */
4669                 strncpy(pSMB->FileName, searchName, name_len);
4670         }
4671
4672         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4673         pSMB->TotalDataCount = 0;
4674         pSMB->MaxParameterCount = cpu_to_le16(2);
4675         /* BB find exact max data count below from sess structure BB */
4676         pSMB->MaxDataCount = cpu_to_le16(4000);
4677         pSMB->MaxSetupCount = 0;
4678         pSMB->Reserved = 0;
4679         pSMB->Flags = 0;
4680         pSMB->Timeout = 0;
4681         pSMB->Reserved2 = 0;
4682         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4683                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4684         pSMB->DataCount = 0;
4685         pSMB->DataOffset = 0;
4686         pSMB->SetupCount = 1;
4687         pSMB->Reserved3 = 0;
4688         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4689         byte_count = params + 1 /* pad */ ;
4690         pSMB->TotalParameterCount = cpu_to_le16(params);
4691         pSMB->ParameterCount = pSMB->TotalParameterCount;
4692         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4693         pSMB->Reserved4 = 0;
4694         inc_rfc1001_len(pSMB, byte_count);
4695         pSMB->ByteCount = cpu_to_le16(byte_count);
4696
4697         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4698                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4699         if (rc) {
4700                 cFYI(1, "error %d in QueryInternalInfo", rc);
4701         } else {
4702                 /* decode response */
4703                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4704                 /* BB also check enough total bytes returned */
4705                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4706                         /* If rc should we check for EOPNOSUPP and
4707                         disable the srvino flag? or in caller? */
4708                         rc = -EIO;      /* bad smb */
4709                 else {
4710                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4711                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4712                         struct file_internal_info *pfinfo;
4713                         /* BB Do we need a cast or hash here ? */
4714                         if (count < 8) {
4715                                 cFYI(1, "Illegal size ret in QryIntrnlInf");
4716                                 rc = -EIO;
4717                                 goto GetInodeNumOut;
4718                         }
4719                         pfinfo = (struct file_internal_info *)
4720                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4721                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4722                 }
4723         }
4724 GetInodeNumOut:
4725         cifs_buf_release(pSMB);
4726         if (rc == -EAGAIN)
4727                 goto GetInodeNumberRetry;
4728         return rc;
4729 }
4730
4731 /* parses DFS refferal V3 structure
4732  * caller is responsible for freeing target_nodes
4733  * returns:
4734  *      on success - 0
4735  *      on failure - errno
4736  */
4737 static int
4738 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4739                 unsigned int *num_of_nodes,
4740                 struct dfs_info3_param **target_nodes,
4741                 const struct nls_table *nls_codepage, int remap,
4742                 const char *searchName)
4743 {
4744         int i, rc = 0;
4745         char *data_end;
4746         bool is_unicode;
4747         struct dfs_referral_level_3 *ref;
4748
4749         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4750                 is_unicode = true;
4751         else
4752                 is_unicode = false;
4753         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4754
4755         if (*num_of_nodes < 1) {
4756                 cERROR(1, "num_referrals: must be at least > 0,"
4757                         "but we get num_referrals = %d\n", *num_of_nodes);
4758                 rc = -EINVAL;
4759                 goto parse_DFS_referrals_exit;
4760         }
4761
4762         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4763         if (ref->VersionNumber != cpu_to_le16(3)) {
4764                 cERROR(1, "Referrals of V%d version are not supported,"
4765                         "should be V3", le16_to_cpu(ref->VersionNumber));
4766                 rc = -EINVAL;
4767                 goto parse_DFS_referrals_exit;
4768         }
4769
4770         /* get the upper boundary of the resp buffer */
4771         data_end = (char *)(&(pSMBr->PathConsumed)) +
4772                                 le16_to_cpu(pSMBr->t2.DataCount);
4773
4774         cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
4775                         *num_of_nodes,
4776                         le32_to_cpu(pSMBr->DFSFlags));
4777
4778         *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4779                         *num_of_nodes, GFP_KERNEL);
4780         if (*target_nodes == NULL) {
4781                 cERROR(1, "Failed to allocate buffer for target_nodes\n");
4782                 rc = -ENOMEM;
4783                 goto parse_DFS_referrals_exit;
4784         }
4785
4786         /* collect necessary data from referrals */
4787         for (i = 0; i < *num_of_nodes; i++) {
4788                 char *temp;
4789                 int max_len;
4790                 struct dfs_info3_param *node = (*target_nodes)+i;
4791
4792                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4793                 if (is_unicode) {
4794                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4795                                                 GFP_KERNEL);
4796                         if (tmp == NULL) {
4797                                 rc = -ENOMEM;
4798                                 goto parse_DFS_referrals_exit;
4799                         }
4800                         cifsConvertToUCS((__le16 *) tmp, searchName,
4801                                         PATH_MAX, nls_codepage, remap);
4802                         node->path_consumed = cifs_ucs2_bytes(tmp,
4803                                         le16_to_cpu(pSMBr->PathConsumed),
4804                                         nls_codepage);
4805                         kfree(tmp);
4806                 } else
4807                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4808
4809                 node->server_type = le16_to_cpu(ref->ServerType);
4810                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4811
4812                 /* copy DfsPath */
4813                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4814                 max_len = data_end - temp;
4815                 node->path_name = cifs_strndup_from_ucs(temp, max_len,
4816                                                       is_unicode, nls_codepage);
4817                 if (!node->path_name) {
4818                         rc = -ENOMEM;
4819                         goto parse_DFS_referrals_exit;
4820                 }
4821
4822                 /* copy link target UNC */
4823                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4824                 max_len = data_end - temp;
4825                 node->node_name = cifs_strndup_from_ucs(temp, max_len,
4826                                                       is_unicode, nls_codepage);
4827                 if (!node->node_name) {
4828                         rc = -ENOMEM;
4829                         goto parse_DFS_referrals_exit;
4830                 }
4831
4832                 ref++;
4833         }
4834
4835 parse_DFS_referrals_exit:
4836         if (rc) {
4837                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4838                 *target_nodes = NULL;
4839                 *num_of_nodes = 0;
4840         }
4841         return rc;
4842 }
4843
4844 int
4845 CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4846                 const unsigned char *searchName,
4847                 struct dfs_info3_param **target_nodes,
4848                 unsigned int *num_of_nodes,
4849                 const struct nls_table *nls_codepage, int remap)
4850 {
4851 /* TRANS2_GET_DFS_REFERRAL */
4852         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4853         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4854         int rc = 0;
4855         int bytes_returned;
4856         int name_len;
4857         __u16 params, byte_count;
4858         *num_of_nodes = 0;
4859         *target_nodes = NULL;
4860
4861         cFYI(1, "In GetDFSRefer the path %s", searchName);
4862         if (ses == NULL)
4863                 return -ENODEV;
4864 getDFSRetry:
4865         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4866                       (void **) &pSMBr);
4867         if (rc)
4868                 return rc;
4869
4870         /* server pointer checked in called function,
4871         but should never be null here anyway */
4872         pSMB->hdr.Mid = GetNextMid(ses->server);
4873         pSMB->hdr.Tid = ses->ipc_tid;
4874         pSMB->hdr.Uid = ses->Suid;
4875         if (ses->capabilities & CAP_STATUS32)
4876                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4877         if (ses->capabilities & CAP_DFS)
4878                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4879
4880         if (ses->capabilities & CAP_UNICODE) {
4881                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4882                 name_len =
4883                     cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
4884                                      searchName, PATH_MAX, nls_codepage, remap);
4885                 name_len++;     /* trailing null */
4886                 name_len *= 2;
4887         } else {        /* BB improve the check for buffer overruns BB */
4888                 name_len = strnlen(searchName, PATH_MAX);
4889                 name_len++;     /* trailing null */
4890                 strncpy(pSMB->RequestFileName, searchName, name_len);
4891         }
4892
4893         if (ses->server) {
4894                 if (ses->server->sec_mode &
4895                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4896                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4897         }
4898
4899         pSMB->hdr.Uid = ses->Suid;
4900
4901         params = 2 /* level */  + name_len /*includes null */ ;
4902         pSMB->TotalDataCount = 0;
4903         pSMB->DataCount = 0;
4904         pSMB->DataOffset = 0;
4905         pSMB->MaxParameterCount = 0;
4906         /* BB find exact max SMB PDU from sess structure BB */
4907         pSMB->MaxDataCount = cpu_to_le16(4000);
4908         pSMB->MaxSetupCount = 0;
4909         pSMB->Reserved = 0;
4910         pSMB->Flags = 0;
4911         pSMB->Timeout = 0;
4912         pSMB->Reserved2 = 0;
4913         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4914           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4915         pSMB->SetupCount = 1;
4916         pSMB->Reserved3 = 0;
4917         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4918         byte_count = params + 3 /* pad */ ;
4919         pSMB->ParameterCount = cpu_to_le16(params);
4920         pSMB->TotalParameterCount = pSMB->ParameterCount;
4921         pSMB->MaxReferralLevel = cpu_to_le16(3);
4922         inc_rfc1001_len(pSMB, byte_count);
4923         pSMB->ByteCount = cpu_to_le16(byte_count);
4924
4925         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4926                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4927         if (rc) {
4928                 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4929                 goto GetDFSRefExit;
4930         }
4931         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4932
4933         /* BB Also check if enough total bytes returned? */
4934         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4935                 rc = -EIO;      /* bad smb */
4936                 goto GetDFSRefExit;
4937         }
4938
4939         cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
4940                                 get_bcc(&pSMBr->hdr),
4941                                 le16_to_cpu(pSMBr->t2.DataOffset));
4942
4943         /* parse returned result into more usable form */
4944         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4945                                  target_nodes, nls_codepage, remap,
4946                                  searchName);
4947
4948 GetDFSRefExit:
4949         cifs_buf_release(pSMB);
4950
4951         if (rc == -EAGAIN)
4952                 goto getDFSRetry;
4953
4954         return rc;
4955 }
4956
4957 /* Query File System Info such as free space to old servers such as Win 9x */
4958 int
4959 SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4960 {
4961 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4962         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4963         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4964         FILE_SYSTEM_ALLOC_INFO *response_data;
4965         int rc = 0;
4966         int bytes_returned = 0;
4967         __u16 params, byte_count;
4968
4969         cFYI(1, "OldQFSInfo");
4970 oldQFSInfoRetry:
4971         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4972                 (void **) &pSMBr);
4973         if (rc)
4974                 return rc;
4975
4976         params = 2;     /* level */
4977         pSMB->TotalDataCount = 0;
4978         pSMB->MaxParameterCount = cpu_to_le16(2);
4979         pSMB->MaxDataCount = cpu_to_le16(1000);
4980         pSMB->MaxSetupCount = 0;
4981         pSMB->Reserved = 0;
4982         pSMB->Flags = 0;
4983         pSMB->Timeout = 0;
4984         pSMB->Reserved2 = 0;
4985         byte_count = params + 1 /* pad */ ;
4986         pSMB->TotalParameterCount = cpu_to_le16(params);
4987         pSMB->ParameterCount = pSMB->TotalParameterCount;
4988         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4989         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4990         pSMB->DataCount = 0;
4991         pSMB->DataOffset = 0;
4992         pSMB->SetupCount = 1;
4993         pSMB->Reserved3 = 0;
4994         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4995         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4996         inc_rfc1001_len(pSMB, byte_count);
4997         pSMB->ByteCount = cpu_to_le16(byte_count);
4998
4999         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5000                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5001         if (rc) {
5002                 cFYI(1, "Send error in QFSInfo = %d", rc);
5003         } else {                /* decode response */
5004                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5005
5006                 if (rc || get_bcc(&pSMBr->hdr) < 18)
5007                         rc = -EIO;      /* bad smb */
5008                 else {
5009                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5010                         cFYI(1, "qfsinf resp BCC: %d  Offset %d",
5011                                  get_bcc(&pSMBr->hdr), data_offset);
5012
5013                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
5014                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5015                         FSData->f_bsize =
5016                                 le16_to_cpu(response_data->BytesPerSector) *
5017                                 le32_to_cpu(response_data->
5018                                         SectorsPerAllocationUnit);
5019                         FSData->f_blocks =
5020                                le32_to_cpu(response_data->TotalAllocationUnits);
5021                         FSData->f_bfree = FSData->f_bavail =
5022                                 le32_to_cpu(response_data->FreeAllocationUnits);
5023                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5024                              (unsigned long long)FSData->f_blocks,
5025                              (unsigned long long)FSData->f_bfree,
5026                              FSData->f_bsize);
5027                 }
5028         }
5029         cifs_buf_release(pSMB);
5030
5031         if (rc == -EAGAIN)
5032                 goto oldQFSInfoRetry;
5033
5034         return rc;
5035 }
5036
5037 int
5038 CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
5039 {
5040 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5041         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5042         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5043         FILE_SYSTEM_INFO *response_data;
5044         int rc = 0;
5045         int bytes_returned = 0;
5046         __u16 params, byte_count;
5047
5048         cFYI(1, "In QFSInfo");
5049 QFSInfoRetry:
5050         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5051                       (void **) &pSMBr);
5052         if (rc)
5053                 return rc;
5054
5055         params = 2;     /* level */
5056         pSMB->TotalDataCount = 0;
5057         pSMB->MaxParameterCount = cpu_to_le16(2);
5058         pSMB->MaxDataCount = cpu_to_le16(1000);
5059         pSMB->MaxSetupCount = 0;
5060         pSMB->Reserved = 0;
5061         pSMB->Flags = 0;
5062         pSMB->Timeout = 0;
5063         pSMB->Reserved2 = 0;
5064         byte_count = params + 1 /* pad */ ;
5065         pSMB->TotalParameterCount = cpu_to_le16(params);
5066         pSMB->ParameterCount = pSMB->TotalParameterCount;
5067         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5068                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5069         pSMB->DataCount = 0;
5070         pSMB->DataOffset = 0;
5071         pSMB->SetupCount = 1;
5072         pSMB->Reserved3 = 0;
5073         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5074         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5075         inc_rfc1001_len(pSMB, byte_count);
5076         pSMB->ByteCount = cpu_to_le16(byte_count);
5077
5078         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5079                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5080         if (rc) {
5081                 cFYI(1, "Send error in QFSInfo = %d", rc);
5082         } else {                /* decode response */
5083                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5084
5085                 if (rc || get_bcc(&pSMBr->hdr) < 24)
5086                         rc = -EIO;      /* bad smb */
5087                 else {
5088                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5089
5090                         response_data =
5091                             (FILE_SYSTEM_INFO
5092                              *) (((char *) &pSMBr->hdr.Protocol) +
5093                                  data_offset);
5094                         FSData->f_bsize =
5095                             le32_to_cpu(response_data->BytesPerSector) *
5096                             le32_to_cpu(response_data->
5097                                         SectorsPerAllocationUnit);
5098                         FSData->f_blocks =
5099                             le64_to_cpu(response_data->TotalAllocationUnits);
5100                         FSData->f_bfree = FSData->f_bavail =
5101                             le64_to_cpu(response_data->FreeAllocationUnits);
5102                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5103                              (unsigned long long)FSData->f_blocks,
5104                              (unsigned long long)FSData->f_bfree,
5105                              FSData->f_bsize);
5106                 }
5107         }
5108         cifs_buf_release(pSMB);
5109
5110         if (rc == -EAGAIN)
5111                 goto QFSInfoRetry;
5112
5113         return rc;
5114 }
5115
5116 int
5117 CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
5118 {
5119 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5120         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5121         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5122         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5123         int rc = 0;
5124         int bytes_returned = 0;
5125         __u16 params, byte_count;
5126
5127         cFYI(1, "In QFSAttributeInfo");
5128 QFSAttributeRetry:
5129         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5130                       (void **) &pSMBr);
5131         if (rc)
5132                 return rc;
5133
5134         params = 2;     /* level */
5135         pSMB->TotalDataCount = 0;
5136         pSMB->MaxParameterCount = cpu_to_le16(2);
5137         /* BB find exact max SMB PDU from sess structure BB */
5138         pSMB->MaxDataCount = cpu_to_le16(1000);
5139         pSMB->MaxSetupCount = 0;
5140         pSMB->Reserved = 0;
5141         pSMB->Flags = 0;
5142         pSMB->Timeout = 0;
5143         pSMB->Reserved2 = 0;
5144         byte_count = params + 1 /* pad */ ;
5145         pSMB->TotalParameterCount = cpu_to_le16(params);
5146         pSMB->ParameterCount = pSMB->TotalParameterCount;
5147         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5148                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5149         pSMB->DataCount = 0;
5150         pSMB->DataOffset = 0;
5151         pSMB->SetupCount = 1;
5152         pSMB->Reserved3 = 0;
5153         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5154         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5155         inc_rfc1001_len(pSMB, byte_count);
5156         pSMB->ByteCount = cpu_to_le16(byte_count);
5157
5158         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5159                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5160         if (rc) {
5161                 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5162         } else {                /* decode response */
5163                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5164
5165                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5166                         /* BB also check if enough bytes returned */
5167                         rc = -EIO;      /* bad smb */
5168                 } else {
5169                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5170                         response_data =
5171                             (FILE_SYSTEM_ATTRIBUTE_INFO
5172                              *) (((char *) &pSMBr->hdr.Protocol) +
5173                                  data_offset);
5174                         memcpy(&tcon->fsAttrInfo, response_data,
5175                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5176                 }
5177         }
5178         cifs_buf_release(pSMB);
5179
5180         if (rc == -EAGAIN)
5181                 goto QFSAttributeRetry;
5182
5183         return rc;
5184 }
5185
5186 int
5187 CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
5188 {
5189 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5190         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5191         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5192         FILE_SYSTEM_DEVICE_INFO *response_data;
5193         int rc = 0;
5194         int bytes_returned = 0;
5195         __u16 params, byte_count;
5196
5197         cFYI(1, "In QFSDeviceInfo");
5198 QFSDeviceRetry:
5199         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5200                       (void **) &pSMBr);
5201         if (rc)
5202                 return rc;
5203
5204         params = 2;     /* level */
5205         pSMB->TotalDataCount = 0;
5206         pSMB->MaxParameterCount = cpu_to_le16(2);
5207         /* BB find exact max SMB PDU from sess structure BB */
5208         pSMB->MaxDataCount = cpu_to_le16(1000);
5209         pSMB->MaxSetupCount = 0;
5210         pSMB->Reserved = 0;
5211         pSMB->Flags = 0;
5212         pSMB->Timeout = 0;
5213         pSMB->Reserved2 = 0;
5214         byte_count = params + 1 /* pad */ ;
5215         pSMB->TotalParameterCount = cpu_to_le16(params);
5216         pSMB->ParameterCount = pSMB->TotalParameterCount;
5217         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5218                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5219
5220         pSMB->DataCount = 0;
5221         pSMB->DataOffset = 0;
5222         pSMB->SetupCount = 1;
5223         pSMB->Reserved3 = 0;
5224         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5225         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5226         inc_rfc1001_len(pSMB, byte_count);
5227         pSMB->ByteCount = cpu_to_le16(byte_count);
5228
5229         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5230                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5231         if (rc) {
5232                 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5233         } else {                /* decode response */
5234                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5235
5236                 if (rc || get_bcc(&pSMBr->hdr) <
5237                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5238                         rc = -EIO;      /* bad smb */
5239                 else {
5240                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5241                         response_data =
5242                             (FILE_SYSTEM_DEVICE_INFO *)
5243                                 (((char *) &pSMBr->hdr.Protocol) +
5244                                  data_offset);
5245                         memcpy(&tcon->fsDevInfo, response_data,
5246                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5247                 }
5248         }
5249         cifs_buf_release(pSMB);
5250
5251         if (rc == -EAGAIN)
5252                 goto QFSDeviceRetry;
5253
5254         return rc;
5255 }
5256
5257 int
5258 CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
5259 {
5260 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5261         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5262         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5263         FILE_SYSTEM_UNIX_INFO *response_data;
5264         int rc = 0;
5265         int bytes_returned = 0;
5266         __u16 params, byte_count;
5267
5268         cFYI(1, "In QFSUnixInfo");
5269 QFSUnixRetry:
5270         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5271                                    (void **) &pSMB, (void **) &pSMBr);
5272         if (rc)
5273                 return rc;
5274
5275         params = 2;     /* level */
5276         pSMB->TotalDataCount = 0;
5277         pSMB->DataCount = 0;
5278         pSMB->DataOffset = 0;
5279         pSMB->MaxParameterCount = cpu_to_le16(2);
5280         /* BB find exact max SMB PDU from sess structure BB */
5281         pSMB->MaxDataCount = cpu_to_le16(100);
5282         pSMB->MaxSetupCount = 0;
5283         pSMB->Reserved = 0;
5284         pSMB->Flags = 0;
5285         pSMB->Timeout = 0;
5286         pSMB->Reserved2 = 0;
5287         byte_count = params + 1 /* pad */ ;
5288         pSMB->ParameterCount = cpu_to_le16(params);
5289         pSMB->TotalParameterCount = pSMB->ParameterCount;
5290         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5291                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5292         pSMB->SetupCount = 1;
5293         pSMB->Reserved3 = 0;
5294         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5295         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5296         inc_rfc1001_len(pSMB, byte_count);
5297         pSMB->ByteCount = cpu_to_le16(byte_count);
5298
5299         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5300                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5301         if (rc) {
5302                 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5303         } else {                /* decode response */
5304                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5305
5306                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5307                         rc = -EIO;      /* bad smb */
5308                 } else {
5309                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5310                         response_data =
5311                             (FILE_SYSTEM_UNIX_INFO
5312                              *) (((char *) &pSMBr->hdr.Protocol) +
5313                                  data_offset);
5314                         memcpy(&tcon->fsUnixInfo, response_data,
5315                                sizeof(FILE_SYSTEM_UNIX_INFO));
5316                 }
5317         }
5318         cifs_buf_release(pSMB);
5319
5320         if (rc == -EAGAIN)
5321                 goto QFSUnixRetry;
5322
5323
5324         return rc;
5325 }
5326
5327 int
5328 CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
5329 {
5330 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5331         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5332         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5333         int rc = 0;
5334         int bytes_returned = 0;
5335         __u16 params, param_offset, offset, byte_count;
5336
5337         cFYI(1, "In SETFSUnixInfo");
5338 SETFSUnixRetry:
5339         /* BB switch to small buf init to save memory */
5340         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5341                                         (void **) &pSMB, (void **) &pSMBr);
5342         if (rc)
5343                 return rc;
5344
5345         params = 4;     /* 2 bytes zero followed by info level. */
5346         pSMB->MaxSetupCount = 0;
5347         pSMB->Reserved = 0;
5348         pSMB->Flags = 0;
5349         pSMB->Timeout = 0;
5350         pSMB->Reserved2 = 0;
5351         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5352                                 - 4;
5353         offset = param_offset + params;
5354
5355         pSMB->MaxParameterCount = cpu_to_le16(4);
5356         /* BB find exact max SMB PDU from sess structure BB */
5357         pSMB->MaxDataCount = cpu_to_le16(100);
5358         pSMB->SetupCount = 1;
5359         pSMB->Reserved3 = 0;
5360         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5361         byte_count = 1 /* pad */ + params + 12;
5362
5363         pSMB->DataCount = cpu_to_le16(12);
5364         pSMB->ParameterCount = cpu_to_le16(params);
5365         pSMB->TotalDataCount = pSMB->DataCount;
5366         pSMB->TotalParameterCount = pSMB->ParameterCount;
5367         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5368         pSMB->DataOffset = cpu_to_le16(offset);
5369
5370         /* Params. */
5371         pSMB->FileNum = 0;
5372         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5373
5374         /* Data. */
5375         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5376         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5377         pSMB->ClientUnixCap = cpu_to_le64(cap);
5378
5379         inc_rfc1001_len(pSMB, byte_count);
5380         pSMB->ByteCount = cpu_to_le16(byte_count);
5381
5382         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5383                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5384         if (rc) {
5385                 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5386         } else {                /* decode response */
5387                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5388                 if (rc)
5389                         rc = -EIO;      /* bad smb */
5390         }
5391         cifs_buf_release(pSMB);
5392
5393         if (rc == -EAGAIN)
5394                 goto SETFSUnixRetry;
5395
5396         return rc;
5397 }
5398
5399
5400
5401 int
5402 CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
5403                    struct kstatfs *FSData)
5404 {
5405 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5406         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5407         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5408         FILE_SYSTEM_POSIX_INFO *response_data;
5409         int rc = 0;
5410         int bytes_returned = 0;
5411         __u16 params, byte_count;
5412
5413         cFYI(1, "In QFSPosixInfo");
5414 QFSPosixRetry:
5415         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5416                       (void **) &pSMBr);
5417         if (rc)
5418                 return rc;
5419
5420         params = 2;     /* level */
5421         pSMB->TotalDataCount = 0;
5422         pSMB->DataCount = 0;
5423         pSMB->DataOffset = 0;
5424         pSMB->MaxParameterCount = cpu_to_le16(2);
5425         /* BB find exact max SMB PDU from sess structure BB */
5426         pSMB->MaxDataCount = cpu_to_le16(100);
5427         pSMB->MaxSetupCount = 0;
5428         pSMB->Reserved = 0;
5429         pSMB->Flags = 0;
5430         pSMB->Timeout = 0;
5431         pSMB->Reserved2 = 0;
5432         byte_count = params + 1 /* pad */ ;
5433         pSMB->ParameterCount = cpu_to_le16(params);
5434         pSMB->TotalParameterCount = pSMB->ParameterCount;
5435         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5436                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5437         pSMB->SetupCount = 1;
5438         pSMB->Reserved3 = 0;
5439         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5440         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5441         inc_rfc1001_len(pSMB, byte_count);
5442         pSMB->ByteCount = cpu_to_le16(byte_count);
5443
5444         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5445                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5446         if (rc) {
5447                 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5448         } else {                /* decode response */
5449                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5450
5451                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5452                         rc = -EIO;      /* bad smb */
5453                 } else {
5454                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5455                         response_data =
5456                             (FILE_SYSTEM_POSIX_INFO
5457                              *) (((char *) &pSMBr->hdr.Protocol) +
5458                                  data_offset);
5459                         FSData->f_bsize =
5460                                         le32_to_cpu(response_data->BlockSize);
5461                         FSData->f_blocks =
5462                                         le64_to_cpu(response_data->TotalBlocks);
5463                         FSData->f_bfree =
5464                             le64_to_cpu(response_data->BlocksAvail);
5465                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5466                                 FSData->f_bavail = FSData->f_bfree;
5467                         } else {
5468                                 FSData->f_bavail =
5469                                     le64_to_cpu(response_data->UserBlocksAvail);
5470                         }
5471                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5472                                 FSData->f_files =
5473                                      le64_to_cpu(response_data->TotalFileNodes);
5474                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5475                                 FSData->f_ffree =
5476                                       le64_to_cpu(response_data->FreeFileNodes);
5477                 }
5478         }
5479         cifs_buf_release(pSMB);
5480
5481         if (rc == -EAGAIN)
5482                 goto QFSPosixRetry;
5483
5484         return rc;
5485 }
5486
5487
5488 /* We can not use write of zero bytes trick to
5489    set file size due to need for large file support.  Also note that
5490    this SetPathInfo is preferred to SetFileInfo based method in next
5491    routine which is only needed to work around a sharing violation bug
5492    in Samba which this routine can run into */
5493
5494 int
5495 CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
5496               __u64 size, bool SetAllocation,
5497               const struct nls_table *nls_codepage, int remap)
5498 {
5499         struct smb_com_transaction2_spi_req *pSMB = NULL;
5500         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5501         struct file_end_of_file_info *parm_data;
5502         int name_len;
5503         int rc = 0;
5504         int bytes_returned = 0;
5505         __u16 params, byte_count, data_count, param_offset, offset;
5506
5507         cFYI(1, "In SetEOF");
5508 SetEOFRetry:
5509         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5510                       (void **) &pSMBr);
5511         if (rc)
5512                 return rc;
5513
5514         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5515                 name_len =
5516                     cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5517                                      PATH_MAX, nls_codepage, remap);
5518                 name_len++;     /* trailing null */
5519                 name_len *= 2;
5520         } else {        /* BB improve the check for buffer overruns BB */
5521                 name_len = strnlen(fileName, PATH_MAX);
5522                 name_len++;     /* trailing null */
5523                 strncpy(pSMB->FileName, fileName, name_len);
5524         }
5525         params = 6 + name_len;
5526         data_count = sizeof(struct file_end_of_file_info);
5527         pSMB->MaxParameterCount = cpu_to_le16(2);
5528         pSMB->MaxDataCount = cpu_to_le16(4100);
5529         pSMB->MaxSetupCount = 0;
5530         pSMB->Reserved = 0;
5531         pSMB->Flags = 0;
5532         pSMB->Timeout = 0;
5533         pSMB->Reserved2 = 0;
5534         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5535                                 InformationLevel) - 4;
5536         offset = param_offset + params;
5537         if (SetAllocation) {
5538                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5539                         pSMB->InformationLevel =
5540                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5541                 else
5542                         pSMB->InformationLevel =
5543                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5544         } else /* Set File Size */  {
5545             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5546                     pSMB->InformationLevel =
5547                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5548             else
5549                     pSMB->InformationLevel =
5550                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5551         }
5552
5553         parm_data =
5554             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5555                                        offset);
5556         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5557         pSMB->DataOffset = cpu_to_le16(offset);
5558         pSMB->SetupCount = 1;
5559         pSMB->Reserved3 = 0;
5560         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5561         byte_count = 3 /* pad */  + params + data_count;
5562         pSMB->DataCount = cpu_to_le16(data_count);
5563         pSMB->TotalDataCount = pSMB->DataCount;
5564         pSMB->ParameterCount = cpu_to_le16(params);
5565         pSMB->TotalParameterCount = pSMB->ParameterCount;
5566         pSMB->Reserved4 = 0;
5567         inc_rfc1001_len(pSMB, byte_count);
5568         parm_data->FileSize = cpu_to_le64(size);
5569         pSMB->ByteCount = cpu_to_le16(byte_count);
5570         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5571                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5572         if (rc)
5573                 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5574
5575         cifs_buf_release(pSMB);
5576
5577         if (rc == -EAGAIN)
5578                 goto SetEOFRetry;
5579
5580         return rc;
5581 }
5582
5583 int
5584 CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5585                    __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5586 {
5587         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5588         struct file_end_of_file_info *parm_data;
5589         int rc = 0;
5590         __u16 params, param_offset, offset, byte_count, count;
5591
5592         cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5593                         (long long)size);
5594         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5595
5596         if (rc)
5597                 return rc;
5598
5599         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5600         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5601
5602         params = 6;
5603         pSMB->MaxSetupCount = 0;
5604         pSMB->Reserved = 0;
5605         pSMB->Flags = 0;
5606         pSMB->Timeout = 0;
5607         pSMB->Reserved2 = 0;
5608         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5609         offset = param_offset + params;
5610
5611         count = sizeof(struct file_end_of_file_info);
5612         pSMB->MaxParameterCount = cpu_to_le16(2);
5613         /* BB find exact max SMB PDU from sess structure BB */
5614         pSMB->MaxDataCount = cpu_to_le16(1000);
5615         pSMB->SetupCount = 1;
5616         pSMB->Reserved3 = 0;
5617         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5618         byte_count = 3 /* pad */  + params + count;
5619         pSMB->DataCount = cpu_to_le16(count);
5620         pSMB->ParameterCount = cpu_to_le16(params);
5621         pSMB->TotalDataCount = pSMB->DataCount;
5622         pSMB->TotalParameterCount = pSMB->ParameterCount;
5623         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5624         parm_data =
5625                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5626                                 + offset);
5627         pSMB->DataOffset = cpu_to_le16(offset);
5628         parm_data->FileSize = cpu_to_le64(size);
5629         pSMB->Fid = fid;
5630         if (SetAllocation) {
5631                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5632                         pSMB->InformationLevel =
5633                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5634                 else
5635                         pSMB->InformationLevel =
5636                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5637         } else /* Set File Size */  {
5638             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5639                     pSMB->InformationLevel =
5640                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5641             else
5642                     pSMB->InformationLevel =
5643                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5644         }
5645         pSMB->Reserved4 = 0;
5646         inc_rfc1001_len(pSMB, byte_count);
5647         pSMB->ByteCount = cpu_to_le16(byte_count);
5648         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5649         if (rc) {
5650                 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5651         }
5652
5653         /* Note: On -EAGAIN error only caller can retry on handle based calls
5654                 since file handle passed in no longer valid */
5655
5656         return rc;
5657 }
5658
5659 /* Some legacy servers such as NT4 require that the file times be set on
5660    an open handle, rather than by pathname - this is awkward due to
5661    potential access conflicts on the open, but it is unavoidable for these
5662    old servers since the only other choice is to go from 100 nanosecond DCE
5663    time and resort to the original setpathinfo level which takes the ancient
5664    DOS time format with 2 second granularity */
5665 int
5666 CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5667                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5668 {
5669         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5670         char *data_offset;
5671         int rc = 0;
5672         __u16 params, param_offset, offset, byte_count, count;
5673
5674         cFYI(1, "Set Times (via SetFileInfo)");
5675         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5676
5677         if (rc)
5678                 return rc;
5679
5680         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5681         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5682
5683         params = 6;
5684         pSMB->MaxSetupCount = 0;
5685         pSMB->Reserved = 0;
5686         pSMB->Flags = 0;
5687         pSMB->Timeout = 0;
5688         pSMB->Reserved2 = 0;
5689         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5690         offset = param_offset + params;
5691
5692         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5693
5694         count = sizeof(FILE_BASIC_INFO);
5695         pSMB->MaxParameterCount = cpu_to_le16(2);
5696         /* BB find max SMB PDU from sess */
5697         pSMB->MaxDataCount = cpu_to_le16(1000);
5698         pSMB->SetupCount = 1;
5699         pSMB->Reserved3 = 0;
5700         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5701         byte_count = 3 /* pad */  + params + count;
5702         pSMB->DataCount = cpu_to_le16(count);
5703         pSMB->ParameterCount = cpu_to_le16(params);
5704         pSMB->TotalDataCount = pSMB->DataCount;
5705         pSMB->TotalParameterCount = pSMB->ParameterCount;
5706         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5707         pSMB->DataOffset = cpu_to_le16(offset);
5708         pSMB->Fid = fid;
5709         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5710                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5711         else
5712                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5713         pSMB->Reserved4 = 0;
5714         inc_rfc1001_len(pSMB, byte_count);
5715         pSMB->ByteCount = cpu_to_le16(byte_count);
5716         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5717         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5718         if (rc)
5719                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5720
5721         /* Note: On -EAGAIN error only caller can retry on handle based calls
5722                 since file handle passed in no longer valid */
5723
5724         return rc;
5725 }
5726
5727 int
5728 CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5729                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5730 {
5731         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5732         char *data_offset;
5733         int rc = 0;
5734         __u16 params, param_offset, offset, byte_count, count;
5735
5736         cFYI(1, "Set File Disposition (via SetFileInfo)");
5737         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5738
5739         if (rc)
5740                 return rc;
5741
5742         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5743         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5744
5745         params = 6;
5746         pSMB->MaxSetupCount = 0;
5747         pSMB->Reserved = 0;
5748         pSMB->Flags = 0;
5749         pSMB->Timeout = 0;
5750         pSMB->Reserved2 = 0;
5751         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5752         offset = param_offset + params;
5753
5754         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5755
5756         count = 1;
5757         pSMB->MaxParameterCount = cpu_to_le16(2);
5758         /* BB find max SMB PDU from sess */
5759         pSMB->MaxDataCount = cpu_to_le16(1000);
5760         pSMB->SetupCount = 1;
5761         pSMB->Reserved3 = 0;
5762         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5763         byte_count = 3 /* pad */  + params + count;
5764         pSMB->DataCount = cpu_to_le16(count);
5765         pSMB->ParameterCount = cpu_to_le16(params);
5766         pSMB->TotalDataCount = pSMB->DataCount;
5767         pSMB->TotalParameterCount = pSMB->ParameterCount;
5768         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5769         pSMB->DataOffset = cpu_to_le16(offset);
5770         pSMB->Fid = fid;
5771         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5772         pSMB->Reserved4 = 0;
5773         inc_rfc1001_len(pSMB, byte_count);
5774         pSMB->ByteCount = cpu_to_le16(byte_count);
5775         *data_offset = delete_file ? 1 : 0;
5776         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5777         if (rc)
5778                 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5779
5780         return rc;
5781 }
5782
5783 int
5784 CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5785                    const char *fileName, const FILE_BASIC_INFO *data,
5786                    const struct nls_table *nls_codepage, int remap)
5787 {
5788         TRANSACTION2_SPI_REQ *pSMB = NULL;
5789         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5790         int name_len;
5791         int rc = 0;
5792         int bytes_returned = 0;
5793         char *data_offset;
5794         __u16 params, param_offset, offset, byte_count, count;
5795
5796         cFYI(1, "In SetTimes");
5797
5798 SetTimesRetry:
5799         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5800                       (void **) &pSMBr);
5801         if (rc)
5802                 return rc;
5803
5804         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5805                 name_len =
5806                     cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5807                                      PATH_MAX, nls_codepage, remap);
5808                 name_len++;     /* trailing null */
5809                 name_len *= 2;
5810         } else {        /* BB improve the check for buffer overruns BB */
5811                 name_len = strnlen(fileName, PATH_MAX);
5812                 name_len++;     /* trailing null */
5813                 strncpy(pSMB->FileName, fileName, name_len);
5814         }
5815
5816         params = 6 + name_len;
5817         count = sizeof(FILE_BASIC_INFO);
5818         pSMB->MaxParameterCount = cpu_to_le16(2);
5819         /* BB find max SMB PDU from sess structure BB */
5820         pSMB->MaxDataCount = cpu_to_le16(1000);
5821         pSMB->MaxSetupCount = 0;
5822         pSMB->Reserved = 0;
5823         pSMB->Flags = 0;
5824         pSMB->Timeout = 0;
5825         pSMB->Reserved2 = 0;
5826         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5827                                 InformationLevel) - 4;
5828         offset = param_offset + params;
5829         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5830         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5831         pSMB->DataOffset = cpu_to_le16(offset);
5832         pSMB->SetupCount = 1;
5833         pSMB->Reserved3 = 0;
5834         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5835         byte_count = 3 /* pad */  + params + count;
5836
5837         pSMB->DataCount = cpu_to_le16(count);
5838         pSMB->ParameterCount = cpu_to_le16(params);
5839         pSMB->TotalDataCount = pSMB->DataCount;
5840         pSMB->TotalParameterCount = pSMB->ParameterCount;
5841         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5842                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5843         else
5844                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5845         pSMB->Reserved4 = 0;
5846         inc_rfc1001_len(pSMB, byte_count);
5847         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5848         pSMB->ByteCount = cpu_to_le16(byte_count);
5849         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5850                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5851         if (rc)
5852                 cFYI(1, "SetPathInfo (times) returned %d", rc);
5853
5854         cifs_buf_release(pSMB);
5855
5856         if (rc == -EAGAIN)
5857                 goto SetTimesRetry;
5858
5859         return rc;
5860 }
5861
5862 /* Can not be used to set time stamps yet (due to old DOS time format) */
5863 /* Can be used to set attributes */
5864 #if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
5865           handling it anyway and NT4 was what we thought it would be needed for
5866           Do not delete it until we prove whether needed for Win9x though */
5867 int
5868 CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5869                 __u16 dos_attrs, const struct nls_table *nls_codepage)
5870 {
5871         SETATTR_REQ *pSMB = NULL;
5872         SETATTR_RSP *pSMBr = NULL;
5873         int rc = 0;
5874         int bytes_returned;
5875         int name_len;
5876
5877         cFYI(1, "In SetAttrLegacy");
5878
5879 SetAttrLgcyRetry:
5880         rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5881                       (void **) &pSMBr);
5882         if (rc)
5883                 return rc;
5884
5885         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5886                 name_len =
5887                         ConvertToUCS((__le16 *) pSMB->fileName, fileName,
5888                                 PATH_MAX, nls_codepage);
5889                 name_len++;     /* trailing null */
5890                 name_len *= 2;
5891         } else {        /* BB improve the check for buffer overruns BB */
5892                 name_len = strnlen(fileName, PATH_MAX);
5893                 name_len++;     /* trailing null */
5894                 strncpy(pSMB->fileName, fileName, name_len);
5895         }
5896         pSMB->attr = cpu_to_le16(dos_attrs);
5897         pSMB->BufferFormat = 0x04;
5898         inc_rfc1001_len(pSMB, name_len + 1);
5899         pSMB->ByteCount = cpu_to_le16(name_len + 1);
5900         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5901                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5902         if (rc)
5903                 cFYI(1, "Error in LegacySetAttr = %d", rc);
5904
5905         cifs_buf_release(pSMB);
5906
5907         if (rc == -EAGAIN)
5908                 goto SetAttrLgcyRetry;
5909
5910         return rc;
5911 }
5912 #endif /* temporarily unneeded SetAttr legacy function */
5913
5914 static void
5915 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5916                         const struct cifs_unix_set_info_args *args)
5917 {
5918         u64 mode = args->mode;
5919
5920         /*
5921          * Samba server ignores set of file size to zero due to bugs in some
5922          * older clients, but we should be precise - we use SetFileSize to
5923          * set file size and do not want to truncate file size to zero
5924          * accidentally as happened on one Samba server beta by putting
5925          * zero instead of -1 here
5926          */
5927         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5928         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5929         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5930         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5931         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5932         data_offset->Uid = cpu_to_le64(args->uid);
5933         data_offset->Gid = cpu_to_le64(args->gid);
5934         /* better to leave device as zero when it is  */
5935         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5936         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5937         data_offset->Permissions = cpu_to_le64(mode);
5938
5939         if (S_ISREG(mode))
5940                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5941         else if (S_ISDIR(mode))
5942                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5943         else if (S_ISLNK(mode))
5944                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5945         else if (S_ISCHR(mode))
5946                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5947         else if (S_ISBLK(mode))
5948                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5949         else if (S_ISFIFO(mode))
5950                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5951         else if (S_ISSOCK(mode))
5952                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5953 }
5954
5955 int
5956 CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5957                        const struct cifs_unix_set_info_args *args,
5958                        u16 fid, u32 pid_of_opener)
5959 {
5960         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5961         FILE_UNIX_BASIC_INFO *data_offset;
5962         int rc = 0;
5963         u16 params, param_offset, offset, byte_count, count;
5964
5965         cFYI(1, "Set Unix Info (via SetFileInfo)");
5966         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5967
5968         if (rc)
5969                 return rc;
5970
5971         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5972         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5973
5974         params = 6;
5975         pSMB->MaxSetupCount = 0;
5976         pSMB->Reserved = 0;
5977         pSMB->Flags = 0;
5978         pSMB->Timeout = 0;
5979         pSMB->Reserved2 = 0;
5980         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5981         offset = param_offset + params;
5982
5983         data_offset = (FILE_UNIX_BASIC_INFO *)
5984                                 ((char *)(&pSMB->hdr.Protocol) + offset);
5985         count = sizeof(FILE_UNIX_BASIC_INFO);
5986
5987         pSMB->MaxParameterCount = cpu_to_le16(2);
5988         /* BB find max SMB PDU from sess */
5989         pSMB->MaxDataCount = cpu_to_le16(1000);
5990         pSMB->SetupCount = 1;
5991         pSMB->Reserved3 = 0;
5992         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5993         byte_count = 3 /* pad */  + params + count;
5994         pSMB->DataCount = cpu_to_le16(count);
5995         pSMB->ParameterCount = cpu_to_le16(params);
5996         pSMB->TotalDataCount = pSMB->DataCount;
5997         pSMB->TotalParameterCount = pSMB->ParameterCount;
5998         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5999         pSMB->DataOffset = cpu_to_le16(offset);
6000         pSMB->Fid = fid;
6001         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6002         pSMB->Reserved4 = 0;
6003         inc_rfc1001_len(pSMB, byte_count);
6004         pSMB->ByteCount = cpu_to_le16(byte_count);
6005
6006         cifs_fill_unix_set_info(data_offset, args);
6007
6008         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
6009         if (rc)
6010                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
6011
6012         /* Note: On -EAGAIN error only caller can retry on handle based calls
6013                 since file handle passed in no longer valid */
6014
6015         return rc;
6016 }
6017
6018 int
6019 CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
6020                        const struct cifs_unix_set_info_args *args,
6021                        const struct nls_table *nls_codepage, int remap)
6022 {
6023         TRANSACTION2_SPI_REQ *pSMB = NULL;
6024         TRANSACTION2_SPI_RSP *pSMBr = NULL;
6025         int name_len;
6026         int rc = 0;
6027         int bytes_returned = 0;
6028         FILE_UNIX_BASIC_INFO *data_offset;
6029         __u16 params, param_offset, offset, count, byte_count;
6030
6031         cFYI(1, "In SetUID/GID/Mode");
6032 setPermsRetry:
6033         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6034                       (void **) &pSMBr);
6035         if (rc)
6036                 return rc;
6037
6038         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6039                 name_len =
6040                     cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
6041                                      PATH_MAX, nls_codepage, remap);
6042                 name_len++;     /* trailing null */
6043                 name_len *= 2;
6044         } else {        /* BB improve the check for buffer overruns BB */
6045                 name_len = strnlen(fileName, PATH_MAX);
6046                 name_len++;     /* trailing null */
6047                 strncpy(pSMB->FileName, fileName, name_len);
6048         }
6049
6050         params = 6 + name_len;
6051         count = sizeof(FILE_UNIX_BASIC_INFO);
6052         pSMB->MaxParameterCount = cpu_to_le16(2);
6053         /* BB find max SMB PDU from sess structure BB */
6054         pSMB->MaxDataCount = cpu_to_le16(1000);
6055         pSMB->MaxSetupCount = 0;
6056         pSMB->Reserved = 0;
6057         pSMB->Flags = 0;
6058         pSMB->Timeout = 0;
6059         pSMB->Reserved2 = 0;
6060         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6061                                 InformationLevel) - 4;
6062         offset = param_offset + params;
6063         data_offset =
6064             (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6065                                       offset);
6066         memset(data_offset, 0, count);
6067         pSMB->DataOffset = cpu_to_le16(offset);
6068         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6069         pSMB->SetupCount = 1;
6070         pSMB->Reserved3 = 0;
6071         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6072         byte_count = 3 /* pad */  + params + count;
6073         pSMB->ParameterCount = cpu_to_le16(params);
6074         pSMB->DataCount = cpu_to_le16(count);
6075         pSMB->TotalParameterCount = pSMB->ParameterCount;
6076         pSMB->TotalDataCount = pSMB->DataCount;
6077         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6078         pSMB->Reserved4 = 0;
6079         inc_rfc1001_len(pSMB, byte_count);
6080
6081         cifs_fill_unix_set_info(data_offset, args);
6082
6083         pSMB->ByteCount = cpu_to_le16(byte_count);
6084         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6085                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6086         if (rc)
6087                 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6088
6089         cifs_buf_release(pSMB);
6090         if (rc == -EAGAIN)
6091                 goto setPermsRetry;
6092         return rc;
6093 }
6094
6095 #ifdef CONFIG_CIFS_XATTR
6096 /*
6097  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6098  * function used by listxattr and getxattr type calls. When ea_name is set,
6099  * it looks for that attribute name and stuffs that value into the EAData
6100  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6101  * buffer. In both cases, the return value is either the length of the
6102  * resulting data or a negative error code. If EAData is a NULL pointer then
6103  * the data isn't copied to it, but the length is returned.
6104  */
6105 ssize_t
6106 CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
6107                 const unsigned char *searchName, const unsigned char *ea_name,
6108                 char *EAData, size_t buf_size,
6109                 const struct nls_table *nls_codepage, int remap)
6110 {
6111                 /* BB assumes one setup word */
6112         TRANSACTION2_QPI_REQ *pSMB = NULL;
6113         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6114         int rc = 0;
6115         int bytes_returned;
6116         int list_len;
6117         struct fealist *ea_response_data;
6118         struct fea *temp_fea;
6119         char *temp_ptr;
6120         char *end_of_smb;
6121         __u16 params, byte_count, data_offset;
6122         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6123
6124         cFYI(1, "In Query All EAs path %s", searchName);
6125 QAllEAsRetry:
6126         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6127                       (void **) &pSMBr);
6128         if (rc)
6129                 return rc;
6130
6131         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6132                 list_len =
6133                     cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
6134                                      PATH_MAX, nls_codepage, remap);
6135                 list_len++;     /* trailing null */
6136                 list_len *= 2;
6137         } else {        /* BB improve the check for buffer overruns BB */
6138                 list_len = strnlen(searchName, PATH_MAX);
6139                 list_len++;     /* trailing null */
6140                 strncpy(pSMB->FileName, searchName, list_len);
6141         }
6142
6143         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6144         pSMB->TotalDataCount = 0;
6145         pSMB->MaxParameterCount = cpu_to_le16(2);
6146         /* BB find exact max SMB PDU from sess structure BB */
6147         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6148         pSMB->MaxSetupCount = 0;
6149         pSMB->Reserved = 0;
6150         pSMB->Flags = 0;
6151         pSMB->Timeout = 0;
6152         pSMB->Reserved2 = 0;
6153         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6154         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6155         pSMB->DataCount = 0;
6156         pSMB->DataOffset = 0;
6157         pSMB->SetupCount = 1;
6158         pSMB->Reserved3 = 0;
6159         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6160         byte_count = params + 1 /* pad */ ;
6161         pSMB->TotalParameterCount = cpu_to_le16(params);
6162         pSMB->ParameterCount = pSMB->TotalParameterCount;
6163         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6164         pSMB->Reserved4 = 0;
6165         inc_rfc1001_len(pSMB, byte_count);
6166         pSMB->ByteCount = cpu_to_le16(byte_count);
6167
6168         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6169                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6170         if (rc) {
6171                 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6172                 goto QAllEAsOut;
6173         }
6174
6175
6176         /* BB also check enough total bytes returned */
6177         /* BB we need to improve the validity checking
6178         of these trans2 responses */
6179
6180         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6181         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6182                 rc = -EIO;      /* bad smb */
6183                 goto QAllEAsOut;
6184         }
6185
6186         /* check that length of list is not more than bcc */
6187         /* check that each entry does not go beyond length
6188            of list */
6189         /* check that each element of each entry does not
6190            go beyond end of list */
6191         /* validate_trans2_offsets() */
6192         /* BB check if start of smb + data_offset > &bcc+ bcc */
6193
6194         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6195         ea_response_data = (struct fealist *)
6196                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6197
6198         list_len = le32_to_cpu(ea_response_data->list_len);
6199         cFYI(1, "ea length %d", list_len);
6200         if (list_len <= 8) {
6201                 cFYI(1, "empty EA list returned from server");
6202                 goto QAllEAsOut;
6203         }
6204
6205         /* make sure list_len doesn't go past end of SMB */
6206         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6207         if ((char *)ea_response_data + list_len > end_of_smb) {
6208                 cFYI(1, "EA list appears to go beyond SMB");
6209                 rc = -EIO;
6210                 goto QAllEAsOut;
6211         }
6212
6213         /* account for ea list len */
6214         list_len -= 4;
6215         temp_fea = ea_response_data->list;
6216         temp_ptr = (char *)temp_fea;
6217         while (list_len > 0) {
6218                 unsigned int name_len;
6219                 __u16 value_len;
6220
6221                 list_len -= 4;
6222                 temp_ptr += 4;
6223                 /* make sure we can read name_len and value_len */
6224                 if (list_len < 0) {
6225                         cFYI(1, "EA entry goes beyond length of list");
6226                         rc = -EIO;
6227                         goto QAllEAsOut;
6228                 }
6229
6230                 name_len = temp_fea->name_len;
6231                 value_len = le16_to_cpu(temp_fea->value_len);
6232                 list_len -= name_len + 1 + value_len;
6233                 if (list_len < 0) {
6234                         cFYI(1, "EA entry goes beyond length of list");
6235                         rc = -EIO;
6236                         goto QAllEAsOut;
6237                 }
6238
6239                 if (ea_name) {
6240                         if (ea_name_len == name_len &&
6241                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6242                                 temp_ptr += name_len + 1;
6243                                 rc = value_len;
6244                                 if (buf_size == 0)
6245                                         goto QAllEAsOut;
6246                                 if ((size_t)value_len > buf_size) {
6247                                         rc = -ERANGE;
6248                                         goto QAllEAsOut;
6249                                 }
6250                                 memcpy(EAData, temp_ptr, value_len);
6251                                 goto QAllEAsOut;
6252                         }
6253                 } else {
6254                         /* account for prefix user. and trailing null */
6255                         rc += (5 + 1 + name_len);
6256                         if (rc < (int) buf_size) {
6257                                 memcpy(EAData, "user.", 5);
6258                                 EAData += 5;
6259                                 memcpy(EAData, temp_ptr, name_len);
6260                                 EAData += name_len;
6261                                 /* null terminate name */
6262                                 *EAData = 0;
6263                                 ++EAData;
6264                         } else if (buf_size == 0) {
6265                                 /* skip copy - calc size only */
6266                         } else {
6267                                 /* stop before overrun buffer */
6268                                 rc = -ERANGE;
6269                                 break;
6270                         }
6271                 }
6272                 temp_ptr += name_len + 1 + value_len;
6273                 temp_fea = (struct fea *)temp_ptr;
6274         }
6275
6276         /* didn't find the named attribute */
6277         if (ea_name)
6278                 rc = -ENODATA;
6279
6280 QAllEAsOut:
6281         cifs_buf_release(pSMB);
6282         if (rc == -EAGAIN)
6283                 goto QAllEAsRetry;
6284
6285         return (ssize_t)rc;
6286 }
6287
6288 int
6289 CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
6290              const char *ea_name, const void *ea_value,
6291              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6292              int remap)
6293 {
6294         struct smb_com_transaction2_spi_req *pSMB = NULL;
6295         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6296         struct fealist *parm_data;
6297         int name_len;
6298         int rc = 0;
6299         int bytes_returned = 0;
6300         __u16 params, param_offset, byte_count, offset, count;
6301
6302         cFYI(1, "In SetEA");
6303 SetEARetry:
6304         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6305                       (void **) &pSMBr);
6306         if (rc)
6307                 return rc;
6308
6309         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6310                 name_len =
6311                     cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
6312                                      PATH_MAX, nls_codepage, remap);
6313                 name_len++;     /* trailing null */
6314                 name_len *= 2;
6315         } else {        /* BB improve the check for buffer overruns BB */
6316                 name_len = strnlen(fileName, PATH_MAX);
6317                 name_len++;     /* trailing null */
6318                 strncpy(pSMB->FileName, fileName, name_len);
6319         }
6320
6321         params = 6 + name_len;
6322
6323         /* done calculating parms using name_len of file name,
6324         now use name_len to calculate length of ea name
6325         we are going to create in the inode xattrs */
6326         if (ea_name == NULL)
6327                 name_len = 0;
6328         else
6329                 name_len = strnlen(ea_name, 255);
6330
6331         count = sizeof(*parm_data) + ea_value_len + name_len;
6332         pSMB->MaxParameterCount = cpu_to_le16(2);
6333         /* BB find max SMB PDU from sess */
6334         pSMB->MaxDataCount = cpu_to_le16(1000);
6335         pSMB->MaxSetupCount = 0;
6336         pSMB->Reserved = 0;
6337         pSMB->Flags = 0;
6338         pSMB->Timeout = 0;
6339         pSMB->Reserved2 = 0;
6340         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6341                                 InformationLevel) - 4;
6342         offset = param_offset + params;
6343         pSMB->InformationLevel =
6344                 cpu_to_le16(SMB_SET_FILE_EA);
6345
6346         parm_data =
6347                 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6348                                        offset);
6349         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6350         pSMB->DataOffset = cpu_to_le16(offset);
6351         pSMB->SetupCount = 1;
6352         pSMB->Reserved3 = 0;
6353         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6354         byte_count = 3 /* pad */  + params + count;
6355         pSMB->DataCount = cpu_to_le16(count);
6356         parm_data->list_len = cpu_to_le32(count);
6357         parm_data->list[0].EA_flags = 0;
6358         /* we checked above that name len is less than 255 */
6359         parm_data->list[0].name_len = (__u8)name_len;
6360         /* EA names are always ASCII */
6361         if (ea_name)
6362                 strncpy(parm_data->list[0].name, ea_name, name_len);
6363         parm_data->list[0].name[name_len] = 0;
6364         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6365         /* caller ensures that ea_value_len is less than 64K but
6366         we need to ensure that it fits within the smb */
6367
6368         /*BB add length check to see if it would fit in
6369              negotiated SMB buffer size BB */
6370         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6371         if (ea_value_len)
6372                 memcpy(parm_data->list[0].name+name_len+1,
6373                        ea_value, ea_value_len);
6374
6375         pSMB->TotalDataCount = pSMB->DataCount;
6376         pSMB->ParameterCount = cpu_to_le16(params);
6377         pSMB->TotalParameterCount = pSMB->ParameterCount;
6378         pSMB->Reserved4 = 0;
6379         inc_rfc1001_len(pSMB, byte_count);
6380         pSMB->ByteCount = cpu_to_le16(byte_count);
6381         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6382                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6383         if (rc)
6384                 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6385
6386         cifs_buf_release(pSMB);
6387
6388         if (rc == -EAGAIN)
6389                 goto SetEARetry;
6390
6391         return rc;
6392 }
6393 #endif
6394
6395 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6396 /*
6397  *      Years ago the kernel added a "dnotify" function for Samba server,
6398  *      to allow network clients (such as Windows) to display updated
6399  *      lists of files in directory listings automatically when
6400  *      files are added by one user when another user has the
6401  *      same directory open on their desktop.  The Linux cifs kernel
6402  *      client hooked into the kernel side of this interface for
6403  *      the same reason, but ironically when the VFS moved from
6404  *      "dnotify" to "inotify" it became harder to plug in Linux
6405  *      network file system clients (the most obvious use case
6406  *      for notify interfaces is when multiple users can update
6407  *      the contents of the same directory - exactly what network
6408  *      file systems can do) although the server (Samba) could
6409  *      still use it.  For the short term we leave the worker
6410  *      function ifdeffed out (below) until inotify is fixed
6411  *      in the VFS to make it easier to plug in network file
6412  *      system clients.  If inotify turns out to be permanently
6413  *      incompatible for network fs clients, we could instead simply
6414  *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
6415  */
6416 int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
6417                   const int notify_subdirs, const __u16 netfid,
6418                   __u32 filter, struct file *pfile, int multishot,
6419                   const struct nls_table *nls_codepage)
6420 {
6421         int rc = 0;
6422         struct smb_com_transaction_change_notify_req *pSMB = NULL;
6423         struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6424         struct dir_notify_req *dnotify_req;
6425         int bytes_returned;
6426
6427         cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6428         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6429                       (void **) &pSMBr);
6430         if (rc)
6431                 return rc;
6432
6433         pSMB->TotalParameterCount = 0 ;
6434         pSMB->TotalDataCount = 0;
6435         pSMB->MaxParameterCount = cpu_to_le32(2);
6436         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6437         pSMB->MaxSetupCount = 4;
6438         pSMB->Reserved = 0;
6439         pSMB->ParameterOffset = 0;
6440         pSMB->DataCount = 0;
6441         pSMB->DataOffset = 0;
6442         pSMB->SetupCount = 4; /* single byte does not need le conversion */
6443         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6444         pSMB->ParameterCount = pSMB->TotalParameterCount;
6445         if (notify_subdirs)
6446                 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6447         pSMB->Reserved2 = 0;
6448         pSMB->CompletionFilter = cpu_to_le32(filter);
6449         pSMB->Fid = netfid; /* file handle always le */
6450         pSMB->ByteCount = 0;
6451
6452         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6453                          (struct smb_hdr *)pSMBr, &bytes_returned,
6454                          CIFS_ASYNC_OP);
6455         if (rc) {
6456                 cFYI(1, "Error in Notify = %d", rc);
6457         } else {
6458                 /* Add file to outstanding requests */
6459                 /* BB change to kmem cache alloc */
6460                 dnotify_req = kmalloc(
6461                                                 sizeof(struct dir_notify_req),
6462                                                  GFP_KERNEL);
6463                 if (dnotify_req) {
6464                         dnotify_req->Pid = pSMB->hdr.Pid;
6465                         dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6466                         dnotify_req->Mid = pSMB->hdr.Mid;
6467                         dnotify_req->Tid = pSMB->hdr.Tid;
6468                         dnotify_req->Uid = pSMB->hdr.Uid;
6469                         dnotify_req->netfid = netfid;
6470                         dnotify_req->pfile = pfile;
6471                         dnotify_req->filter = filter;
6472                         dnotify_req->multishot = multishot;
6473                         spin_lock(&GlobalMid_Lock);
6474                         list_add_tail(&dnotify_req->lhead,
6475                                         &GlobalDnotifyReqList);
6476                         spin_unlock(&GlobalMid_Lock);
6477                 } else
6478                         rc = -ENOMEM;
6479         }
6480         cifs_buf_release(pSMB);
6481         return rc;
6482 }
6483 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */