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