CIFS: Separate protocol-specific code from transport routines
[jlayton/linux.git] / fs / cifs / cifssmb.c
1 /*
2  *   fs/cifs/cifssmb.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2010
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   Contains the routines for constructing the SMB PDUs themselves
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23
24  /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c   */
25  /* These are mostly routines that operate on a pathname, or on a tree id     */
26  /* (mounted volume), but there are eight handle based routines which must be */
27  /* treated slightly differently for reconnection purposes since we never     */
28  /* want to reuse a stale file handle and only the caller knows the file info */
29
30 #include <linux/fs.h>
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <asm/uaccess.h>
39 #include "cifspdu.h"
40 #include "cifsglob.h"
41 #include "cifsacl.h"
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
45 #include "fscache.h"
46
47 #ifdef CONFIG_CIFS_POSIX
48 static struct {
49         int index;
50         char *name;
51 } protocols[] = {
52 #ifdef CONFIG_CIFS_WEAK_PW_HASH
53         {LANMAN_PROT, "\2LM1.2X002"},
54         {LANMAN2_PROT, "\2LANMAN2.1"},
55 #endif /* weak password hashing for legacy clients */
56         {CIFS_PROT, "\2NT LM 0.12"},
57         {POSIX_PROT, "\2POSIX 2"},
58         {BAD_PROT, "\2"}
59 };
60 #else
61 static struct {
62         int index;
63         char *name;
64 } protocols[] = {
65 #ifdef CONFIG_CIFS_WEAK_PW_HASH
66         {LANMAN_PROT, "\2LM1.2X002"},
67         {LANMAN2_PROT, "\2LANMAN2.1"},
68 #endif /* weak password hashing for legacy clients */
69         {CIFS_PROT, "\2NT LM 0.12"},
70         {BAD_PROT, "\2"}
71 };
72 #endif
73
74 /* define the number of elements in the cifs dialect array */
75 #ifdef CONFIG_CIFS_POSIX
76 #ifdef CONFIG_CIFS_WEAK_PW_HASH
77 #define CIFS_NUM_PROT 4
78 #else
79 #define CIFS_NUM_PROT 2
80 #endif /* CIFS_WEAK_PW_HASH */
81 #else /* not posix */
82 #ifdef CONFIG_CIFS_WEAK_PW_HASH
83 #define CIFS_NUM_PROT 3
84 #else
85 #define CIFS_NUM_PROT 1
86 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
87 #endif /* CIFS_POSIX */
88
89 /* 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                 cifs_set_credits(server, server->maxReq);
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         cifs_set_credits(server, server->maxReq);
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, (char *)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         cifs_add_credits(server, 1);
725 }
726
727 int
728 CIFSSMBEcho(struct TCP_Server_Info *server)
729 {
730         ECHO_REQ *smb;
731         int rc = 0;
732         struct kvec iov;
733
734         cFYI(1, "In echo request");
735
736         rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
737         if (rc)
738                 return rc;
739
740         /* set up echo request */
741         smb->hdr.Tid = 0xffff;
742         smb->hdr.WordCount = 1;
743         put_unaligned_le16(1, &smb->EchoCount);
744         put_bcc(1, &smb->hdr);
745         smb->Data[0] = 'a';
746         inc_rfc1001_len(smb, 3);
747         iov.iov_base = smb;
748         iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
749
750         rc = cifs_call_async(server, &iov, 1, NULL, cifs_echo_callback,
751                              server, true);
752         if (rc)
753                 cFYI(1, "Echo request failed: %d", rc);
754
755         cifs_small_buf_release(smb);
756
757         return rc;
758 }
759
760 int
761 CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
762 {
763         LOGOFF_ANDX_REQ *pSMB;
764         int rc = 0;
765
766         cFYI(1, "In SMBLogoff for session disconnect");
767
768         /*
769          * BB: do we need to check validity of ses and server? They should
770          * always be valid since we have an active reference. If not, that
771          * should probably be a BUG()
772          */
773         if (!ses || !ses->server)
774                 return -EIO;
775
776         mutex_lock(&ses->session_mutex);
777         if (ses->need_reconnect)
778                 goto session_already_dead; /* no need to send SMBlogoff if uid
779                                               already closed due to reconnect */
780         rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
781         if (rc) {
782                 mutex_unlock(&ses->session_mutex);
783                 return rc;
784         }
785
786         pSMB->hdr.Mid = GetNextMid(ses->server);
787
788         if (ses->server->sec_mode &
789                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
790                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
791
792         pSMB->hdr.Uid = ses->Suid;
793
794         pSMB->AndXCommand = 0xFF;
795         rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
796 session_already_dead:
797         mutex_unlock(&ses->session_mutex);
798
799         /* if session dead then we do not need to do ulogoff,
800                 since server closed smb session, no sense reporting
801                 error */
802         if (rc == -EAGAIN)
803                 rc = 0;
804         return rc;
805 }
806
807 int
808 CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
809                  __u16 type, const struct nls_table *nls_codepage, int remap)
810 {
811         TRANSACTION2_SPI_REQ *pSMB = NULL;
812         TRANSACTION2_SPI_RSP *pSMBr = NULL;
813         struct unlink_psx_rq *pRqD;
814         int name_len;
815         int rc = 0;
816         int bytes_returned = 0;
817         __u16 params, param_offset, offset, byte_count;
818
819         cFYI(1, "In POSIX delete");
820 PsxDelete:
821         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
822                       (void **) &pSMBr);
823         if (rc)
824                 return rc;
825
826         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
827                 name_len =
828                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
829                                        PATH_MAX, nls_codepage, remap);
830                 name_len++;     /* trailing null */
831                 name_len *= 2;
832         } else { /* BB add path length overrun check */
833                 name_len = strnlen(fileName, PATH_MAX);
834                 name_len++;     /* trailing null */
835                 strncpy(pSMB->FileName, fileName, name_len);
836         }
837
838         params = 6 + name_len;
839         pSMB->MaxParameterCount = cpu_to_le16(2);
840         pSMB->MaxDataCount = 0; /* BB double check this with jra */
841         pSMB->MaxSetupCount = 0;
842         pSMB->Reserved = 0;
843         pSMB->Flags = 0;
844         pSMB->Timeout = 0;
845         pSMB->Reserved2 = 0;
846         param_offset = offsetof(struct smb_com_transaction2_spi_req,
847                                 InformationLevel) - 4;
848         offset = param_offset + params;
849
850         /* Setup pointer to Request Data (inode type) */
851         pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
852         pRqD->type = cpu_to_le16(type);
853         pSMB->ParameterOffset = cpu_to_le16(param_offset);
854         pSMB->DataOffset = cpu_to_le16(offset);
855         pSMB->SetupCount = 1;
856         pSMB->Reserved3 = 0;
857         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
858         byte_count = 3 /* pad */  + params + sizeof(struct unlink_psx_rq);
859
860         pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
861         pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
862         pSMB->ParameterCount = cpu_to_le16(params);
863         pSMB->TotalParameterCount = pSMB->ParameterCount;
864         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
865         pSMB->Reserved4 = 0;
866         inc_rfc1001_len(pSMB, byte_count);
867         pSMB->ByteCount = cpu_to_le16(byte_count);
868         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
869                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
870         if (rc)
871                 cFYI(1, "Posix delete returned %d", rc);
872         cifs_buf_release(pSMB);
873
874         cifs_stats_inc(&tcon->num_deletes);
875
876         if (rc == -EAGAIN)
877                 goto PsxDelete;
878
879         return rc;
880 }
881
882 int
883 CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
884                const struct nls_table *nls_codepage, int remap)
885 {
886         DELETE_FILE_REQ *pSMB = NULL;
887         DELETE_FILE_RSP *pSMBr = NULL;
888         int rc = 0;
889         int bytes_returned;
890         int name_len;
891
892 DelFileRetry:
893         rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
894                       (void **) &pSMBr);
895         if (rc)
896                 return rc;
897
898         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
899                 name_len =
900                     cifsConvertToUTF16((__le16 *) pSMB->fileName, fileName,
901                                        PATH_MAX, nls_codepage, remap);
902                 name_len++;     /* trailing null */
903                 name_len *= 2;
904         } else {                /* BB improve check for buffer overruns BB */
905                 name_len = strnlen(fileName, PATH_MAX);
906                 name_len++;     /* trailing null */
907                 strncpy(pSMB->fileName, fileName, name_len);
908         }
909         pSMB->SearchAttributes =
910             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
911         pSMB->BufferFormat = 0x04;
912         inc_rfc1001_len(pSMB, name_len + 1);
913         pSMB->ByteCount = cpu_to_le16(name_len + 1);
914         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
915                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
916         cifs_stats_inc(&tcon->num_deletes);
917         if (rc)
918                 cFYI(1, "Error in RMFile = %d", rc);
919
920         cifs_buf_release(pSMB);
921         if (rc == -EAGAIN)
922                 goto DelFileRetry;
923
924         return rc;
925 }
926
927 int
928 CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
929              const struct nls_table *nls_codepage, int remap)
930 {
931         DELETE_DIRECTORY_REQ *pSMB = NULL;
932         DELETE_DIRECTORY_RSP *pSMBr = NULL;
933         int rc = 0;
934         int bytes_returned;
935         int name_len;
936
937         cFYI(1, "In CIFSSMBRmDir");
938 RmDirRetry:
939         rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
940                       (void **) &pSMBr);
941         if (rc)
942                 return rc;
943
944         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
945                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, dirName,
946                                               PATH_MAX, nls_codepage, remap);
947                 name_len++;     /* trailing null */
948                 name_len *= 2;
949         } else {                /* BB improve check for buffer overruns BB */
950                 name_len = strnlen(dirName, PATH_MAX);
951                 name_len++;     /* trailing null */
952                 strncpy(pSMB->DirName, dirName, name_len);
953         }
954
955         pSMB->BufferFormat = 0x04;
956         inc_rfc1001_len(pSMB, name_len + 1);
957         pSMB->ByteCount = cpu_to_le16(name_len + 1);
958         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
959                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
960         cifs_stats_inc(&tcon->num_rmdirs);
961         if (rc)
962                 cFYI(1, "Error in RMDir = %d", rc);
963
964         cifs_buf_release(pSMB);
965         if (rc == -EAGAIN)
966                 goto RmDirRetry;
967         return rc;
968 }
969
970 int
971 CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
972              const char *name, const struct nls_table *nls_codepage, int remap)
973 {
974         int rc = 0;
975         CREATE_DIRECTORY_REQ *pSMB = NULL;
976         CREATE_DIRECTORY_RSP *pSMBr = NULL;
977         int bytes_returned;
978         int name_len;
979
980         cFYI(1, "In CIFSSMBMkDir");
981 MkDirRetry:
982         rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
983                       (void **) &pSMBr);
984         if (rc)
985                 return rc;
986
987         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
988                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
989                                               PATH_MAX, nls_codepage, remap);
990                 name_len++;     /* trailing null */
991                 name_len *= 2;
992         } else {                /* BB improve check for buffer overruns BB */
993                 name_len = strnlen(name, PATH_MAX);
994                 name_len++;     /* trailing null */
995                 strncpy(pSMB->DirName, name, name_len);
996         }
997
998         pSMB->BufferFormat = 0x04;
999         inc_rfc1001_len(pSMB, name_len + 1);
1000         pSMB->ByteCount = cpu_to_le16(name_len + 1);
1001         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1002                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1003         cifs_stats_inc(&tcon->num_mkdirs);
1004         if (rc)
1005                 cFYI(1, "Error in Mkdir = %d", rc);
1006
1007         cifs_buf_release(pSMB);
1008         if (rc == -EAGAIN)
1009                 goto MkDirRetry;
1010         return rc;
1011 }
1012
1013 int
1014 CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
1015                 __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
1016                 __u32 *pOplock, const char *name,
1017                 const struct nls_table *nls_codepage, int remap)
1018 {
1019         TRANSACTION2_SPI_REQ *pSMB = NULL;
1020         TRANSACTION2_SPI_RSP *pSMBr = NULL;
1021         int name_len;
1022         int rc = 0;
1023         int bytes_returned = 0;
1024         __u16 params, param_offset, offset, byte_count, count;
1025         OPEN_PSX_REQ *pdata;
1026         OPEN_PSX_RSP *psx_rsp;
1027
1028         cFYI(1, "In POSIX Create");
1029 PsxCreat:
1030         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1031                       (void **) &pSMBr);
1032         if (rc)
1033                 return rc;
1034
1035         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1036                 name_len =
1037                     cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1038                                        PATH_MAX, nls_codepage, remap);
1039                 name_len++;     /* trailing null */
1040                 name_len *= 2;
1041         } else {        /* BB improve the check for buffer overruns BB */
1042                 name_len = strnlen(name, PATH_MAX);
1043                 name_len++;     /* trailing null */
1044                 strncpy(pSMB->FileName, name, name_len);
1045         }
1046
1047         params = 6 + name_len;
1048         count = sizeof(OPEN_PSX_REQ);
1049         pSMB->MaxParameterCount = cpu_to_le16(2);
1050         pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1051         pSMB->MaxSetupCount = 0;
1052         pSMB->Reserved = 0;
1053         pSMB->Flags = 0;
1054         pSMB->Timeout = 0;
1055         pSMB->Reserved2 = 0;
1056         param_offset = offsetof(struct smb_com_transaction2_spi_req,
1057                                 InformationLevel) - 4;
1058         offset = param_offset + params;
1059         pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1060         pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1061         pdata->Permissions = cpu_to_le64(mode);
1062         pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1063         pdata->OpenFlags =  cpu_to_le32(*pOplock);
1064         pSMB->ParameterOffset = cpu_to_le16(param_offset);
1065         pSMB->DataOffset = cpu_to_le16(offset);
1066         pSMB->SetupCount = 1;
1067         pSMB->Reserved3 = 0;
1068         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1069         byte_count = 3 /* pad */  + params + count;
1070
1071         pSMB->DataCount = cpu_to_le16(count);
1072         pSMB->ParameterCount = cpu_to_le16(params);
1073         pSMB->TotalDataCount = pSMB->DataCount;
1074         pSMB->TotalParameterCount = pSMB->ParameterCount;
1075         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1076         pSMB->Reserved4 = 0;
1077         inc_rfc1001_len(pSMB, byte_count);
1078         pSMB->ByteCount = cpu_to_le16(byte_count);
1079         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1080                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1081         if (rc) {
1082                 cFYI(1, "Posix create returned %d", rc);
1083                 goto psx_create_err;
1084         }
1085
1086         cFYI(1, "copying inode info");
1087         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1088
1089         if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1090                 rc = -EIO;      /* bad smb */
1091                 goto psx_create_err;
1092         }
1093
1094         /* copy return information to pRetData */
1095         psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1096                         + le16_to_cpu(pSMBr->t2.DataOffset));
1097
1098         *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1099         if (netfid)
1100                 *netfid = psx_rsp->Fid;   /* cifs fid stays in le */
1101         /* Let caller know file was created so we can set the mode. */
1102         /* Do we care about the CreateAction in any other cases? */
1103         if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1104                 *pOplock |= CIFS_CREATE_ACTION;
1105         /* check to make sure response data is there */
1106         if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1107                 pRetData->Type = cpu_to_le32(-1); /* unknown */
1108                 cFYI(DBG2, "unknown type");
1109         } else {
1110                 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1111                                         + sizeof(FILE_UNIX_BASIC_INFO)) {
1112                         cERROR(1, "Open response data too small");
1113                         pRetData->Type = cpu_to_le32(-1);
1114                         goto psx_create_err;
1115                 }
1116                 memcpy((char *) pRetData,
1117                         (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1118                         sizeof(FILE_UNIX_BASIC_INFO));
1119         }
1120
1121 psx_create_err:
1122         cifs_buf_release(pSMB);
1123
1124         if (posix_flags & SMB_O_DIRECTORY)
1125                 cifs_stats_inc(&tcon->num_posixmkdirs);
1126         else
1127                 cifs_stats_inc(&tcon->num_posixopens);
1128
1129         if (rc == -EAGAIN)
1130                 goto PsxCreat;
1131
1132         return rc;
1133 }
1134
1135 static __u16 convert_disposition(int disposition)
1136 {
1137         __u16 ofun = 0;
1138
1139         switch (disposition) {
1140                 case FILE_SUPERSEDE:
1141                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1142                         break;
1143                 case FILE_OPEN:
1144                         ofun = SMBOPEN_OAPPEND;
1145                         break;
1146                 case FILE_CREATE:
1147                         ofun = SMBOPEN_OCREATE;
1148                         break;
1149                 case FILE_OPEN_IF:
1150                         ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1151                         break;
1152                 case FILE_OVERWRITE:
1153                         ofun = SMBOPEN_OTRUNC;
1154                         break;
1155                 case FILE_OVERWRITE_IF:
1156                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1157                         break;
1158                 default:
1159                         cFYI(1, "unknown disposition %d", disposition);
1160                         ofun =  SMBOPEN_OAPPEND; /* regular open */
1161         }
1162         return ofun;
1163 }
1164
1165 static int
1166 access_flags_to_smbopen_mode(const int access_flags)
1167 {
1168         int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1169
1170         if (masked_flags == GENERIC_READ)
1171                 return SMBOPEN_READ;
1172         else if (masked_flags == GENERIC_WRITE)
1173                 return SMBOPEN_WRITE;
1174
1175         /* just go for read/write */
1176         return SMBOPEN_READWRITE;
1177 }
1178
1179 int
1180 SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
1181             const char *fileName, const int openDisposition,
1182             const int access_flags, const int create_options, __u16 *netfid,
1183             int *pOplock, FILE_ALL_INFO *pfile_info,
1184             const struct nls_table *nls_codepage, int remap)
1185 {
1186         int rc = -EACCES;
1187         OPENX_REQ *pSMB = NULL;
1188         OPENX_RSP *pSMBr = NULL;
1189         int bytes_returned;
1190         int name_len;
1191         __u16 count;
1192
1193 OldOpenRetry:
1194         rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1195                       (void **) &pSMBr);
1196         if (rc)
1197                 return rc;
1198
1199         pSMB->AndXCommand = 0xFF;       /* none */
1200
1201         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1202                 count = 1;      /* account for one byte pad to word boundary */
1203                 name_len =
1204                    cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1205                                       fileName, PATH_MAX, nls_codepage, remap);
1206                 name_len++;     /* trailing null */
1207                 name_len *= 2;
1208         } else {                /* BB improve check for buffer overruns BB */
1209                 count = 0;      /* no pad */
1210                 name_len = strnlen(fileName, PATH_MAX);
1211                 name_len++;     /* trailing null */
1212                 strncpy(pSMB->fileName, fileName, name_len);
1213         }
1214         if (*pOplock & REQ_OPLOCK)
1215                 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1216         else if (*pOplock & REQ_BATCHOPLOCK)
1217                 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1218
1219         pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1220         pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1221         pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1222         /* set file as system file if special file such
1223            as fifo and server expecting SFU style and
1224            no Unix extensions */
1225
1226         if (create_options & CREATE_OPTION_SPECIAL)
1227                 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1228         else /* BB FIXME BB */
1229                 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1230
1231         if (create_options & CREATE_OPTION_READONLY)
1232                 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1233
1234         /* BB FIXME BB */
1235 /*      pSMB->CreateOptions = cpu_to_le32(create_options &
1236                                                  CREATE_OPTIONS_MASK); */
1237         /* BB FIXME END BB */
1238
1239         pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1240         pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1241         count += name_len;
1242         inc_rfc1001_len(pSMB, count);
1243
1244         pSMB->ByteCount = cpu_to_le16(count);
1245         /* long_op set to 1 to allow for oplock break timeouts */
1246         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1247                         (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1248         cifs_stats_inc(&tcon->num_opens);
1249         if (rc) {
1250                 cFYI(1, "Error in Open = %d", rc);
1251         } else {
1252         /* BB verify if wct == 15 */
1253
1254 /*              *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1255
1256                 *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1257                 /* Let caller know file was created so we can set the mode. */
1258                 /* Do we care about the CreateAction in any other cases? */
1259         /* BB FIXME BB */
1260 /*              if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1261                         *pOplock |= CIFS_CREATE_ACTION; */
1262         /* BB FIXME END */
1263
1264                 if (pfile_info) {
1265                         pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1266                         pfile_info->LastAccessTime = 0; /* BB fixme */
1267                         pfile_info->LastWriteTime = 0; /* BB fixme */
1268                         pfile_info->ChangeTime = 0;  /* BB fixme */
1269                         pfile_info->Attributes =
1270                                 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1271                         /* the file_info buf is endian converted by caller */
1272                         pfile_info->AllocationSize =
1273                                 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1274                         pfile_info->EndOfFile = pfile_info->AllocationSize;
1275                         pfile_info->NumberOfLinks = cpu_to_le32(1);
1276                         pfile_info->DeletePending = 0;
1277                 }
1278         }
1279
1280         cifs_buf_release(pSMB);
1281         if (rc == -EAGAIN)
1282                 goto OldOpenRetry;
1283         return rc;
1284 }
1285
1286 int
1287 CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
1288             const char *fileName, const int openDisposition,
1289             const int access_flags, const int create_options, __u16 *netfid,
1290             int *pOplock, FILE_ALL_INFO *pfile_info,
1291             const struct nls_table *nls_codepage, int remap)
1292 {
1293         int rc = -EACCES;
1294         OPEN_REQ *pSMB = NULL;
1295         OPEN_RSP *pSMBr = NULL;
1296         int bytes_returned;
1297         int name_len;
1298         __u16 count;
1299
1300 openRetry:
1301         rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1302                       (void **) &pSMBr);
1303         if (rc)
1304                 return rc;
1305
1306         pSMB->AndXCommand = 0xFF;       /* none */
1307
1308         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1309                 count = 1;      /* account for one byte pad to word boundary */
1310                 name_len =
1311                     cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1312                                        fileName, PATH_MAX, nls_codepage, remap);
1313                 name_len++;     /* trailing null */
1314                 name_len *= 2;
1315                 pSMB->NameLength = cpu_to_le16(name_len);
1316         } else {                /* BB improve check for buffer overruns BB */
1317                 count = 0;      /* no pad */
1318                 name_len = strnlen(fileName, PATH_MAX);
1319                 name_len++;     /* trailing null */
1320                 pSMB->NameLength = cpu_to_le16(name_len);
1321                 strncpy(pSMB->fileName, fileName, name_len);
1322         }
1323         if (*pOplock & REQ_OPLOCK)
1324                 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1325         else if (*pOplock & REQ_BATCHOPLOCK)
1326                 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1327         pSMB->DesiredAccess = cpu_to_le32(access_flags);
1328         pSMB->AllocationSize = 0;
1329         /* set file as system file if special file such
1330            as fifo and server expecting SFU style and
1331            no Unix extensions */
1332         if (create_options & CREATE_OPTION_SPECIAL)
1333                 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1334         else
1335                 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1336
1337         /* XP does not handle ATTR_POSIX_SEMANTICS */
1338         /* but it helps speed up case sensitive checks for other
1339         servers such as Samba */
1340         if (tcon->ses->capabilities & CAP_UNIX)
1341                 pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1342
1343         if (create_options & CREATE_OPTION_READONLY)
1344                 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1345
1346         pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1347         pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1348         pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1349         /* BB Expirement with various impersonation levels and verify */
1350         pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1351         pSMB->SecurityFlags =
1352             SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1353
1354         count += name_len;
1355         inc_rfc1001_len(pSMB, count);
1356
1357         pSMB->ByteCount = cpu_to_le16(count);
1358         /* long_op set to 1 to allow for oplock break timeouts */
1359         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1360                         (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1361         cifs_stats_inc(&tcon->num_opens);
1362         if (rc) {
1363                 cFYI(1, "Error in Open = %d", rc);
1364         } else {
1365                 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1366                 *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1367                 /* Let caller know file was created so we can set the mode. */
1368                 /* Do we care about the CreateAction in any other cases? */
1369                 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1370                         *pOplock |= CIFS_CREATE_ACTION;
1371                 if (pfile_info) {
1372                         memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1373                                 36 /* CreationTime to Attributes */);
1374                         /* the file_info buf is endian converted by caller */
1375                         pfile_info->AllocationSize = pSMBr->AllocationSize;
1376                         pfile_info->EndOfFile = pSMBr->EndOfFile;
1377                         pfile_info->NumberOfLinks = cpu_to_le32(1);
1378                         pfile_info->DeletePending = 0;
1379                 }
1380         }
1381
1382         cifs_buf_release(pSMB);
1383         if (rc == -EAGAIN)
1384                 goto openRetry;
1385         return rc;
1386 }
1387
1388 struct cifs_readdata *
1389 cifs_readdata_alloc(unsigned int nr_pages)
1390 {
1391         struct cifs_readdata *rdata;
1392
1393         /* readdata + 1 kvec for each page */
1394         rdata = kzalloc(sizeof(*rdata) +
1395                         sizeof(struct kvec) * nr_pages, GFP_KERNEL);
1396         if (rdata != NULL) {
1397                 INIT_WORK(&rdata->work, cifs_readv_complete);
1398                 INIT_LIST_HEAD(&rdata->pages);
1399         }
1400         return rdata;
1401 }
1402
1403 void
1404 cifs_readdata_free(struct cifs_readdata *rdata)
1405 {
1406         cifsFileInfo_put(rdata->cfile);
1407         kfree(rdata);
1408 }
1409
1410 /*
1411  * Discard any remaining data in the current SMB. To do this, we borrow the
1412  * current bigbuf.
1413  */
1414 static int
1415 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1416 {
1417         READ_RSP *rsp = (READ_RSP *)server->smallbuf;
1418         unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length);
1419         int remaining = rfclen + 4 - server->total_read;
1420         struct cifs_readdata *rdata = mid->callback_data;
1421
1422         while (remaining > 0) {
1423                 int length;
1424
1425                 length = cifs_read_from_socket(server, server->bigbuf,
1426                                 min_t(unsigned int, remaining,
1427                                         CIFSMaxBufSize + MAX_CIFS_HDR_SIZE));
1428                 if (length < 0)
1429                         return length;
1430                 server->total_read += length;
1431                 remaining -= length;
1432         }
1433
1434         dequeue_mid(mid, rdata->result);
1435         return 0;
1436 }
1437
1438 static int
1439 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1440 {
1441         int length, len;
1442         unsigned int data_offset, remaining, data_len;
1443         struct cifs_readdata *rdata = mid->callback_data;
1444         READ_RSP *rsp = (READ_RSP *)server->smallbuf;
1445         unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length) + 4;
1446         u64 eof;
1447         pgoff_t eof_index;
1448         struct page *page, *tpage;
1449
1450         cFYI(1, "%s: mid=%u offset=%llu bytes=%u", __func__,
1451                 mid->mid, rdata->offset, rdata->bytes);
1452
1453         /*
1454          * read the rest of READ_RSP header (sans Data array), or whatever we
1455          * can if there's not enough data. At this point, we've read down to
1456          * the Mid.
1457          */
1458         len = min_t(unsigned int, rfclen, sizeof(*rsp)) -
1459                         sizeof(struct smb_hdr) + 1;
1460
1461         rdata->iov[0].iov_base = server->smallbuf + sizeof(struct smb_hdr) - 1;
1462         rdata->iov[0].iov_len = len;
1463
1464         length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1465         if (length < 0)
1466                 return length;
1467         server->total_read += length;
1468
1469         /* Was the SMB read successful? */
1470         rdata->result = map_smb_to_linux_error(&rsp->hdr, false);
1471         if (rdata->result != 0) {
1472                 cFYI(1, "%s: server returned error %d", __func__,
1473                         rdata->result);
1474                 return cifs_readv_discard(server, mid);
1475         }
1476
1477         /* Is there enough to get to the rest of the READ_RSP header? */
1478         if (server->total_read < sizeof(READ_RSP)) {
1479                 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1480                         __func__, server->total_read, sizeof(READ_RSP));
1481                 rdata->result = -EIO;
1482                 return cifs_readv_discard(server, mid);
1483         }
1484
1485         data_offset = le16_to_cpu(rsp->DataOffset) + 4;
1486         if (data_offset < server->total_read) {
1487                 /*
1488                  * win2k8 sometimes sends an offset of 0 when the read
1489                  * is beyond the EOF. Treat it as if the data starts just after
1490                  * the header.
1491                  */
1492                 cFYI(1, "%s: data offset (%u) inside read response header",
1493                         __func__, data_offset);
1494                 data_offset = server->total_read;
1495         } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1496                 /* data_offset is beyond the end of smallbuf */
1497                 cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
1498                         __func__, data_offset);
1499                 rdata->result = -EIO;
1500                 return cifs_readv_discard(server, mid);
1501         }
1502
1503         cFYI(1, "%s: total_read=%u data_offset=%u", __func__,
1504                 server->total_read, data_offset);
1505
1506         len = data_offset - server->total_read;
1507         if (len > 0) {
1508                 /* read any junk before data into the rest of smallbuf */
1509                 rdata->iov[0].iov_base = server->smallbuf + server->total_read;
1510                 rdata->iov[0].iov_len = len;
1511                 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1512                 if (length < 0)
1513                         return length;
1514                 server->total_read += length;
1515         }
1516
1517         /* set up first iov for signature check */
1518         rdata->iov[0].iov_base = server->smallbuf;
1519         rdata->iov[0].iov_len = server->total_read;
1520         cFYI(1, "0: iov_base=%p iov_len=%zu",
1521                 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1522
1523         /* how much data is in the response? */
1524         data_len = le16_to_cpu(rsp->DataLengthHigh) << 16;
1525         data_len += le16_to_cpu(rsp->DataLength);
1526         if (data_offset + data_len > rfclen) {
1527                 /* data_len is corrupt -- discard frame */
1528                 rdata->result = -EIO;
1529                 return cifs_readv_discard(server, mid);
1530         }
1531
1532         /* marshal up the page array */
1533         len = 0;
1534         remaining = data_len;
1535         rdata->nr_iov = 1;
1536
1537         /* determine the eof that the server (probably) has */
1538         eof = CIFS_I(rdata->mapping->host)->server_eof;
1539         eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
1540         cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
1541
1542         list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1543                 if (remaining >= PAGE_CACHE_SIZE) {
1544                         /* enough data to fill the page */
1545                         rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1546                         rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
1547                         cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1548                                 rdata->nr_iov, page->index,
1549                                 rdata->iov[rdata->nr_iov].iov_base,
1550                                 rdata->iov[rdata->nr_iov].iov_len);
1551                         ++rdata->nr_iov;
1552                         len += PAGE_CACHE_SIZE;
1553                         remaining -= PAGE_CACHE_SIZE;
1554                 } else if (remaining > 0) {
1555                         /* enough for partial page, fill and zero the rest */
1556                         rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1557                         rdata->iov[rdata->nr_iov].iov_len = remaining;
1558                         cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1559                                 rdata->nr_iov, page->index,
1560                                 rdata->iov[rdata->nr_iov].iov_base,
1561                                 rdata->iov[rdata->nr_iov].iov_len);
1562                         memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
1563                                 '\0', PAGE_CACHE_SIZE - remaining);
1564                         ++rdata->nr_iov;
1565                         len += remaining;
1566                         remaining = 0;
1567                 } else if (page->index > eof_index) {
1568                         /*
1569                          * The VFS will not try to do readahead past the
1570                          * i_size, but it's possible that we have outstanding
1571                          * writes with gaps in the middle and the i_size hasn't
1572                          * caught up yet. Populate those with zeroed out pages
1573                          * to prevent the VFS from repeatedly attempting to
1574                          * fill them until the writes are flushed.
1575                          */
1576                         zero_user(page, 0, PAGE_CACHE_SIZE);
1577                         list_del(&page->lru);
1578                         lru_cache_add_file(page);
1579                         flush_dcache_page(page);
1580                         SetPageUptodate(page);
1581                         unlock_page(page);
1582                         page_cache_release(page);
1583                 } else {
1584                         /* no need to hold page hostage */
1585                         list_del(&page->lru);
1586                         lru_cache_add_file(page);
1587                         unlock_page(page);
1588                         page_cache_release(page);
1589                 }
1590         }
1591
1592         /* issue the read if we have any iovecs left to fill */
1593         if (rdata->nr_iov > 1) {
1594                 length = cifs_readv_from_socket(server, &rdata->iov[1],
1595                                                 rdata->nr_iov - 1, len);
1596                 if (length < 0)
1597                         return length;
1598                 server->total_read += length;
1599         } else {
1600                 length = 0;
1601         }
1602
1603         rdata->bytes = length;
1604
1605         cFYI(1, "total_read=%u rfclen=%u remaining=%u", server->total_read,
1606                 rfclen, remaining);
1607
1608         /* discard anything left over */
1609         if (server->total_read < rfclen)
1610                 return cifs_readv_discard(server, mid);
1611
1612         dequeue_mid(mid, false);
1613         return length;
1614 }
1615
1616 static void
1617 cifs_readv_complete(struct work_struct *work)
1618 {
1619         struct cifs_readdata *rdata = container_of(work,
1620                                                 struct cifs_readdata, work);
1621         struct page *page, *tpage;
1622
1623         list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1624                 list_del(&page->lru);
1625                 lru_cache_add_file(page);
1626
1627                 if (rdata->result == 0) {
1628                         kunmap(page);
1629                         flush_dcache_page(page);
1630                         SetPageUptodate(page);
1631                 }
1632
1633                 unlock_page(page);
1634
1635                 if (rdata->result == 0)
1636                         cifs_readpage_to_fscache(rdata->mapping->host, page);
1637
1638                 page_cache_release(page);
1639         }
1640         cifs_readdata_free(rdata);
1641 }
1642
1643 static void
1644 cifs_readv_callback(struct mid_q_entry *mid)
1645 {
1646         struct cifs_readdata *rdata = mid->callback_data;
1647         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1648         struct TCP_Server_Info *server = tcon->ses->server;
1649
1650         cFYI(1, "%s: mid=%u state=%d result=%d bytes=%u", __func__,
1651                 mid->mid, mid->midState, rdata->result, rdata->bytes);
1652
1653         switch (mid->midState) {
1654         case MID_RESPONSE_RECEIVED:
1655                 /* result already set, check signature */
1656                 if (server->sec_mode &
1657                     (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1658                         if (cifs_verify_signature(rdata->iov, rdata->nr_iov,
1659                                           server, mid->sequence_number + 1))
1660                                 cERROR(1, "Unexpected SMB signature");
1661                 }
1662                 /* FIXME: should this be counted toward the initiating task? */
1663                 task_io_account_read(rdata->bytes);
1664                 cifs_stats_bytes_read(tcon, rdata->bytes);
1665                 break;
1666         case MID_REQUEST_SUBMITTED:
1667         case MID_RETRY_NEEDED:
1668                 rdata->result = -EAGAIN;
1669                 break;
1670         default:
1671                 rdata->result = -EIO;
1672         }
1673
1674         queue_work(system_nrt_wq, &rdata->work);
1675         DeleteMidQEntry(mid);
1676         cifs_add_credits(server, 1);
1677 }
1678
1679 /* cifs_async_readv - send an async write, and set up mid to handle result */
1680 int
1681 cifs_async_readv(struct cifs_readdata *rdata)
1682 {
1683         int rc;
1684         READ_REQ *smb = NULL;
1685         int wct;
1686         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1687
1688         cFYI(1, "%s: offset=%llu bytes=%u", __func__,
1689                 rdata->offset, rdata->bytes);
1690
1691         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1692                 wct = 12;
1693         else {
1694                 wct = 10; /* old style read */
1695                 if ((rdata->offset >> 32) > 0)  {
1696                         /* can not handle this big offset for old */
1697                         return -EIO;
1698                 }
1699         }
1700
1701         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1702         if (rc)
1703                 return rc;
1704
1705         smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1706         smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1707
1708         smb->AndXCommand = 0xFF;        /* none */
1709         smb->Fid = rdata->cfile->netfid;
1710         smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1711         if (wct == 12)
1712                 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1713         smb->Remaining = 0;
1714         smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1715         smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1716         if (wct == 12)
1717                 smb->ByteCount = 0;
1718         else {
1719                 /* old style read */
1720                 struct smb_com_readx_req *smbr =
1721                         (struct smb_com_readx_req *)smb;
1722                 smbr->ByteCount = 0;
1723         }
1724
1725         /* 4 for RFC1001 length + 1 for BCC */
1726         rdata->iov[0].iov_base = smb;
1727         rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1728
1729         rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
1730                              cifs_readv_receive, cifs_readv_callback,
1731                              rdata, false);
1732
1733         if (rc == 0)
1734                 cifs_stats_inc(&tcon->num_reads);
1735
1736         cifs_small_buf_release(smb);
1737         return rc;
1738 }
1739
1740 int
1741 CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
1742             char **buf, int *pbuf_type)
1743 {
1744         int rc = -EACCES;
1745         READ_REQ *pSMB = NULL;
1746         READ_RSP *pSMBr = NULL;
1747         char *pReadData = NULL;
1748         int wct;
1749         int resp_buf_type = 0;
1750         struct kvec iov[1];
1751         __u32 pid = io_parms->pid;
1752         __u16 netfid = io_parms->netfid;
1753         __u64 offset = io_parms->offset;
1754         struct cifs_tcon *tcon = io_parms->tcon;
1755         unsigned int count = io_parms->length;
1756
1757         cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1758         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1759                 wct = 12;
1760         else {
1761                 wct = 10; /* old style read */
1762                 if ((offset >> 32) > 0)  {
1763                         /* can not handle this big offset for old */
1764                         return -EIO;
1765                 }
1766         }
1767
1768         *nbytes = 0;
1769         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1770         if (rc)
1771                 return rc;
1772
1773         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1774         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1775
1776         /* tcon and ses pointer are checked in smb_init */
1777         if (tcon->ses->server == NULL)
1778                 return -ECONNABORTED;
1779
1780         pSMB->AndXCommand = 0xFF;       /* none */
1781         pSMB->Fid = netfid;
1782         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1783         if (wct == 12)
1784                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1785
1786         pSMB->Remaining = 0;
1787         pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1788         pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1789         if (wct == 12)
1790                 pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1791         else {
1792                 /* old style read */
1793                 struct smb_com_readx_req *pSMBW =
1794                         (struct smb_com_readx_req *)pSMB;
1795                 pSMBW->ByteCount = 0;
1796         }
1797
1798         iov[0].iov_base = (char *)pSMB;
1799         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1800         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1801                          &resp_buf_type, CIFS_LOG_ERROR);
1802         cifs_stats_inc(&tcon->num_reads);
1803         pSMBr = (READ_RSP *)iov[0].iov_base;
1804         if (rc) {
1805                 cERROR(1, "Send error in read = %d", rc);
1806         } else {
1807                 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1808                 data_length = data_length << 16;
1809                 data_length += le16_to_cpu(pSMBr->DataLength);
1810                 *nbytes = data_length;
1811
1812                 /*check that DataLength would not go beyond end of SMB */
1813                 if ((data_length > CIFSMaxBufSize)
1814                                 || (data_length > count)) {
1815                         cFYI(1, "bad length %d for count %d",
1816                                  data_length, count);
1817                         rc = -EIO;
1818                         *nbytes = 0;
1819                 } else {
1820                         pReadData = (char *) (&pSMBr->hdr.Protocol) +
1821                                         le16_to_cpu(pSMBr->DataOffset);
1822 /*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
1823                                 cERROR(1, "Faulting on read rc = %d",rc);
1824                                 rc = -EFAULT;
1825                         }*/ /* can not use copy_to_user when using page cache*/
1826                         if (*buf)
1827                                 memcpy(*buf, pReadData, data_length);
1828                 }
1829         }
1830
1831 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1832         if (*buf) {
1833                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1834                         cifs_small_buf_release(iov[0].iov_base);
1835                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1836                         cifs_buf_release(iov[0].iov_base);
1837         } else if (resp_buf_type != CIFS_NO_BUFFER) {
1838                 /* return buffer to caller to free */
1839                 *buf = iov[0].iov_base;
1840                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1841                         *pbuf_type = CIFS_SMALL_BUFFER;
1842                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1843                         *pbuf_type = CIFS_LARGE_BUFFER;
1844         } /* else no valid buffer on return - leave as null */
1845
1846         /* Note: On -EAGAIN error only caller can retry on handle based calls
1847                 since file handle passed in no longer valid */
1848         return rc;
1849 }
1850
1851
1852 int
1853 CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
1854              unsigned int *nbytes, const char *buf,
1855              const char __user *ubuf, const int long_op)
1856 {
1857         int rc = -EACCES;
1858         WRITE_REQ *pSMB = NULL;
1859         WRITE_RSP *pSMBr = NULL;
1860         int bytes_returned, wct;
1861         __u32 bytes_sent;
1862         __u16 byte_count;
1863         __u32 pid = io_parms->pid;
1864         __u16 netfid = io_parms->netfid;
1865         __u64 offset = io_parms->offset;
1866         struct cifs_tcon *tcon = io_parms->tcon;
1867         unsigned int count = io_parms->length;
1868
1869         *nbytes = 0;
1870
1871         /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1872         if (tcon->ses == NULL)
1873                 return -ECONNABORTED;
1874
1875         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1876                 wct = 14;
1877         else {
1878                 wct = 12;
1879                 if ((offset >> 32) > 0) {
1880                         /* can not handle big offset for old srv */
1881                         return -EIO;
1882                 }
1883         }
1884
1885         rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1886                       (void **) &pSMBr);
1887         if (rc)
1888                 return rc;
1889
1890         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1891         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1892
1893         /* tcon and ses pointer are checked in smb_init */
1894         if (tcon->ses->server == NULL)
1895                 return -ECONNABORTED;
1896
1897         pSMB->AndXCommand = 0xFF;       /* none */
1898         pSMB->Fid = netfid;
1899         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1900         if (wct == 14)
1901                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1902
1903         pSMB->Reserved = 0xFFFFFFFF;
1904         pSMB->WriteMode = 0;
1905         pSMB->Remaining = 0;
1906
1907         /* Can increase buffer size if buffer is big enough in some cases ie we
1908         can send more if LARGE_WRITE_X capability returned by the server and if
1909         our buffer is big enough or if we convert to iovecs on socket writes
1910         and eliminate the copy to the CIFS buffer */
1911         if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1912                 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1913         } else {
1914                 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1915                          & ~0xFF;
1916         }
1917
1918         if (bytes_sent > count)
1919                 bytes_sent = count;
1920         pSMB->DataOffset =
1921                 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1922         if (buf)
1923                 memcpy(pSMB->Data, buf, bytes_sent);
1924         else if (ubuf) {
1925                 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1926                         cifs_buf_release(pSMB);
1927                         return -EFAULT;
1928                 }
1929         } else if (count != 0) {
1930                 /* No buffer */
1931                 cifs_buf_release(pSMB);
1932                 return -EINVAL;
1933         } /* else setting file size with write of zero bytes */
1934         if (wct == 14)
1935                 byte_count = bytes_sent + 1; /* pad */
1936         else /* wct == 12 */
1937                 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1938
1939         pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1940         pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1941         inc_rfc1001_len(pSMB, byte_count);
1942
1943         if (wct == 14)
1944                 pSMB->ByteCount = cpu_to_le16(byte_count);
1945         else { /* old style write has byte count 4 bytes earlier
1946                   so 4 bytes pad  */
1947                 struct smb_com_writex_req *pSMBW =
1948                         (struct smb_com_writex_req *)pSMB;
1949                 pSMBW->ByteCount = cpu_to_le16(byte_count);
1950         }
1951
1952         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1953                          (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1954         cifs_stats_inc(&tcon->num_writes);
1955         if (rc) {
1956                 cFYI(1, "Send error in write = %d", rc);
1957         } else {
1958                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1959                 *nbytes = (*nbytes) << 16;
1960                 *nbytes += le16_to_cpu(pSMBr->Count);
1961
1962                 /*
1963                  * Mask off high 16 bits when bytes written as returned by the
1964                  * server is greater than bytes requested by the client. Some
1965                  * OS/2 servers are known to set incorrect CountHigh values.
1966                  */
1967                 if (*nbytes > count)
1968                         *nbytes &= 0xFFFF;
1969         }
1970
1971         cifs_buf_release(pSMB);
1972
1973         /* Note: On -EAGAIN error only caller can retry on handle based calls
1974                 since file handle passed in no longer valid */
1975
1976         return rc;
1977 }
1978
1979 void
1980 cifs_writedata_release(struct kref *refcount)
1981 {
1982         struct cifs_writedata *wdata = container_of(refcount,
1983                                         struct cifs_writedata, refcount);
1984
1985         if (wdata->cfile)
1986                 cifsFileInfo_put(wdata->cfile);
1987
1988         kfree(wdata);
1989 }
1990
1991 /*
1992  * Write failed with a retryable error. Resend the write request. It's also
1993  * possible that the page was redirtied so re-clean the page.
1994  */
1995 static void
1996 cifs_writev_requeue(struct cifs_writedata *wdata)
1997 {
1998         int i, rc;
1999         struct inode *inode = wdata->cfile->dentry->d_inode;
2000
2001         for (i = 0; i < wdata->nr_pages; i++) {
2002                 lock_page(wdata->pages[i]);
2003                 clear_page_dirty_for_io(wdata->pages[i]);
2004         }
2005
2006         do {
2007                 rc = cifs_async_writev(wdata);
2008         } while (rc == -EAGAIN);
2009
2010         for (i = 0; i < wdata->nr_pages; i++) {
2011                 if (rc != 0)
2012                         SetPageError(wdata->pages[i]);
2013                 unlock_page(wdata->pages[i]);
2014         }
2015
2016         mapping_set_error(inode->i_mapping, rc);
2017         kref_put(&wdata->refcount, cifs_writedata_release);
2018 }
2019
2020 static void
2021 cifs_writev_complete(struct work_struct *work)
2022 {
2023         struct cifs_writedata *wdata = container_of(work,
2024                                                 struct cifs_writedata, work);
2025         struct inode *inode = wdata->cfile->dentry->d_inode;
2026         int i = 0;
2027
2028         if (wdata->result == 0) {
2029                 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2030                 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2031                                          wdata->bytes);
2032         } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2033                 return cifs_writev_requeue(wdata);
2034
2035         for (i = 0; i < wdata->nr_pages; i++) {
2036                 struct page *page = wdata->pages[i];
2037                 if (wdata->result == -EAGAIN)
2038                         __set_page_dirty_nobuffers(page);
2039                 else if (wdata->result < 0)
2040                         SetPageError(page);
2041                 end_page_writeback(page);
2042                 page_cache_release(page);
2043         }
2044         if (wdata->result != -EAGAIN)
2045                 mapping_set_error(inode->i_mapping, wdata->result);
2046         kref_put(&wdata->refcount, cifs_writedata_release);
2047 }
2048
2049 struct cifs_writedata *
2050 cifs_writedata_alloc(unsigned int nr_pages)
2051 {
2052         struct cifs_writedata *wdata;
2053
2054         /* this would overflow */
2055         if (nr_pages == 0) {
2056                 cERROR(1, "%s: called with nr_pages == 0!", __func__);
2057                 return NULL;
2058         }
2059
2060         /* writedata + number of page pointers */
2061         wdata = kzalloc(sizeof(*wdata) +
2062                         sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
2063         if (wdata != NULL) {
2064                 INIT_WORK(&wdata->work, cifs_writev_complete);
2065                 kref_init(&wdata->refcount);
2066         }
2067         return wdata;
2068 }
2069
2070 /*
2071  * Check the midState and signature on received buffer (if any), and queue the
2072  * workqueue completion task.
2073  */
2074 static void
2075 cifs_writev_callback(struct mid_q_entry *mid)
2076 {
2077         struct cifs_writedata *wdata = mid->callback_data;
2078         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2079         unsigned int written;
2080         WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2081
2082         switch (mid->midState) {
2083         case MID_RESPONSE_RECEIVED:
2084                 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2085                 if (wdata->result != 0)
2086                         break;
2087
2088                 written = le16_to_cpu(smb->CountHigh);
2089                 written <<= 16;
2090                 written += le16_to_cpu(smb->Count);
2091                 /*
2092                  * Mask off high 16 bits when bytes written as returned
2093                  * by the server is greater than bytes requested by the
2094                  * client. OS/2 servers are known to set incorrect
2095                  * CountHigh values.
2096                  */
2097                 if (written > wdata->bytes)
2098                         written &= 0xFFFF;
2099
2100                 if (written < wdata->bytes)
2101                         wdata->result = -ENOSPC;
2102                 else
2103                         wdata->bytes = written;
2104                 break;
2105         case MID_REQUEST_SUBMITTED:
2106         case MID_RETRY_NEEDED:
2107                 wdata->result = -EAGAIN;
2108                 break;
2109         default:
2110                 wdata->result = -EIO;
2111                 break;
2112         }
2113
2114         queue_work(system_nrt_wq, &wdata->work);
2115         DeleteMidQEntry(mid);
2116         cifs_add_credits(tcon->ses->server, 1);
2117 }
2118
2119 /* cifs_async_writev - send an async write, and set up mid to handle result */
2120 int
2121 cifs_async_writev(struct cifs_writedata *wdata)
2122 {
2123         int i, rc = -EACCES;
2124         WRITE_REQ *smb = NULL;
2125         int wct;
2126         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2127         struct inode *inode = wdata->cfile->dentry->d_inode;
2128         struct kvec *iov = NULL;
2129
2130         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2131                 wct = 14;
2132         } else {
2133                 wct = 12;
2134                 if (wdata->offset >> 32 > 0) {
2135                         /* can not handle big offset for old srv */
2136                         return -EIO;
2137                 }
2138         }
2139
2140         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2141         if (rc)
2142                 goto async_writev_out;
2143
2144         /* 1 iov per page + 1 for header */
2145         iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
2146         if (iov == NULL) {
2147                 rc = -ENOMEM;
2148                 goto async_writev_out;
2149         }
2150
2151         smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
2152         smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
2153
2154         smb->AndXCommand = 0xFF;        /* none */
2155         smb->Fid = wdata->cfile->netfid;
2156         smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2157         if (wct == 14)
2158                 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2159         smb->Reserved = 0xFFFFFFFF;
2160         smb->WriteMode = 0;
2161         smb->Remaining = 0;
2162
2163         smb->DataOffset =
2164             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2165
2166         /* 4 for RFC1001 length + 1 for BCC */
2167         iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2168         iov[0].iov_base = smb;
2169
2170         /* marshal up the pages into iov array */
2171         wdata->bytes = 0;
2172         for (i = 0; i < wdata->nr_pages; i++) {
2173                 iov[i + 1].iov_len = min(inode->i_size -
2174                                       page_offset(wdata->pages[i]),
2175                                         (loff_t)PAGE_CACHE_SIZE);
2176                 iov[i + 1].iov_base = kmap(wdata->pages[i]);
2177                 wdata->bytes += iov[i + 1].iov_len;
2178         }
2179
2180         cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2181
2182         smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2183         smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2184
2185         if (wct == 14) {
2186                 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2187                 put_bcc(wdata->bytes + 1, &smb->hdr);
2188         } else {
2189                 /* wct == 12 */
2190                 struct smb_com_writex_req *smbw =
2191                                 (struct smb_com_writex_req *)smb;
2192                 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2193                 put_bcc(wdata->bytes + 5, &smbw->hdr);
2194                 iov[0].iov_len += 4; /* pad bigger by four bytes */
2195         }
2196
2197         kref_get(&wdata->refcount);
2198         rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
2199                              NULL, cifs_writev_callback, wdata, false);
2200
2201         if (rc == 0)
2202                 cifs_stats_inc(&tcon->num_writes);
2203         else
2204                 kref_put(&wdata->refcount, cifs_writedata_release);
2205
2206         /* send is done, unmap pages */
2207         for (i = 0; i < wdata->nr_pages; i++)
2208                 kunmap(wdata->pages[i]);
2209
2210 async_writev_out:
2211         cifs_small_buf_release(smb);
2212         kfree(iov);
2213         return rc;
2214 }
2215
2216 int
2217 CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
2218               unsigned int *nbytes, struct kvec *iov, int n_vec,
2219               const int long_op)
2220 {
2221         int rc = -EACCES;
2222         WRITE_REQ *pSMB = NULL;
2223         int wct;
2224         int smb_hdr_len;
2225         int resp_buf_type = 0;
2226         __u32 pid = io_parms->pid;
2227         __u16 netfid = io_parms->netfid;
2228         __u64 offset = io_parms->offset;
2229         struct cifs_tcon *tcon = io_parms->tcon;
2230         unsigned int count = io_parms->length;
2231
2232         *nbytes = 0;
2233
2234         cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
2235
2236         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2237                 wct = 14;
2238         } else {
2239                 wct = 12;
2240                 if ((offset >> 32) > 0) {
2241                         /* can not handle big offset for old srv */
2242                         return -EIO;
2243                 }
2244         }
2245         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2246         if (rc)
2247                 return rc;
2248
2249         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2250         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2251
2252         /* tcon and ses pointer are checked in smb_init */
2253         if (tcon->ses->server == NULL)
2254                 return -ECONNABORTED;
2255
2256         pSMB->AndXCommand = 0xFF;       /* none */
2257         pSMB->Fid = netfid;
2258         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2259         if (wct == 14)
2260                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2261         pSMB->Reserved = 0xFFFFFFFF;
2262         pSMB->WriteMode = 0;
2263         pSMB->Remaining = 0;
2264
2265         pSMB->DataOffset =
2266             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2267
2268         pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2269         pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2270         /* header + 1 byte pad */
2271         smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2272         if (wct == 14)
2273                 inc_rfc1001_len(pSMB, count + 1);
2274         else /* wct == 12 */
2275                 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2276         if (wct == 14)
2277                 pSMB->ByteCount = cpu_to_le16(count + 1);
2278         else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2279                 struct smb_com_writex_req *pSMBW =
2280                                 (struct smb_com_writex_req *)pSMB;
2281                 pSMBW->ByteCount = cpu_to_le16(count + 5);
2282         }
2283         iov[0].iov_base = pSMB;
2284         if (wct == 14)
2285                 iov[0].iov_len = smb_hdr_len + 4;
2286         else /* wct == 12 pad bigger by four bytes */
2287                 iov[0].iov_len = smb_hdr_len + 8;
2288
2289
2290         rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
2291                           long_op);
2292         cifs_stats_inc(&tcon->num_writes);
2293         if (rc) {
2294                 cFYI(1, "Send error Write2 = %d", rc);
2295         } else if (resp_buf_type == 0) {
2296                 /* presumably this can not happen, but best to be safe */
2297                 rc = -EIO;
2298         } else {
2299                 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2300                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2301                 *nbytes = (*nbytes) << 16;
2302                 *nbytes += le16_to_cpu(pSMBr->Count);
2303
2304                 /*
2305                  * Mask off high 16 bits when bytes written as returned by the
2306                  * server is greater than bytes requested by the client. OS/2
2307                  * servers are known to set incorrect CountHigh values.
2308                  */
2309                 if (*nbytes > count)
2310                         *nbytes &= 0xFFFF;
2311         }
2312
2313 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2314         if (resp_buf_type == CIFS_SMALL_BUFFER)
2315                 cifs_small_buf_release(iov[0].iov_base);
2316         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2317                 cifs_buf_release(iov[0].iov_base);
2318
2319         /* Note: On -EAGAIN error only caller can retry on handle based calls
2320                 since file handle passed in no longer valid */
2321
2322         return rc;
2323 }
2324
2325 int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
2326                const __u8 lock_type, const __u32 num_unlock,
2327                const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2328 {
2329         int rc = 0;
2330         LOCK_REQ *pSMB = NULL;
2331         struct kvec iov[2];
2332         int resp_buf_type;
2333         __u16 count;
2334
2335         cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2336
2337         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2338         if (rc)
2339                 return rc;
2340
2341         pSMB->Timeout = 0;
2342         pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2343         pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2344         pSMB->LockType = lock_type;
2345         pSMB->AndXCommand = 0xFF; /* none */
2346         pSMB->Fid = netfid; /* netfid stays le */
2347
2348         count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2349         inc_rfc1001_len(pSMB, count);
2350         pSMB->ByteCount = cpu_to_le16(count);
2351
2352         iov[0].iov_base = (char *)pSMB;
2353         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2354                          (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2355         iov[1].iov_base = (char *)buf;
2356         iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2357
2358         cifs_stats_inc(&tcon->num_locks);
2359         rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2360         if (rc)
2361                 cFYI(1, "Send error in cifs_lockv = %d", rc);
2362
2363         return rc;
2364 }
2365
2366 int
2367 CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
2368             const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2369             const __u64 offset, const __u32 numUnlock,
2370             const __u32 numLock, const __u8 lockType,
2371             const bool waitFlag, const __u8 oplock_level)
2372 {
2373         int rc = 0;
2374         LOCK_REQ *pSMB = NULL;
2375 /*      LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2376         int bytes_returned;
2377         int timeout = 0;
2378         __u16 count;
2379
2380         cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2381         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2382
2383         if (rc)
2384                 return rc;
2385
2386         if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2387                 timeout = CIFS_ASYNC_OP; /* no response expected */
2388                 pSMB->Timeout = 0;
2389         } else if (waitFlag) {
2390                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2391                 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2392         } else {
2393                 pSMB->Timeout = 0;
2394         }
2395
2396         pSMB->NumberOfLocks = cpu_to_le16(numLock);
2397         pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2398         pSMB->LockType = lockType;
2399         pSMB->OplockLevel = oplock_level;
2400         pSMB->AndXCommand = 0xFF;       /* none */
2401         pSMB->Fid = smb_file_id; /* netfid stays le */
2402
2403         if ((numLock != 0) || (numUnlock != 0)) {
2404                 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2405                 /* BB where to store pid high? */
2406                 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2407                 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2408                 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2409                 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2410                 count = sizeof(LOCKING_ANDX_RANGE);
2411         } else {
2412                 /* oplock break */
2413                 count = 0;
2414         }
2415         inc_rfc1001_len(pSMB, count);
2416         pSMB->ByteCount = cpu_to_le16(count);
2417
2418         if (waitFlag) {
2419                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2420                         (struct smb_hdr *) pSMB, &bytes_returned);
2421                 cifs_small_buf_release(pSMB);
2422         } else {
2423                 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, timeout);
2424                 /* SMB buffer freed by function above */
2425         }
2426         cifs_stats_inc(&tcon->num_locks);
2427         if (rc)
2428                 cFYI(1, "Send error in Lock = %d", rc);
2429
2430         /* Note: On -EAGAIN error only caller can retry on handle based calls
2431         since file handle passed in no longer valid */
2432         return rc;
2433 }
2434
2435 int
2436 CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
2437                 const __u16 smb_file_id, const __u32 netpid, const int get_flag,
2438                 const __u64 len, struct file_lock *pLockData,
2439                 const __u16 lock_type, const bool waitFlag)
2440 {
2441         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2442         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2443         struct cifs_posix_lock *parm_data;
2444         int rc = 0;
2445         int timeout = 0;
2446         int bytes_returned = 0;
2447         int resp_buf_type = 0;
2448         __u16 params, param_offset, offset, byte_count, count;
2449         struct kvec iov[1];
2450
2451         cFYI(1, "Posix Lock");
2452
2453         if (pLockData == NULL)
2454                 return -EINVAL;
2455
2456         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2457
2458         if (rc)
2459                 return rc;
2460
2461         pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2462
2463         params = 6;
2464         pSMB->MaxSetupCount = 0;
2465         pSMB->Reserved = 0;
2466         pSMB->Flags = 0;
2467         pSMB->Reserved2 = 0;
2468         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2469         offset = param_offset + params;
2470
2471         count = sizeof(struct cifs_posix_lock);
2472         pSMB->MaxParameterCount = cpu_to_le16(2);
2473         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2474         pSMB->SetupCount = 1;
2475         pSMB->Reserved3 = 0;
2476         if (get_flag)
2477                 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2478         else
2479                 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2480         byte_count = 3 /* pad */  + params + count;
2481         pSMB->DataCount = cpu_to_le16(count);
2482         pSMB->ParameterCount = cpu_to_le16(params);
2483         pSMB->TotalDataCount = pSMB->DataCount;
2484         pSMB->TotalParameterCount = pSMB->ParameterCount;
2485         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2486         parm_data = (struct cifs_posix_lock *)
2487                         (((char *) &pSMB->hdr.Protocol) + offset);
2488
2489         parm_data->lock_type = cpu_to_le16(lock_type);
2490         if (waitFlag) {
2491                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2492                 parm_data->lock_flags = cpu_to_le16(1);
2493                 pSMB->Timeout = cpu_to_le32(-1);
2494         } else
2495                 pSMB->Timeout = 0;
2496
2497         parm_data->pid = cpu_to_le32(netpid);
2498         parm_data->start = cpu_to_le64(pLockData->fl_start);
2499         parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2500
2501         pSMB->DataOffset = cpu_to_le16(offset);
2502         pSMB->Fid = smb_file_id;
2503         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2504         pSMB->Reserved4 = 0;
2505         inc_rfc1001_len(pSMB, byte_count);
2506         pSMB->ByteCount = cpu_to_le16(byte_count);
2507         if (waitFlag) {
2508                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2509                         (struct smb_hdr *) pSMBr, &bytes_returned);
2510         } else {
2511                 iov[0].iov_base = (char *)pSMB;
2512                 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2513                 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2514                                 &resp_buf_type, timeout);
2515                 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2516                                 not try to free it twice below on exit */
2517                 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2518         }
2519
2520         if (rc) {
2521                 cFYI(1, "Send error in Posix Lock = %d", rc);
2522         } else if (get_flag) {
2523                 /* lock structure can be returned on get */
2524                 __u16 data_offset;
2525                 __u16 data_count;
2526                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2527
2528                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2529                         rc = -EIO;      /* bad smb */
2530                         goto plk_err_exit;
2531                 }
2532                 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2533                 data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2534                 if (data_count < sizeof(struct cifs_posix_lock)) {
2535                         rc = -EIO;
2536                         goto plk_err_exit;
2537                 }
2538                 parm_data = (struct cifs_posix_lock *)
2539                         ((char *)&pSMBr->hdr.Protocol + data_offset);
2540                 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2541                         pLockData->fl_type = F_UNLCK;
2542                 else {
2543                         if (parm_data->lock_type ==
2544                                         __constant_cpu_to_le16(CIFS_RDLCK))
2545                                 pLockData->fl_type = F_RDLCK;
2546                         else if (parm_data->lock_type ==
2547                                         __constant_cpu_to_le16(CIFS_WRLCK))
2548                                 pLockData->fl_type = F_WRLCK;
2549
2550                         pLockData->fl_start = le64_to_cpu(parm_data->start);
2551                         pLockData->fl_end = pLockData->fl_start +
2552                                         le64_to_cpu(parm_data->length) - 1;
2553                         pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2554                 }
2555         }
2556
2557 plk_err_exit:
2558         if (pSMB)
2559                 cifs_small_buf_release(pSMB);
2560
2561         if (resp_buf_type == CIFS_SMALL_BUFFER)
2562                 cifs_small_buf_release(iov[0].iov_base);
2563         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2564                 cifs_buf_release(iov[0].iov_base);
2565
2566         /* Note: On -EAGAIN error only caller can retry on handle based calls
2567            since file handle passed in no longer valid */
2568
2569         return rc;
2570 }
2571
2572
2573 int
2574 CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2575 {
2576         int rc = 0;
2577         CLOSE_REQ *pSMB = NULL;
2578         cFYI(1, "In CIFSSMBClose");
2579
2580 /* do not retry on dead session on close */
2581         rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2582         if (rc == -EAGAIN)
2583                 return 0;
2584         if (rc)
2585                 return rc;
2586
2587         pSMB->FileID = (__u16) smb_file_id;
2588         pSMB->LastWriteTime = 0xFFFFFFFF;
2589         pSMB->ByteCount = 0;
2590         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2591         cifs_stats_inc(&tcon->num_closes);
2592         if (rc) {
2593                 if (rc != -EINTR) {
2594                         /* EINTR is expected when user ctl-c to kill app */
2595                         cERROR(1, "Send error in Close = %d", rc);
2596                 }
2597         }
2598
2599         /* Since session is dead, file will be closed on server already */
2600         if (rc == -EAGAIN)
2601                 rc = 0;
2602
2603         return rc;
2604 }
2605
2606 int
2607 CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2608 {
2609         int rc = 0;
2610         FLUSH_REQ *pSMB = NULL;
2611         cFYI(1, "In CIFSSMBFlush");
2612
2613         rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2614         if (rc)
2615                 return rc;
2616
2617         pSMB->FileID = (__u16) smb_file_id;
2618         pSMB->ByteCount = 0;
2619         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2620         cifs_stats_inc(&tcon->num_flushes);
2621         if (rc)
2622                 cERROR(1, "Send error in Flush = %d", rc);
2623
2624         return rc;
2625 }
2626
2627 int
2628 CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
2629               const char *fromName, const char *toName,
2630               const struct nls_table *nls_codepage, int remap)
2631 {
2632         int rc = 0;
2633         RENAME_REQ *pSMB = NULL;
2634         RENAME_RSP *pSMBr = NULL;
2635         int bytes_returned;
2636         int name_len, name_len2;
2637         __u16 count;
2638
2639         cFYI(1, "In CIFSSMBRename");
2640 renameRetry:
2641         rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2642                       (void **) &pSMBr);
2643         if (rc)
2644                 return rc;
2645
2646         pSMB->BufferFormat = 0x04;
2647         pSMB->SearchAttributes =
2648             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2649                         ATTR_DIRECTORY);
2650
2651         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2652                 name_len =
2653                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
2654                                        PATH_MAX, nls_codepage, remap);
2655                 name_len++;     /* trailing null */
2656                 name_len *= 2;
2657                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2658         /* protocol requires ASCII signature byte on Unicode string */
2659                 pSMB->OldFileName[name_len + 1] = 0x00;
2660                 name_len2 =
2661                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2662                                        toName, PATH_MAX, nls_codepage, remap);
2663                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2664                 name_len2 *= 2; /* convert to bytes */
2665         } else {        /* BB improve the check for buffer overruns BB */
2666                 name_len = strnlen(fromName, PATH_MAX);
2667                 name_len++;     /* trailing null */
2668                 strncpy(pSMB->OldFileName, fromName, name_len);
2669                 name_len2 = strnlen(toName, PATH_MAX);
2670                 name_len2++;    /* trailing null */
2671                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2672                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2673                 name_len2++;    /* trailing null */
2674                 name_len2++;    /* signature byte */
2675         }
2676
2677         count = 1 /* 1st signature byte */  + name_len + name_len2;
2678         inc_rfc1001_len(pSMB, count);
2679         pSMB->ByteCount = cpu_to_le16(count);
2680
2681         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2682                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2683         cifs_stats_inc(&tcon->num_renames);
2684         if (rc)
2685                 cFYI(1, "Send error in rename = %d", rc);
2686
2687         cifs_buf_release(pSMB);
2688
2689         if (rc == -EAGAIN)
2690                 goto renameRetry;
2691
2692         return rc;
2693 }
2694
2695 int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
2696                 int netfid, const char *target_name,
2697                 const struct nls_table *nls_codepage, int remap)
2698 {
2699         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2700         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2701         struct set_file_rename *rename_info;
2702         char *data_offset;
2703         char dummy_string[30];
2704         int rc = 0;
2705         int bytes_returned = 0;
2706         int len_of_str;
2707         __u16 params, param_offset, offset, count, byte_count;
2708
2709         cFYI(1, "Rename to File by handle");
2710         rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2711                         (void **) &pSMBr);
2712         if (rc)
2713                 return rc;
2714
2715         params = 6;
2716         pSMB->MaxSetupCount = 0;
2717         pSMB->Reserved = 0;
2718         pSMB->Flags = 0;
2719         pSMB->Timeout = 0;
2720         pSMB->Reserved2 = 0;
2721         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2722         offset = param_offset + params;
2723
2724         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2725         rename_info = (struct set_file_rename *) data_offset;
2726         pSMB->MaxParameterCount = cpu_to_le16(2);
2727         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2728         pSMB->SetupCount = 1;
2729         pSMB->Reserved3 = 0;
2730         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2731         byte_count = 3 /* pad */  + params;
2732         pSMB->ParameterCount = cpu_to_le16(params);
2733         pSMB->TotalParameterCount = pSMB->ParameterCount;
2734         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2735         pSMB->DataOffset = cpu_to_le16(offset);
2736         /* construct random name ".cifs_tmp<inodenum><mid>" */
2737         rename_info->overwrite = cpu_to_le32(1);
2738         rename_info->root_fid  = 0;
2739         /* unicode only call */
2740         if (target_name == NULL) {
2741                 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2742                 len_of_str =
2743                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2744                                         dummy_string, 24, nls_codepage, remap);
2745         } else {
2746                 len_of_str =
2747                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2748                                         target_name, PATH_MAX, nls_codepage,
2749                                         remap);
2750         }
2751         rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2752         count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2753         byte_count += count;
2754         pSMB->DataCount = cpu_to_le16(count);
2755         pSMB->TotalDataCount = pSMB->DataCount;
2756         pSMB->Fid = netfid;
2757         pSMB->InformationLevel =
2758                 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2759         pSMB->Reserved4 = 0;
2760         inc_rfc1001_len(pSMB, byte_count);
2761         pSMB->ByteCount = cpu_to_le16(byte_count);
2762         rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2763                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2764         cifs_stats_inc(&pTcon->num_t2renames);
2765         if (rc)
2766                 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2767
2768         cifs_buf_release(pSMB);
2769
2770         /* Note: On -EAGAIN error only caller can retry on handle based calls
2771                 since file handle passed in no longer valid */
2772
2773         return rc;
2774 }
2775
2776 int
2777 CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
2778             const __u16 target_tid, const char *toName, const int flags,
2779             const struct nls_table *nls_codepage, int remap)
2780 {
2781         int rc = 0;
2782         COPY_REQ *pSMB = NULL;
2783         COPY_RSP *pSMBr = NULL;
2784         int bytes_returned;
2785         int name_len, name_len2;
2786         __u16 count;
2787
2788         cFYI(1, "In CIFSSMBCopy");
2789 copyRetry:
2790         rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2791                         (void **) &pSMBr);
2792         if (rc)
2793                 return rc;
2794
2795         pSMB->BufferFormat = 0x04;
2796         pSMB->Tid2 = target_tid;
2797
2798         pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2799
2800         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2801                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2802                                               fromName, PATH_MAX, nls_codepage,
2803                                               remap);
2804                 name_len++;     /* trailing null */
2805                 name_len *= 2;
2806                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2807                 /* protocol requires ASCII signature byte on Unicode string */
2808                 pSMB->OldFileName[name_len + 1] = 0x00;
2809                 name_len2 =
2810                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2811                                        toName, PATH_MAX, nls_codepage, remap);
2812                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2813                 name_len2 *= 2; /* convert to bytes */
2814         } else {        /* BB improve the check for buffer overruns BB */
2815                 name_len = strnlen(fromName, PATH_MAX);
2816                 name_len++;     /* trailing null */
2817                 strncpy(pSMB->OldFileName, fromName, name_len);
2818                 name_len2 = strnlen(toName, PATH_MAX);
2819                 name_len2++;    /* trailing null */
2820                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2821                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2822                 name_len2++;    /* trailing null */
2823                 name_len2++;    /* signature byte */
2824         }
2825
2826         count = 1 /* 1st signature byte */  + name_len + name_len2;
2827         inc_rfc1001_len(pSMB, count);
2828         pSMB->ByteCount = cpu_to_le16(count);
2829
2830         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2831                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2832         if (rc) {
2833                 cFYI(1, "Send error in copy = %d with %d files copied",
2834                         rc, le16_to_cpu(pSMBr->CopyCount));
2835         }
2836         cifs_buf_release(pSMB);
2837
2838         if (rc == -EAGAIN)
2839                 goto copyRetry;
2840
2841         return rc;
2842 }
2843
2844 int
2845 CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
2846                       const char *fromName, const char *toName,
2847                       const struct nls_table *nls_codepage)
2848 {
2849         TRANSACTION2_SPI_REQ *pSMB = NULL;
2850         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2851         char *data_offset;
2852         int name_len;
2853         int name_len_target;
2854         int rc = 0;
2855         int bytes_returned = 0;
2856         __u16 params, param_offset, offset, byte_count;
2857
2858         cFYI(1, "In Symlink Unix style");
2859 createSymLinkRetry:
2860         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2861                       (void **) &pSMBr);
2862         if (rc)
2863                 return rc;
2864
2865         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2866                 name_len =
2867                     cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2868                                     /* find define for this maxpathcomponent */
2869                                     PATH_MAX, nls_codepage);
2870                 name_len++;     /* trailing null */
2871                 name_len *= 2;
2872
2873         } else {        /* BB improve the check for buffer overruns BB */
2874                 name_len = strnlen(fromName, PATH_MAX);
2875                 name_len++;     /* trailing null */
2876                 strncpy(pSMB->FileName, fromName, name_len);
2877         }
2878         params = 6 + name_len;
2879         pSMB->MaxSetupCount = 0;
2880         pSMB->Reserved = 0;
2881         pSMB->Flags = 0;
2882         pSMB->Timeout = 0;
2883         pSMB->Reserved2 = 0;
2884         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2885                                 InformationLevel) - 4;
2886         offset = param_offset + params;
2887
2888         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2889         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2890                 name_len_target =
2891                     cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2892                                     /* find define for this maxpathcomponent */
2893                                     , nls_codepage);
2894                 name_len_target++;      /* trailing null */
2895                 name_len_target *= 2;
2896         } else {        /* BB improve the check for buffer overruns BB */
2897                 name_len_target = strnlen(toName, PATH_MAX);
2898                 name_len_target++;      /* trailing null */
2899                 strncpy(data_offset, toName, name_len_target);
2900         }
2901
2902         pSMB->MaxParameterCount = cpu_to_le16(2);
2903         /* BB find exact max on data count below from sess */
2904         pSMB->MaxDataCount = cpu_to_le16(1000);
2905         pSMB->SetupCount = 1;
2906         pSMB->Reserved3 = 0;
2907         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2908         byte_count = 3 /* pad */  + params + name_len_target;
2909         pSMB->DataCount = cpu_to_le16(name_len_target);
2910         pSMB->ParameterCount = cpu_to_le16(params);
2911         pSMB->TotalDataCount = pSMB->DataCount;
2912         pSMB->TotalParameterCount = pSMB->ParameterCount;
2913         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2914         pSMB->DataOffset = cpu_to_le16(offset);
2915         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2916         pSMB->Reserved4 = 0;
2917         inc_rfc1001_len(pSMB, byte_count);
2918         pSMB->ByteCount = cpu_to_le16(byte_count);
2919         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2920                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2921         cifs_stats_inc(&tcon->num_symlinks);
2922         if (rc)
2923                 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2924
2925         cifs_buf_release(pSMB);
2926
2927         if (rc == -EAGAIN)
2928                 goto createSymLinkRetry;
2929
2930         return rc;
2931 }
2932
2933 int
2934 CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
2935                        const char *fromName, const char *toName,
2936                        const struct nls_table *nls_codepage, int remap)
2937 {
2938         TRANSACTION2_SPI_REQ *pSMB = NULL;
2939         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2940         char *data_offset;
2941         int name_len;
2942         int name_len_target;
2943         int rc = 0;
2944         int bytes_returned = 0;
2945         __u16 params, param_offset, offset, byte_count;
2946
2947         cFYI(1, "In Create Hard link Unix style");
2948 createHardLinkRetry:
2949         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2950                       (void **) &pSMBr);
2951         if (rc)
2952                 return rc;
2953
2954         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2955                 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2956                                               PATH_MAX, nls_codepage, remap);
2957                 name_len++;     /* trailing null */
2958                 name_len *= 2;
2959
2960         } else {        /* BB improve the check for buffer overruns BB */
2961                 name_len = strnlen(toName, PATH_MAX);
2962                 name_len++;     /* trailing null */
2963                 strncpy(pSMB->FileName, toName, name_len);
2964         }
2965         params = 6 + name_len;
2966         pSMB->MaxSetupCount = 0;
2967         pSMB->Reserved = 0;
2968         pSMB->Flags = 0;
2969         pSMB->Timeout = 0;
2970         pSMB->Reserved2 = 0;
2971         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2972                                 InformationLevel) - 4;
2973         offset = param_offset + params;
2974
2975         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2976         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2977                 name_len_target =
2978                     cifsConvertToUTF16((__le16 *) data_offset, fromName,
2979                                        PATH_MAX, nls_codepage, remap);
2980                 name_len_target++;      /* trailing null */
2981                 name_len_target *= 2;
2982         } else {        /* BB improve the check for buffer overruns BB */
2983                 name_len_target = strnlen(fromName, PATH_MAX);
2984                 name_len_target++;      /* trailing null */
2985                 strncpy(data_offset, fromName, name_len_target);
2986         }
2987
2988         pSMB->MaxParameterCount = cpu_to_le16(2);
2989         /* BB find exact max on data count below from sess*/
2990         pSMB->MaxDataCount = cpu_to_le16(1000);
2991         pSMB->SetupCount = 1;
2992         pSMB->Reserved3 = 0;
2993         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2994         byte_count = 3 /* pad */  + params + name_len_target;
2995         pSMB->ParameterCount = cpu_to_le16(params);
2996         pSMB->TotalParameterCount = pSMB->ParameterCount;
2997         pSMB->DataCount = cpu_to_le16(name_len_target);
2998         pSMB->TotalDataCount = pSMB->DataCount;
2999         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3000         pSMB->DataOffset = cpu_to_le16(offset);
3001         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3002         pSMB->Reserved4 = 0;
3003         inc_rfc1001_len(pSMB, byte_count);
3004         pSMB->ByteCount = cpu_to_le16(byte_count);
3005         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3006                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3007         cifs_stats_inc(&tcon->num_hardlinks);
3008         if (rc)
3009                 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
3010
3011         cifs_buf_release(pSMB);
3012         if (rc == -EAGAIN)
3013                 goto createHardLinkRetry;
3014
3015         return rc;
3016 }
3017
3018 int
3019 CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
3020                    const char *fromName, const char *toName,
3021                    const struct nls_table *nls_codepage, int remap)
3022 {
3023         int rc = 0;
3024         NT_RENAME_REQ *pSMB = NULL;
3025         RENAME_RSP *pSMBr = NULL;
3026         int bytes_returned;
3027         int name_len, name_len2;
3028         __u16 count;
3029
3030         cFYI(1, "In CIFSCreateHardLink");
3031 winCreateHardLinkRetry:
3032
3033         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3034                       (void **) &pSMBr);
3035         if (rc)
3036                 return rc;
3037
3038         pSMB->SearchAttributes =
3039             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3040                         ATTR_DIRECTORY);
3041         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3042         pSMB->ClusterCount = 0;
3043
3044         pSMB->BufferFormat = 0x04;
3045
3046         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3047                 name_len =
3048                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
3049                                        PATH_MAX, nls_codepage, remap);
3050                 name_len++;     /* trailing null */
3051                 name_len *= 2;
3052
3053                 /* protocol specifies ASCII buffer format (0x04) for unicode */
3054                 pSMB->OldFileName[name_len] = 0x04;
3055                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3056                 name_len2 =
3057                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3058                                        toName, PATH_MAX, nls_codepage, remap);
3059                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
3060                 name_len2 *= 2; /* convert to bytes */
3061         } else {        /* BB improve the check for buffer overruns BB */
3062                 name_len = strnlen(fromName, PATH_MAX);
3063                 name_len++;     /* trailing null */
3064                 strncpy(pSMB->OldFileName, fromName, name_len);
3065                 name_len2 = strnlen(toName, PATH_MAX);
3066                 name_len2++;    /* trailing null */
3067                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
3068                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
3069                 name_len2++;    /* trailing null */
3070                 name_len2++;    /* signature byte */
3071         }
3072
3073         count = 1 /* string type byte */  + name_len + name_len2;
3074         inc_rfc1001_len(pSMB, count);
3075         pSMB->ByteCount = cpu_to_le16(count);
3076
3077         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3078                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3079         cifs_stats_inc(&tcon->num_hardlinks);
3080         if (rc)
3081                 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
3082
3083         cifs_buf_release(pSMB);
3084         if (rc == -EAGAIN)
3085                 goto winCreateHardLinkRetry;
3086
3087         return rc;
3088 }
3089
3090 int
3091 CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
3092                         const unsigned char *searchName, char **symlinkinfo,
3093                         const struct nls_table *nls_codepage)
3094 {
3095 /* SMB_QUERY_FILE_UNIX_LINK */
3096         TRANSACTION2_QPI_REQ *pSMB = NULL;
3097         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3098         int rc = 0;
3099         int bytes_returned;
3100         int name_len;
3101         __u16 params, byte_count;
3102         char *data_start;
3103
3104         cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
3105
3106 querySymLinkRetry:
3107         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3108                       (void **) &pSMBr);
3109         if (rc)
3110                 return rc;
3111
3112         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3113                 name_len =
3114                         cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3115                                         PATH_MAX, nls_codepage);
3116                 name_len++;     /* trailing null */
3117                 name_len *= 2;
3118         } else {        /* BB improve the check for buffer overruns BB */
3119                 name_len = strnlen(searchName, PATH_MAX);
3120                 name_len++;     /* trailing null */
3121                 strncpy(pSMB->FileName, searchName, name_len);
3122         }
3123
3124         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3125         pSMB->TotalDataCount = 0;
3126         pSMB->MaxParameterCount = cpu_to_le16(2);
3127         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3128         pSMB->MaxSetupCount = 0;
3129         pSMB->Reserved = 0;
3130         pSMB->Flags = 0;
3131         pSMB->Timeout = 0;
3132         pSMB->Reserved2 = 0;
3133         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3134         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3135         pSMB->DataCount = 0;
3136         pSMB->DataOffset = 0;
3137         pSMB->SetupCount = 1;
3138         pSMB->Reserved3 = 0;
3139         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3140         byte_count = params + 1 /* pad */ ;
3141         pSMB->TotalParameterCount = cpu_to_le16(params);
3142         pSMB->ParameterCount = pSMB->TotalParameterCount;
3143         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3144         pSMB->Reserved4 = 0;
3145         inc_rfc1001_len(pSMB, byte_count);
3146         pSMB->ByteCount = cpu_to_le16(byte_count);
3147
3148         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3149                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3150         if (rc) {
3151                 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3152         } else {
3153                 /* decode response */
3154
3155                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3156                 /* BB also check enough total bytes returned */
3157                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3158                         rc = -EIO;
3159                 else {
3160                         bool is_unicode;
3161                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3162
3163                         data_start = ((char *) &pSMBr->hdr.Protocol) +
3164                                            le16_to_cpu(pSMBr->t2.DataOffset);
3165
3166                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3167                                 is_unicode = true;
3168                         else
3169                                 is_unicode = false;
3170
3171                         /* BB FIXME investigate remapping reserved chars here */
3172                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
3173                                         count, is_unicode, nls_codepage);
3174                         if (!*symlinkinfo)
3175                                 rc = -ENOMEM;
3176                 }
3177         }
3178         cifs_buf_release(pSMB);
3179         if (rc == -EAGAIN)
3180                 goto querySymLinkRetry;
3181         return rc;
3182 }
3183
3184 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3185 /*
3186  *      Recent Windows versions now create symlinks more frequently
3187  *      and they use the "reparse point" mechanism below.  We can of course
3188  *      do symlinks nicely to Samba and other servers which support the
3189  *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3190  *      "MF" symlinks optionally, but for recent Windows we really need to
3191  *      reenable the code below and fix the cifs_symlink callers to handle this.
3192  *      In the interim this code has been moved to its own config option so
3193  *      it is not compiled in by default until callers fixed up and more tested.
3194  */
3195 int
3196 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
3197                         const unsigned char *searchName,
3198                         char *symlinkinfo, const int buflen, __u16 fid,
3199                         const struct nls_table *nls_codepage)
3200 {
3201         int rc = 0;
3202         int bytes_returned;
3203         struct smb_com_transaction_ioctl_req *pSMB;
3204         struct smb_com_transaction_ioctl_rsp *pSMBr;
3205
3206         cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3207         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3208                       (void **) &pSMBr);
3209         if (rc)
3210                 return rc;
3211
3212         pSMB->TotalParameterCount = 0 ;
3213         pSMB->TotalDataCount = 0;
3214         pSMB->MaxParameterCount = cpu_to_le32(2);
3215         /* BB find exact data count max from sess structure BB */
3216         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3217         pSMB->MaxSetupCount = 4;
3218         pSMB->Reserved = 0;
3219         pSMB->ParameterOffset = 0;
3220         pSMB->DataCount = 0;
3221         pSMB->DataOffset = 0;
3222         pSMB->SetupCount = 4;
3223         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3224         pSMB->ParameterCount = pSMB->TotalParameterCount;
3225         pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3226         pSMB->IsFsctl = 1; /* FSCTL */
3227         pSMB->IsRootFlag = 0;
3228         pSMB->Fid = fid; /* file handle always le */
3229         pSMB->ByteCount = 0;
3230
3231         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3232                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3233         if (rc) {
3234                 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3235         } else {                /* decode response */
3236                 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3237                 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3238                 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3239                         /* BB also check enough total bytes returned */
3240                         rc = -EIO;      /* bad smb */
3241                         goto qreparse_out;
3242                 }
3243                 if (data_count && (data_count < 2048)) {
3244                         char *end_of_smb = 2 /* sizeof byte count */ +
3245                                get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3246
3247                         struct reparse_data *reparse_buf =
3248                                                 (struct reparse_data *)
3249                                                 ((char *)&pSMBr->hdr.Protocol
3250                                                                  + data_offset);
3251                         if ((char *)reparse_buf >= end_of_smb) {
3252                                 rc = -EIO;
3253                                 goto qreparse_out;
3254                         }
3255                         if ((reparse_buf->LinkNamesBuf +
3256                                 reparse_buf->TargetNameOffset +
3257                                 reparse_buf->TargetNameLen) > end_of_smb) {
3258                                 cFYI(1, "reparse buf beyond SMB");
3259                                 rc = -EIO;
3260                                 goto qreparse_out;
3261                         }
3262
3263                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3264                                 cifs_from_ucs2(symlinkinfo, (__le16 *)
3265                                                 (reparse_buf->LinkNamesBuf +
3266                                                 reparse_buf->TargetNameOffset),
3267                                                 buflen,
3268                                                 reparse_buf->TargetNameLen,
3269                                                 nls_codepage, 0);
3270                         } else { /* ASCII names */
3271                                 strncpy(symlinkinfo,
3272                                         reparse_buf->LinkNamesBuf +
3273                                         reparse_buf->TargetNameOffset,
3274                                         min_t(const int, buflen,
3275                                            reparse_buf->TargetNameLen));
3276                         }
3277                 } else {
3278                         rc = -EIO;
3279                         cFYI(1, "Invalid return data count on "
3280                                  "get reparse info ioctl");
3281                 }
3282                 symlinkinfo[buflen] = 0; /* just in case so the caller
3283                                         does not go off the end of the buffer */
3284                 cFYI(1, "readlink result - %s", symlinkinfo);
3285         }
3286
3287 qreparse_out:
3288         cifs_buf_release(pSMB);
3289
3290         /* Note: On -EAGAIN error only caller can retry on handle based calls
3291                 since file handle passed in no longer valid */
3292
3293         return rc;
3294 }
3295 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3296
3297 #ifdef CONFIG_CIFS_POSIX
3298
3299 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3300 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3301                              struct cifs_posix_ace *cifs_ace)
3302 {
3303         /* u8 cifs fields do not need le conversion */
3304         ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3305         ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3306         ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3307         /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3308
3309         return;
3310 }
3311
3312 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3313 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3314                                const int acl_type, const int size_of_data_area)
3315 {
3316         int size =  0;
3317         int i;
3318         __u16 count;
3319         struct cifs_posix_ace *pACE;
3320         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3321         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3322
3323         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3324                 return -EOPNOTSUPP;
3325
3326         if (acl_type & ACL_TYPE_ACCESS) {
3327                 count = le16_to_cpu(cifs_acl->access_entry_count);
3328                 pACE = &cifs_acl->ace_array[0];
3329                 size = sizeof(struct cifs_posix_acl);
3330                 size += sizeof(struct cifs_posix_ace) * count;
3331                 /* check if we would go beyond end of SMB */
3332                 if (size_of_data_area < size) {
3333                         cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3334                                 size_of_data_area, size);
3335                         return -EINVAL;
3336                 }
3337         } else if (acl_type & ACL_TYPE_DEFAULT) {
3338                 count = le16_to_cpu(cifs_acl->access_entry_count);
3339                 size = sizeof(struct cifs_posix_acl);
3340                 size += sizeof(struct cifs_posix_ace) * count;
3341 /* skip past access ACEs to get to default ACEs */
3342                 pACE = &cifs_acl->ace_array[count];
3343                 count = le16_to_cpu(cifs_acl->default_entry_count);
3344                 size += sizeof(struct cifs_posix_ace) * count;
3345                 /* check if we would go beyond end of SMB */
3346                 if (size_of_data_area < size)
3347                         return -EINVAL;
3348         } else {
3349                 /* illegal type */
3350                 return -EINVAL;
3351         }
3352
3353         size = posix_acl_xattr_size(count);
3354         if ((buflen == 0) || (local_acl == NULL)) {
3355                 /* used to query ACL EA size */
3356         } else if (size > buflen) {
3357                 return -ERANGE;
3358         } else /* buffer big enough */ {
3359                 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3360                 for (i = 0; i < count ; i++) {
3361                         cifs_convert_ace(&local_acl->a_entries[i], pACE);
3362                         pACE++;
3363                 }
3364         }
3365         return size;
3366 }
3367
3368 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3369                                      const posix_acl_xattr_entry *local_ace)
3370 {
3371         __u16 rc = 0; /* 0 = ACL converted ok */
3372
3373         cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3374         cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
3375         /* BB is there a better way to handle the large uid? */
3376         if (local_ace->e_id == cpu_to_le32(-1)) {
3377         /* Probably no need to le convert -1 on any arch but can not hurt */
3378                 cifs_ace->cifs_uid = cpu_to_le64(-1);
3379         } else
3380                 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3381         /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3382         return rc;
3383 }
3384
3385 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3386 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3387                                const int buflen, const int acl_type)
3388 {
3389         __u16 rc = 0;
3390         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3391         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3392         int count;
3393         int i;
3394
3395         if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3396                 return 0;
3397
3398         count = posix_acl_xattr_count((size_t)buflen);
3399         cFYI(1, "setting acl with %d entries from buf of length %d and "
3400                 "version of %d",
3401                 count, buflen, le32_to_cpu(local_acl->a_version));
3402         if (le32_to_cpu(local_acl->a_version) != 2) {
3403                 cFYI(1, "unknown POSIX ACL version %d",
3404                      le32_to_cpu(local_acl->a_version));
3405                 return 0;
3406         }
3407         cifs_acl->version = cpu_to_le16(1);
3408         if (acl_type == ACL_TYPE_ACCESS)
3409                 cifs_acl->access_entry_count = cpu_to_le16(count);
3410         else if (acl_type == ACL_TYPE_DEFAULT)
3411                 cifs_acl->default_entry_count = cpu_to_le16(count);
3412         else {
3413                 cFYI(1, "unknown ACL type %d", acl_type);
3414                 return 0;
3415         }
3416         for (i = 0; i < count; i++) {
3417                 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3418                                         &local_acl->a_entries[i]);
3419                 if (rc != 0) {
3420                         /* ACE not converted */
3421                         break;
3422                 }
3423         }
3424         if (rc == 0) {
3425                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3426                 rc += sizeof(struct cifs_posix_acl);
3427                 /* BB add check to make sure ACL does not overflow SMB */
3428         }
3429         return rc;
3430 }
3431
3432 int
3433 CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
3434                    const unsigned char *searchName,
3435                    char *acl_inf, const int buflen, const int acl_type,
3436                    const struct nls_table *nls_codepage, int remap)
3437 {
3438 /* SMB_QUERY_POSIX_ACL */
3439         TRANSACTION2_QPI_REQ *pSMB = NULL;
3440         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3441         int rc = 0;
3442         int bytes_returned;
3443         int name_len;
3444         __u16 params, byte_count;
3445
3446         cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3447
3448 queryAclRetry:
3449         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3450                 (void **) &pSMBr);
3451         if (rc)
3452                 return rc;
3453
3454         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3455                 name_len =
3456                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3457                                            searchName, PATH_MAX, nls_codepage,
3458                                            remap);
3459                 name_len++;     /* trailing null */
3460                 name_len *= 2;
3461                 pSMB->FileName[name_len] = 0;
3462                 pSMB->FileName[name_len+1] = 0;
3463         } else {        /* BB improve the check for buffer overruns BB */
3464                 name_len = strnlen(searchName, PATH_MAX);
3465                 name_len++;     /* trailing null */
3466                 strncpy(pSMB->FileName, searchName, name_len);
3467         }
3468
3469         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3470         pSMB->TotalDataCount = 0;
3471         pSMB->MaxParameterCount = cpu_to_le16(2);
3472         /* BB find exact max data count below from sess structure BB */
3473         pSMB->MaxDataCount = cpu_to_le16(4000);
3474         pSMB->MaxSetupCount = 0;
3475         pSMB->Reserved = 0;
3476         pSMB->Flags = 0;
3477         pSMB->Timeout = 0;
3478         pSMB->Reserved2 = 0;
3479         pSMB->ParameterOffset = cpu_to_le16(
3480                 offsetof(struct smb_com_transaction2_qpi_req,
3481                          InformationLevel) - 4);
3482         pSMB->DataCount = 0;
3483         pSMB->DataOffset = 0;
3484         pSMB->SetupCount = 1;
3485         pSMB->Reserved3 = 0;
3486         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3487         byte_count = params + 1 /* pad */ ;
3488         pSMB->TotalParameterCount = cpu_to_le16(params);
3489         pSMB->ParameterCount = pSMB->TotalParameterCount;
3490         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3491         pSMB->Reserved4 = 0;
3492         inc_rfc1001_len(pSMB, byte_count);
3493         pSMB->ByteCount = cpu_to_le16(byte_count);
3494
3495         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3496                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3497         cifs_stats_inc(&tcon->num_acl_get);
3498         if (rc) {
3499                 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3500         } else {
3501                 /* decode response */
3502
3503                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3504                 /* BB also check enough total bytes returned */
3505                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3506                         rc = -EIO;      /* bad smb */
3507                 else {
3508                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3509                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3510                         rc = cifs_copy_posix_acl(acl_inf,
3511                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3512                                 buflen, acl_type, count);
3513                 }
3514         }
3515         cifs_buf_release(pSMB);
3516         if (rc == -EAGAIN)
3517                 goto queryAclRetry;
3518         return rc;
3519 }
3520
3521 int
3522 CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
3523                    const unsigned char *fileName,
3524                    const char *local_acl, const int buflen,
3525                    const int acl_type,
3526                    const struct nls_table *nls_codepage, int remap)
3527 {
3528         struct smb_com_transaction2_spi_req *pSMB = NULL;
3529         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3530         char *parm_data;
3531         int name_len;
3532         int rc = 0;
3533         int bytes_returned = 0;
3534         __u16 params, byte_count, data_count, param_offset, offset;
3535
3536         cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3537 setAclRetry:
3538         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3539                       (void **) &pSMBr);
3540         if (rc)
3541                 return rc;
3542         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3543                 name_len =
3544                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3545                                            PATH_MAX, nls_codepage, remap);
3546                 name_len++;     /* trailing null */
3547                 name_len *= 2;
3548         } else {        /* BB improve the check for buffer overruns BB */
3549                 name_len = strnlen(fileName, PATH_MAX);
3550                 name_len++;     /* trailing null */
3551                 strncpy(pSMB->FileName, fileName, name_len);
3552         }
3553         params = 6 + name_len;
3554         pSMB->MaxParameterCount = cpu_to_le16(2);
3555         /* BB find max SMB size from sess */
3556         pSMB->MaxDataCount = cpu_to_le16(1000);
3557         pSMB->MaxSetupCount = 0;
3558         pSMB->Reserved = 0;
3559         pSMB->Flags = 0;
3560         pSMB->Timeout = 0;
3561         pSMB->Reserved2 = 0;
3562         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3563                                 InformationLevel) - 4;
3564         offset = param_offset + params;
3565         parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3566         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3567
3568         /* convert to on the wire format for POSIX ACL */
3569         data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3570
3571         if (data_count == 0) {
3572                 rc = -EOPNOTSUPP;
3573                 goto setACLerrorExit;
3574         }
3575         pSMB->DataOffset = cpu_to_le16(offset);
3576         pSMB->SetupCount = 1;
3577         pSMB->Reserved3 = 0;
3578         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3579         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3580         byte_count = 3 /* pad */  + params + data_count;
3581         pSMB->DataCount = cpu_to_le16(data_count);
3582         pSMB->TotalDataCount = pSMB->DataCount;
3583         pSMB->ParameterCount = cpu_to_le16(params);
3584         pSMB->TotalParameterCount = pSMB->ParameterCount;
3585         pSMB->Reserved4 = 0;
3586         inc_rfc1001_len(pSMB, byte_count);
3587         pSMB->ByteCount = cpu_to_le16(byte_count);
3588         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3589                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3590         if (rc)
3591                 cFYI(1, "Set POSIX ACL returned %d", rc);
3592
3593 setACLerrorExit:
3594         cifs_buf_release(pSMB);
3595         if (rc == -EAGAIN)
3596                 goto setAclRetry;
3597         return rc;
3598 }
3599
3600 /* BB fix tabs in this function FIXME BB */
3601 int
3602 CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
3603                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3604 {
3605         int rc = 0;
3606         struct smb_t2_qfi_req *pSMB = NULL;
3607         struct smb_t2_qfi_rsp *pSMBr = NULL;
3608         int bytes_returned;
3609         __u16 params, byte_count;
3610
3611         cFYI(1, "In GetExtAttr");
3612         if (tcon == NULL)
3613                 return -ENODEV;
3614
3615 GetExtAttrRetry:
3616         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3617                         (void **) &pSMBr);
3618         if (rc)
3619                 return rc;
3620
3621         params = 2 /* level */ + 2 /* fid */;
3622         pSMB->t2.TotalDataCount = 0;
3623         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3624         /* BB find exact max data count below from sess structure BB */
3625         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3626         pSMB->t2.MaxSetupCount = 0;
3627         pSMB->t2.Reserved = 0;
3628         pSMB->t2.Flags = 0;
3629         pSMB->t2.Timeout = 0;
3630         pSMB->t2.Reserved2 = 0;
3631         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3632                                                Fid) - 4);
3633         pSMB->t2.DataCount = 0;
3634         pSMB->t2.DataOffset = 0;
3635         pSMB->t2.SetupCount = 1;
3636         pSMB->t2.Reserved3 = 0;
3637         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3638         byte_count = params + 1 /* pad */ ;
3639         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3640         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3641         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3642         pSMB->Pad = 0;
3643         pSMB->Fid = netfid;
3644         inc_rfc1001_len(pSMB, byte_count);
3645         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3646
3647         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3648                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3649         if (rc) {
3650                 cFYI(1, "error %d in GetExtAttr", rc);
3651         } else {
3652                 /* decode response */
3653                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3654                 /* BB also check enough total bytes returned */
3655                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3656                         /* If rc should we check for EOPNOSUPP and
3657                            disable the srvino flag? or in caller? */
3658                         rc = -EIO;      /* bad smb */
3659                 else {
3660                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3661                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3662                         struct file_chattr_info *pfinfo;
3663                         /* BB Do we need a cast or hash here ? */
3664                         if (count != 16) {
3665                                 cFYI(1, "Illegal size ret in GetExtAttr");
3666                                 rc = -EIO;
3667                                 goto GetExtAttrOut;
3668                         }
3669                         pfinfo = (struct file_chattr_info *)
3670                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3671                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3672                         *pMask = le64_to_cpu(pfinfo->mask);
3673                 }
3674         }
3675 GetExtAttrOut:
3676         cifs_buf_release(pSMB);
3677         if (rc == -EAGAIN)
3678                 goto GetExtAttrRetry;
3679         return rc;
3680 }
3681
3682 #endif /* CONFIG_POSIX */
3683
3684 #ifdef CONFIG_CIFS_ACL
3685 /*
3686  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3687  * all NT TRANSACTS that we init here have total parm and data under about 400
3688  * bytes (to fit in small cifs buffer size), which is the case so far, it
3689  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3690  * returned setup area) and MaxParameterCount (returned parms size) must be set
3691  * by caller
3692  */
3693 static int
3694 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3695                    const int parm_len, struct cifs_tcon *tcon,
3696                    void **ret_buf)
3697 {
3698         int rc;
3699         __u32 temp_offset;
3700         struct smb_com_ntransact_req *pSMB;
3701
3702         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3703                                 (void **)&pSMB);
3704         if (rc)
3705                 return rc;
3706         *ret_buf = (void *)pSMB;
3707         pSMB->Reserved = 0;
3708         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3709         pSMB->TotalDataCount  = 0;
3710         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3711         pSMB->ParameterCount = pSMB->TotalParameterCount;
3712         pSMB->DataCount  = pSMB->TotalDataCount;
3713         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3714                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3715         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3716         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3717         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3718         pSMB->SubCommand = cpu_to_le16(sub_command);
3719         return 0;
3720 }
3721
3722 static int
3723 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3724                    __u32 *pparmlen, __u32 *pdatalen)
3725 {
3726         char *end_of_smb;
3727         __u32 data_count, data_offset, parm_count, parm_offset;
3728         struct smb_com_ntransact_rsp *pSMBr;
3729         u16 bcc;
3730
3731         *pdatalen = 0;
3732         *pparmlen = 0;
3733
3734         if (buf == NULL)
3735                 return -EINVAL;
3736
3737         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3738
3739         bcc = get_bcc(&pSMBr->hdr);
3740         end_of_smb = 2 /* sizeof byte count */ + bcc +
3741                         (char *)&pSMBr->ByteCount;
3742
3743         data_offset = le32_to_cpu(pSMBr->DataOffset);
3744         data_count = le32_to_cpu(pSMBr->DataCount);
3745         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3746         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3747
3748         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3749         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3750
3751         /* should we also check that parm and data areas do not overlap? */
3752         if (*ppparm > end_of_smb) {
3753                 cFYI(1, "parms start after end of smb");
3754                 return -EINVAL;
3755         } else if (parm_count + *ppparm > end_of_smb) {
3756                 cFYI(1, "parm end after end of smb");
3757                 return -EINVAL;
3758         } else if (*ppdata > end_of_smb) {
3759                 cFYI(1, "data starts after end of smb");
3760                 return -EINVAL;
3761         } else if (data_count + *ppdata > end_of_smb) {
3762                 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3763                         *ppdata, data_count, (data_count + *ppdata),
3764                         end_of_smb, pSMBr);
3765                 return -EINVAL;
3766         } else if (parm_count + data_count > bcc) {
3767                 cFYI(1, "parm count and data count larger than SMB");
3768                 return -EINVAL;
3769         }
3770         *pdatalen = data_count;
3771         *pparmlen = parm_count;
3772         return 0;
3773 }
3774
3775 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3776 int
3777 CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3778                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3779 {
3780         int rc = 0;
3781         int buf_type = 0;
3782         QUERY_SEC_DESC_REQ *pSMB;
3783         struct kvec iov[1];
3784
3785         cFYI(1, "GetCifsACL");
3786
3787         *pbuflen = 0;
3788         *acl_inf = NULL;
3789
3790         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3791                         8 /* parm len */, tcon, (void **) &pSMB);
3792         if (rc)
3793                 return rc;
3794
3795         pSMB->MaxParameterCount = cpu_to_le32(4);
3796         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3797         pSMB->MaxSetupCount = 0;
3798         pSMB->Fid = fid; /* file handle always le */
3799         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3800                                      CIFS_ACL_DACL);
3801         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3802         inc_rfc1001_len(pSMB, 11);
3803         iov[0].iov_base = (char *)pSMB;
3804         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3805
3806         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3807                          0);
3808         cifs_stats_inc(&tcon->num_acl_get);
3809         if (rc) {
3810                 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3811         } else {                /* decode response */
3812                 __le32 *parm;
3813                 __u32 parm_len;
3814                 __u32 acl_len;
3815                 struct smb_com_ntransact_rsp *pSMBr;
3816                 char *pdata;
3817
3818 /* validate_nttransact */
3819                 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3820                                         &pdata, &parm_len, pbuflen);
3821                 if (rc)
3822                         goto qsec_out;
3823                 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3824
3825                 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3826
3827                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3828                         rc = -EIO;      /* bad smb */
3829                         *pbuflen = 0;
3830                         goto qsec_out;
3831                 }
3832
3833 /* BB check that data area is minimum length and as big as acl_len */
3834
3835                 acl_len = le32_to_cpu(*parm);
3836                 if (acl_len != *pbuflen) {
3837                         cERROR(1, "acl length %d does not match %d",
3838                                    acl_len, *pbuflen);
3839                         if (*pbuflen > acl_len)
3840                                 *pbuflen = acl_len;
3841                 }
3842
3843                 /* check if buffer is big enough for the acl
3844                    header followed by the smallest SID */
3845                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3846                     (*pbuflen >= 64 * 1024)) {
3847                         cERROR(1, "bad acl length %d", *pbuflen);
3848                         rc = -EINVAL;
3849                         *pbuflen = 0;
3850                 } else {
3851                         *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3852                         if (*acl_inf == NULL) {
3853                                 *pbuflen = 0;
3854                                 rc = -ENOMEM;
3855                         }
3856                         memcpy(*acl_inf, pdata, *pbuflen);
3857                 }
3858         }
3859 qsec_out:
3860         if (buf_type == CIFS_SMALL_BUFFER)
3861                 cifs_small_buf_release(iov[0].iov_base);
3862         else if (buf_type == CIFS_LARGE_BUFFER)
3863                 cifs_buf_release(iov[0].iov_base);
3864 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3865         return rc;
3866 }
3867
3868 int
3869 CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3870                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3871 {
3872         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3873         int rc = 0;
3874         int bytes_returned = 0;
3875         SET_SEC_DESC_REQ *pSMB = NULL;
3876         NTRANSACT_RSP *pSMBr = NULL;
3877
3878 setCifsAclRetry:
3879         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
3880                         (void **) &pSMBr);
3881         if (rc)
3882                         return (rc);
3883
3884         pSMB->MaxSetupCount = 0;
3885         pSMB->Reserved = 0;
3886
3887         param_count = 8;
3888         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3889         data_count = acllen;
3890         data_offset = param_offset + param_count;
3891         byte_count = 3 /* pad */  + param_count;
3892
3893         pSMB->DataCount = cpu_to_le32(data_count);
3894         pSMB->TotalDataCount = pSMB->DataCount;
3895         pSMB->MaxParameterCount = cpu_to_le32(4);
3896         pSMB->MaxDataCount = cpu_to_le32(16384);
3897         pSMB->ParameterCount = cpu_to_le32(param_count);
3898         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3899         pSMB->TotalParameterCount = pSMB->ParameterCount;
3900         pSMB->DataOffset = cpu_to_le32(data_offset);
3901         pSMB->SetupCount = 0;
3902         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3903         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3904
3905         pSMB->Fid = fid; /* file handle always le */
3906         pSMB->Reserved2 = 0;
3907         pSMB->AclFlags = cpu_to_le32(aclflag);
3908
3909         if (pntsd && acllen) {
3910                 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3911                         (char *) pntsd,
3912                         acllen);
3913                 inc_rfc1001_len(pSMB, byte_count + data_count);
3914         } else
3915                 inc_rfc1001_len(pSMB, byte_count);
3916
3917         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3918                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3919
3920         cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3921         if (rc)
3922                 cFYI(1, "Set CIFS ACL returned %d", rc);
3923         cifs_buf_release(pSMB);
3924
3925         if (rc == -EAGAIN)
3926                 goto setCifsAclRetry;
3927
3928         return (rc);
3929 }
3930
3931 #endif /* CONFIG_CIFS_ACL */
3932
3933 /* Legacy Query Path Information call for lookup to old servers such
3934    as Win9x/WinME */
3935 int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3936                         const unsigned char *searchName,
3937                         FILE_ALL_INFO *pFinfo,
3938                         const struct nls_table *nls_codepage, int remap)
3939 {
3940         QUERY_INFORMATION_REQ *pSMB;
3941         QUERY_INFORMATION_RSP *pSMBr;
3942         int rc = 0;
3943         int bytes_returned;
3944         int name_len;
3945
3946         cFYI(1, "In SMBQPath path %s", searchName);
3947 QInfRetry:
3948         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3949                       (void **) &pSMBr);
3950         if (rc)
3951                 return rc;
3952
3953         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3954                 name_len =
3955                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3956                                            searchName, PATH_MAX, nls_codepage,
3957                                            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                     cifsConvertToUTF16((__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                     cifsConvertToUTF16((__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                     cifsConvertToUTF16((__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, (char *) 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                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4665                                            searchName, PATH_MAX, nls_codepage,
4666                                            remap);
4667                 name_len++;     /* trailing null */
4668                 name_len *= 2;
4669         } else {        /* BB improve the check for buffer overruns BB */
4670                 name_len = strnlen(searchName, PATH_MAX);
4671                 name_len++;     /* trailing null */
4672                 strncpy(pSMB->FileName, searchName, name_len);
4673         }
4674
4675         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4676         pSMB->TotalDataCount = 0;
4677         pSMB->MaxParameterCount = cpu_to_le16(2);
4678         /* BB find exact max data count below from sess structure BB */
4679         pSMB->MaxDataCount = cpu_to_le16(4000);
4680         pSMB->MaxSetupCount = 0;
4681         pSMB->Reserved = 0;
4682         pSMB->Flags = 0;
4683         pSMB->Timeout = 0;
4684         pSMB->Reserved2 = 0;
4685         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4686                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4687         pSMB->DataCount = 0;
4688         pSMB->DataOffset = 0;
4689         pSMB->SetupCount = 1;
4690         pSMB->Reserved3 = 0;
4691         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4692         byte_count = params + 1 /* pad */ ;
4693         pSMB->TotalParameterCount = cpu_to_le16(params);
4694         pSMB->ParameterCount = pSMB->TotalParameterCount;
4695         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4696         pSMB->Reserved4 = 0;
4697         inc_rfc1001_len(pSMB, byte_count);
4698         pSMB->ByteCount = cpu_to_le16(byte_count);
4699
4700         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4701                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4702         if (rc) {
4703                 cFYI(1, "error %d in QueryInternalInfo", rc);
4704         } else {
4705                 /* decode response */
4706                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4707                 /* BB also check enough total bytes returned */
4708                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4709                         /* If rc should we check for EOPNOSUPP and
4710                         disable the srvino flag? or in caller? */
4711                         rc = -EIO;      /* bad smb */
4712                 else {
4713                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4714                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4715                         struct file_internal_info *pfinfo;
4716                         /* BB Do we need a cast or hash here ? */
4717                         if (count < 8) {
4718                                 cFYI(1, "Illegal size ret in QryIntrnlInf");
4719                                 rc = -EIO;
4720                                 goto GetInodeNumOut;
4721                         }
4722                         pfinfo = (struct file_internal_info *)
4723                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4724                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4725                 }
4726         }
4727 GetInodeNumOut:
4728         cifs_buf_release(pSMB);
4729         if (rc == -EAGAIN)
4730                 goto GetInodeNumberRetry;
4731         return rc;
4732 }
4733
4734 /* parses DFS refferal V3 structure
4735  * caller is responsible for freeing target_nodes
4736  * returns:
4737  *      on success - 0
4738  *      on failure - errno
4739  */
4740 static int
4741 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4742                 unsigned int *num_of_nodes,
4743                 struct dfs_info3_param **target_nodes,
4744                 const struct nls_table *nls_codepage, int remap,
4745                 const char *searchName)
4746 {
4747         int i, rc = 0;
4748         char *data_end;
4749         bool is_unicode;
4750         struct dfs_referral_level_3 *ref;
4751
4752         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4753                 is_unicode = true;
4754         else
4755                 is_unicode = false;
4756         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4757
4758         if (*num_of_nodes < 1) {
4759                 cERROR(1, "num_referrals: must be at least > 0,"
4760                         "but we get num_referrals = %d\n", *num_of_nodes);
4761                 rc = -EINVAL;
4762                 goto parse_DFS_referrals_exit;
4763         }
4764
4765         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4766         if (ref->VersionNumber != cpu_to_le16(3)) {
4767                 cERROR(1, "Referrals of V%d version are not supported,"
4768                         "should be V3", le16_to_cpu(ref->VersionNumber));
4769                 rc = -EINVAL;
4770                 goto parse_DFS_referrals_exit;
4771         }
4772
4773         /* get the upper boundary of the resp buffer */
4774         data_end = (char *)(&(pSMBr->PathConsumed)) +
4775                                 le16_to_cpu(pSMBr->t2.DataCount);
4776
4777         cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
4778                         *num_of_nodes,
4779                         le32_to_cpu(pSMBr->DFSFlags));
4780
4781         *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4782                         *num_of_nodes, GFP_KERNEL);
4783         if (*target_nodes == NULL) {
4784                 cERROR(1, "Failed to allocate buffer for target_nodes\n");
4785                 rc = -ENOMEM;
4786                 goto parse_DFS_referrals_exit;
4787         }
4788
4789         /* collect necessary data from referrals */
4790         for (i = 0; i < *num_of_nodes; i++) {
4791                 char *temp;
4792                 int max_len;
4793                 struct dfs_info3_param *node = (*target_nodes)+i;
4794
4795                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4796                 if (is_unicode) {
4797                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4798                                                 GFP_KERNEL);
4799                         if (tmp == NULL) {
4800                                 rc = -ENOMEM;
4801                                 goto parse_DFS_referrals_exit;
4802                         }
4803                         cifsConvertToUTF16((__le16 *) tmp, searchName,
4804                                            PATH_MAX, nls_codepage, remap);
4805                         node->path_consumed = cifs_utf16_bytes(tmp,
4806                                         le16_to_cpu(pSMBr->PathConsumed),
4807                                         nls_codepage);
4808                         kfree(tmp);
4809                 } else
4810                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4811
4812                 node->server_type = le16_to_cpu(ref->ServerType);
4813                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4814
4815                 /* copy DfsPath */
4816                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4817                 max_len = data_end - temp;
4818                 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4819                                                 is_unicode, nls_codepage);
4820                 if (!node->path_name) {
4821                         rc = -ENOMEM;
4822                         goto parse_DFS_referrals_exit;
4823                 }
4824
4825                 /* copy link target UNC */
4826                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4827                 max_len = data_end - temp;
4828                 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4829                                                 is_unicode, nls_codepage);
4830                 if (!node->node_name)
4831                         rc = -ENOMEM;
4832         }
4833
4834 parse_DFS_referrals_exit:
4835         if (rc) {
4836                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4837                 *target_nodes = NULL;
4838                 *num_of_nodes = 0;
4839         }
4840         return rc;
4841 }
4842
4843 int
4844 CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4845                 const unsigned char *searchName,
4846                 struct dfs_info3_param **target_nodes,
4847                 unsigned int *num_of_nodes,
4848                 const struct nls_table *nls_codepage, int remap)
4849 {
4850 /* TRANS2_GET_DFS_REFERRAL */
4851         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4852         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4853         int rc = 0;
4854         int bytes_returned;
4855         int name_len;
4856         __u16 params, byte_count;
4857         *num_of_nodes = 0;
4858         *target_nodes = NULL;
4859
4860         cFYI(1, "In GetDFSRefer the path %s", searchName);
4861         if (ses == NULL)
4862                 return -ENODEV;
4863 getDFSRetry:
4864         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4865                       (void **) &pSMBr);
4866         if (rc)
4867                 return rc;
4868
4869         /* server pointer checked in called function,
4870         but should never be null here anyway */
4871         pSMB->hdr.Mid = GetNextMid(ses->server);
4872         pSMB->hdr.Tid = ses->ipc_tid;
4873         pSMB->hdr.Uid = ses->Suid;
4874         if (ses->capabilities & CAP_STATUS32)
4875                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4876         if (ses->capabilities & CAP_DFS)
4877                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4878
4879         if (ses->capabilities & CAP_UNICODE) {
4880                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4881                 name_len =
4882                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4883                                        searchName, PATH_MAX, nls_codepage,
4884                                        remap);
4885                 name_len++;     /* trailing null */
4886                 name_len *= 2;
4887         } else {        /* BB improve the check for buffer overruns BB */
4888                 name_len = strnlen(searchName, PATH_MAX);
4889                 name_len++;     /* trailing null */
4890                 strncpy(pSMB->RequestFileName, searchName, name_len);
4891         }
4892
4893         if (ses->server) {
4894                 if (ses->server->sec_mode &
4895                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4896                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4897         }
4898
4899         pSMB->hdr.Uid = ses->Suid;
4900
4901         params = 2 /* level */  + name_len /*includes null */ ;
4902         pSMB->TotalDataCount = 0;
4903         pSMB->DataCount = 0;
4904         pSMB->DataOffset = 0;
4905         pSMB->MaxParameterCount = 0;
4906         /* BB find exact max SMB PDU from sess structure BB */
4907         pSMB->MaxDataCount = cpu_to_le16(4000);
4908         pSMB->MaxSetupCount = 0;
4909         pSMB->Reserved = 0;
4910         pSMB->Flags = 0;
4911         pSMB->Timeout = 0;
4912         pSMB->Reserved2 = 0;
4913         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4914           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4915         pSMB->SetupCount = 1;
4916         pSMB->Reserved3 = 0;
4917         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4918         byte_count = params + 3 /* pad */ ;
4919         pSMB->ParameterCount = cpu_to_le16(params);
4920         pSMB->TotalParameterCount = pSMB->ParameterCount;
4921         pSMB->MaxReferralLevel = cpu_to_le16(3);
4922         inc_rfc1001_len(pSMB, byte_count);
4923         pSMB->ByteCount = cpu_to_le16(byte_count);
4924
4925         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4926                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4927         if (rc) {
4928                 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4929                 goto GetDFSRefExit;
4930         }
4931         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4932
4933         /* BB Also check if enough total bytes returned? */
4934         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4935                 rc = -EIO;      /* bad smb */
4936                 goto GetDFSRefExit;
4937         }
4938
4939         cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
4940                                 get_bcc(&pSMBr->hdr),
4941                                 le16_to_cpu(pSMBr->t2.DataOffset));
4942
4943         /* parse returned result into more usable form */
4944         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4945                                  target_nodes, nls_codepage, remap,
4946                                  searchName);
4947
4948 GetDFSRefExit:
4949         cifs_buf_release(pSMB);
4950
4951         if (rc == -EAGAIN)
4952                 goto getDFSRetry;
4953
4954         return rc;
4955 }
4956
4957 /* Query File System Info such as free space to old servers such as Win 9x */
4958 int
4959 SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4960 {
4961 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4962         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4963         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4964         FILE_SYSTEM_ALLOC_INFO *response_data;
4965         int rc = 0;
4966         int bytes_returned = 0;
4967         __u16 params, byte_count;
4968
4969         cFYI(1, "OldQFSInfo");
4970 oldQFSInfoRetry:
4971         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4972                 (void **) &pSMBr);
4973         if (rc)
4974                 return rc;
4975
4976         params = 2;     /* level */
4977         pSMB->TotalDataCount = 0;
4978         pSMB->MaxParameterCount = cpu_to_le16(2);
4979         pSMB->MaxDataCount = cpu_to_le16(1000);
4980         pSMB->MaxSetupCount = 0;
4981         pSMB->Reserved = 0;
4982         pSMB->Flags = 0;
4983         pSMB->Timeout = 0;
4984         pSMB->Reserved2 = 0;
4985         byte_count = params + 1 /* pad */ ;
4986         pSMB->TotalParameterCount = cpu_to_le16(params);
4987         pSMB->ParameterCount = pSMB->TotalParameterCount;
4988         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4989         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4990         pSMB->DataCount = 0;
4991         pSMB->DataOffset = 0;
4992         pSMB->SetupCount = 1;
4993         pSMB->Reserved3 = 0;
4994         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4995         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4996         inc_rfc1001_len(pSMB, byte_count);
4997         pSMB->ByteCount = cpu_to_le16(byte_count);
4998
4999         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5000                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5001         if (rc) {
5002                 cFYI(1, "Send error in QFSInfo = %d", rc);
5003         } else {                /* decode response */
5004                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5005
5006                 if (rc || get_bcc(&pSMBr->hdr) < 18)
5007                         rc = -EIO;      /* bad smb */
5008                 else {
5009                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5010                         cFYI(1, "qfsinf resp BCC: %d  Offset %d",
5011                                  get_bcc(&pSMBr->hdr), data_offset);
5012
5013                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
5014                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5015                         FSData->f_bsize =
5016                                 le16_to_cpu(response_data->BytesPerSector) *
5017                                 le32_to_cpu(response_data->
5018                                         SectorsPerAllocationUnit);
5019                         FSData->f_blocks =
5020                                le32_to_cpu(response_data->TotalAllocationUnits);
5021                         FSData->f_bfree = FSData->f_bavail =
5022                                 le32_to_cpu(response_data->FreeAllocationUnits);
5023                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5024                              (unsigned long long)FSData->f_blocks,
5025                              (unsigned long long)FSData->f_bfree,
5026                              FSData->f_bsize);
5027                 }
5028         }
5029         cifs_buf_release(pSMB);
5030
5031         if (rc == -EAGAIN)
5032                 goto oldQFSInfoRetry;
5033
5034         return rc;
5035 }
5036
5037 int
5038 CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
5039 {
5040 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5041         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5042         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5043         FILE_SYSTEM_INFO *response_data;
5044         int rc = 0;
5045         int bytes_returned = 0;
5046         __u16 params, byte_count;
5047
5048         cFYI(1, "In QFSInfo");
5049 QFSInfoRetry:
5050         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5051                       (void **) &pSMBr);
5052         if (rc)
5053                 return rc;
5054
5055         params = 2;     /* level */
5056         pSMB->TotalDataCount = 0;
5057         pSMB->MaxParameterCount = cpu_to_le16(2);
5058         pSMB->MaxDataCount = cpu_to_le16(1000);
5059         pSMB->MaxSetupCount = 0;
5060         pSMB->Reserved = 0;
5061         pSMB->Flags = 0;
5062         pSMB->Timeout = 0;
5063         pSMB->Reserved2 = 0;
5064         byte_count = params + 1 /* pad */ ;
5065         pSMB->TotalParameterCount = cpu_to_le16(params);
5066         pSMB->ParameterCount = pSMB->TotalParameterCount;
5067         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5068                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5069         pSMB->DataCount = 0;
5070         pSMB->DataOffset = 0;
5071         pSMB->SetupCount = 1;
5072         pSMB->Reserved3 = 0;
5073         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5074         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5075         inc_rfc1001_len(pSMB, byte_count);
5076         pSMB->ByteCount = cpu_to_le16(byte_count);
5077
5078         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5079                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5080         if (rc) {
5081                 cFYI(1, "Send error in QFSInfo = %d", rc);
5082         } else {                /* decode response */
5083                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5084
5085                 if (rc || get_bcc(&pSMBr->hdr) < 24)
5086                         rc = -EIO;      /* bad smb */
5087                 else {
5088                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5089
5090                         response_data =
5091                             (FILE_SYSTEM_INFO
5092                              *) (((char *) &pSMBr->hdr.Protocol) +
5093                                  data_offset);
5094                         FSData->f_bsize =
5095                             le32_to_cpu(response_data->BytesPerSector) *
5096                             le32_to_cpu(response_data->
5097                                         SectorsPerAllocationUnit);
5098                         FSData->f_blocks =
5099                             le64_to_cpu(response_data->TotalAllocationUnits);
5100                         FSData->f_bfree = FSData->f_bavail =
5101                             le64_to_cpu(response_data->FreeAllocationUnits);
5102                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5103                              (unsigned long long)FSData->f_blocks,
5104                              (unsigned long long)FSData->f_bfree,
5105                              FSData->f_bsize);
5106                 }
5107         }
5108         cifs_buf_release(pSMB);
5109
5110         if (rc == -EAGAIN)
5111                 goto QFSInfoRetry;
5112
5113         return rc;
5114 }
5115
5116 int
5117 CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
5118 {
5119 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5120         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5121         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5122         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5123         int rc = 0;
5124         int bytes_returned = 0;
5125         __u16 params, byte_count;
5126
5127         cFYI(1, "In QFSAttributeInfo");
5128 QFSAttributeRetry:
5129         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5130                       (void **) &pSMBr);
5131         if (rc)
5132                 return rc;
5133
5134         params = 2;     /* level */
5135         pSMB->TotalDataCount = 0;
5136         pSMB->MaxParameterCount = cpu_to_le16(2);
5137         /* BB find exact max SMB PDU from sess structure BB */
5138         pSMB->MaxDataCount = cpu_to_le16(1000);
5139         pSMB->MaxSetupCount = 0;
5140         pSMB->Reserved = 0;
5141         pSMB->Flags = 0;
5142         pSMB->Timeout = 0;
5143         pSMB->Reserved2 = 0;
5144         byte_count = params + 1 /* pad */ ;
5145         pSMB->TotalParameterCount = cpu_to_le16(params);
5146         pSMB->ParameterCount = pSMB->TotalParameterCount;
5147         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5148                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5149         pSMB->DataCount = 0;
5150         pSMB->DataOffset = 0;
5151         pSMB->SetupCount = 1;
5152         pSMB->Reserved3 = 0;
5153         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5154         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5155         inc_rfc1001_len(pSMB, byte_count);
5156         pSMB->ByteCount = cpu_to_le16(byte_count);
5157
5158         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5159                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5160         if (rc) {
5161                 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5162         } else {                /* decode response */
5163                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5164
5165                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5166                         /* BB also check if enough bytes returned */
5167                         rc = -EIO;      /* bad smb */
5168                 } else {
5169                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5170                         response_data =
5171                             (FILE_SYSTEM_ATTRIBUTE_INFO
5172                              *) (((char *) &pSMBr->hdr.Protocol) +
5173                                  data_offset);
5174                         memcpy(&tcon->fsAttrInfo, response_data,
5175                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5176                 }
5177         }
5178         cifs_buf_release(pSMB);
5179
5180         if (rc == -EAGAIN)
5181                 goto QFSAttributeRetry;
5182
5183         return rc;
5184 }
5185
5186 int
5187 CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
5188 {
5189 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5190         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5191         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5192         FILE_SYSTEM_DEVICE_INFO *response_data;
5193         int rc = 0;
5194         int bytes_returned = 0;
5195         __u16 params, byte_count;
5196
5197         cFYI(1, "In QFSDeviceInfo");
5198 QFSDeviceRetry:
5199         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5200                       (void **) &pSMBr);
5201         if (rc)
5202                 return rc;
5203
5204         params = 2;     /* level */
5205         pSMB->TotalDataCount = 0;
5206         pSMB->MaxParameterCount = cpu_to_le16(2);
5207         /* BB find exact max SMB PDU from sess structure BB */
5208         pSMB->MaxDataCount = cpu_to_le16(1000);
5209         pSMB->MaxSetupCount = 0;
5210         pSMB->Reserved = 0;
5211         pSMB->Flags = 0;
5212         pSMB->Timeout = 0;
5213         pSMB->Reserved2 = 0;
5214         byte_count = params + 1 /* pad */ ;
5215         pSMB->TotalParameterCount = cpu_to_le16(params);
5216         pSMB->ParameterCount = pSMB->TotalParameterCount;
5217         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5218                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5219
5220         pSMB->DataCount = 0;
5221         pSMB->DataOffset = 0;
5222         pSMB->SetupCount = 1;
5223         pSMB->Reserved3 = 0;
5224         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5225         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5226         inc_rfc1001_len(pSMB, byte_count);
5227         pSMB->ByteCount = cpu_to_le16(byte_count);
5228
5229         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5230                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5231         if (rc) {
5232                 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5233         } else {                /* decode response */
5234                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5235
5236                 if (rc || get_bcc(&pSMBr->hdr) <
5237                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5238                         rc = -EIO;      /* bad smb */
5239                 else {
5240                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5241                         response_data =
5242                             (FILE_SYSTEM_DEVICE_INFO *)
5243                                 (((char *) &pSMBr->hdr.Protocol) +
5244                                  data_offset);
5245                         memcpy(&tcon->fsDevInfo, response_data,
5246                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5247                 }
5248         }
5249         cifs_buf_release(pSMB);
5250
5251         if (rc == -EAGAIN)
5252                 goto QFSDeviceRetry;
5253
5254         return rc;
5255 }
5256
5257 int
5258 CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
5259 {
5260 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5261         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5262         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5263         FILE_SYSTEM_UNIX_INFO *response_data;
5264         int rc = 0;
5265         int bytes_returned = 0;
5266         __u16 params, byte_count;
5267
5268         cFYI(1, "In QFSUnixInfo");
5269 QFSUnixRetry:
5270         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5271                                    (void **) &pSMB, (void **) &pSMBr);
5272         if (rc)
5273                 return rc;
5274
5275         params = 2;     /* level */
5276         pSMB->TotalDataCount = 0;
5277         pSMB->DataCount = 0;
5278         pSMB->DataOffset = 0;
5279         pSMB->MaxParameterCount = cpu_to_le16(2);
5280         /* BB find exact max SMB PDU from sess structure BB */
5281         pSMB->MaxDataCount = cpu_to_le16(100);
5282         pSMB->MaxSetupCount = 0;
5283         pSMB->Reserved = 0;
5284         pSMB->Flags = 0;
5285         pSMB->Timeout = 0;
5286         pSMB->Reserved2 = 0;
5287         byte_count = params + 1 /* pad */ ;
5288         pSMB->ParameterCount = cpu_to_le16(params);
5289         pSMB->TotalParameterCount = pSMB->ParameterCount;
5290         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5291                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5292         pSMB->SetupCount = 1;
5293         pSMB->Reserved3 = 0;
5294         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5295         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5296         inc_rfc1001_len(pSMB, byte_count);
5297         pSMB->ByteCount = cpu_to_le16(byte_count);
5298
5299         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5300                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5301         if (rc) {
5302                 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5303         } else {                /* decode response */
5304                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5305
5306                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5307                         rc = -EIO;      /* bad smb */
5308                 } else {
5309                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5310                         response_data =
5311                             (FILE_SYSTEM_UNIX_INFO
5312                              *) (((char *) &pSMBr->hdr.Protocol) +
5313                                  data_offset);
5314                         memcpy(&tcon->fsUnixInfo, response_data,
5315                                sizeof(FILE_SYSTEM_UNIX_INFO));
5316                 }
5317         }
5318         cifs_buf_release(pSMB);
5319
5320         if (rc == -EAGAIN)
5321                 goto QFSUnixRetry;
5322
5323
5324         return rc;
5325 }
5326
5327 int
5328 CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
5329 {
5330 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5331         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5332         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5333         int rc = 0;
5334         int bytes_returned = 0;
5335         __u16 params, param_offset, offset, byte_count;
5336
5337         cFYI(1, "In SETFSUnixInfo");
5338 SETFSUnixRetry:
5339         /* BB switch to small buf init to save memory */
5340         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5341                                         (void **) &pSMB, (void **) &pSMBr);
5342         if (rc)
5343                 return rc;
5344
5345         params = 4;     /* 2 bytes zero followed by info level. */
5346         pSMB->MaxSetupCount = 0;
5347         pSMB->Reserved = 0;
5348         pSMB->Flags = 0;
5349         pSMB->Timeout = 0;
5350         pSMB->Reserved2 = 0;
5351         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5352                                 - 4;
5353         offset = param_offset + params;
5354
5355         pSMB->MaxParameterCount = cpu_to_le16(4);
5356         /* BB find exact max SMB PDU from sess structure BB */
5357         pSMB->MaxDataCount = cpu_to_le16(100);
5358         pSMB->SetupCount = 1;
5359         pSMB->Reserved3 = 0;
5360         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5361         byte_count = 1 /* pad */ + params + 12;
5362
5363         pSMB->DataCount = cpu_to_le16(12);
5364         pSMB->ParameterCount = cpu_to_le16(params);
5365         pSMB->TotalDataCount = pSMB->DataCount;
5366         pSMB->TotalParameterCount = pSMB->ParameterCount;
5367         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5368         pSMB->DataOffset = cpu_to_le16(offset);
5369
5370         /* Params. */
5371         pSMB->FileNum = 0;
5372         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5373
5374         /* Data. */
5375         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5376         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5377         pSMB->ClientUnixCap = cpu_to_le64(cap);
5378
5379         inc_rfc1001_len(pSMB, byte_count);
5380         pSMB->ByteCount = cpu_to_le16(byte_count);
5381
5382         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5383                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5384         if (rc) {
5385                 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5386         } else {                /* decode response */
5387                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5388                 if (rc)
5389                         rc = -EIO;      /* bad smb */
5390         }
5391         cifs_buf_release(pSMB);
5392
5393         if (rc == -EAGAIN)
5394                 goto SETFSUnixRetry;
5395
5396         return rc;
5397 }
5398
5399
5400
5401 int
5402 CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
5403                    struct kstatfs *FSData)
5404 {
5405 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5406         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5407         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5408         FILE_SYSTEM_POSIX_INFO *response_data;
5409         int rc = 0;
5410         int bytes_returned = 0;
5411         __u16 params, byte_count;
5412
5413         cFYI(1, "In QFSPosixInfo");
5414 QFSPosixRetry:
5415         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5416                       (void **) &pSMBr);
5417         if (rc)
5418                 return rc;
5419
5420         params = 2;     /* level */
5421         pSMB->TotalDataCount = 0;
5422         pSMB->DataCount = 0;
5423         pSMB->DataOffset = 0;
5424         pSMB->MaxParameterCount = cpu_to_le16(2);
5425         /* BB find exact max SMB PDU from sess structure BB */
5426         pSMB->MaxDataCount = cpu_to_le16(100);
5427         pSMB->MaxSetupCount = 0;
5428         pSMB->Reserved = 0;
5429         pSMB->Flags = 0;
5430         pSMB->Timeout = 0;
5431         pSMB->Reserved2 = 0;
5432         byte_count = params + 1 /* pad */ ;
5433         pSMB->ParameterCount = cpu_to_le16(params);
5434         pSMB->TotalParameterCount = pSMB->ParameterCount;
5435         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5436                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5437         pSMB->SetupCount = 1;
5438         pSMB->Reserved3 = 0;
5439         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5440         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5441         inc_rfc1001_len(pSMB, byte_count);
5442         pSMB->ByteCount = cpu_to_le16(byte_count);
5443
5444         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5445                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5446         if (rc) {
5447                 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5448         } else {                /* decode response */
5449                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5450
5451                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5452                         rc = -EIO;      /* bad smb */
5453                 } else {
5454                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5455                         response_data =
5456                             (FILE_SYSTEM_POSIX_INFO
5457                              *) (((char *) &pSMBr->hdr.Protocol) +
5458                                  data_offset);
5459                         FSData->f_bsize =
5460                                         le32_to_cpu(response_data->BlockSize);
5461                         FSData->f_blocks =
5462                                         le64_to_cpu(response_data->TotalBlocks);
5463                         FSData->f_bfree =
5464                             le64_to_cpu(response_data->BlocksAvail);
5465                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5466                                 FSData->f_bavail = FSData->f_bfree;
5467                         } else {
5468                                 FSData->f_bavail =
5469                                     le64_to_cpu(response_data->UserBlocksAvail);
5470                         }
5471                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5472                                 FSData->f_files =
5473                                      le64_to_cpu(response_data->TotalFileNodes);
5474                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5475                                 FSData->f_ffree =
5476                                       le64_to_cpu(response_data->FreeFileNodes);
5477                 }
5478         }
5479         cifs_buf_release(pSMB);
5480
5481         if (rc == -EAGAIN)
5482                 goto QFSPosixRetry;
5483
5484         return rc;
5485 }
5486
5487
5488 /* We can not use write of zero bytes trick to
5489    set file size due to need for large file support.  Also note that
5490    this SetPathInfo is preferred to SetFileInfo based method in next
5491    routine which is only needed to work around a sharing violation bug
5492    in Samba which this routine can run into */
5493
5494 int
5495 CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
5496               __u64 size, bool SetAllocation,
5497               const struct nls_table *nls_codepage, int remap)
5498 {
5499         struct smb_com_transaction2_spi_req *pSMB = NULL;
5500         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5501         struct file_end_of_file_info *parm_data;
5502         int name_len;
5503         int rc = 0;
5504         int bytes_returned = 0;
5505         __u16 params, byte_count, data_count, param_offset, offset;
5506
5507         cFYI(1, "In SetEOF");
5508 SetEOFRetry:
5509         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5510                       (void **) &pSMBr);
5511         if (rc)
5512                 return rc;
5513
5514         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5515                 name_len =
5516                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5517                                        PATH_MAX, nls_codepage, remap);
5518                 name_len++;     /* trailing null */
5519                 name_len *= 2;
5520         } else {        /* BB improve the check for buffer overruns BB */
5521                 name_len = strnlen(fileName, PATH_MAX);
5522                 name_len++;     /* trailing null */
5523                 strncpy(pSMB->FileName, fileName, name_len);
5524         }
5525         params = 6 + name_len;
5526         data_count = sizeof(struct file_end_of_file_info);
5527         pSMB->MaxParameterCount = cpu_to_le16(2);
5528         pSMB->MaxDataCount = cpu_to_le16(4100);
5529         pSMB->MaxSetupCount = 0;
5530         pSMB->Reserved = 0;
5531         pSMB->Flags = 0;
5532         pSMB->Timeout = 0;
5533         pSMB->Reserved2 = 0;
5534         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5535                                 InformationLevel) - 4;
5536         offset = param_offset + params;
5537         if (SetAllocation) {
5538                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5539                         pSMB->InformationLevel =
5540                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5541                 else
5542                         pSMB->InformationLevel =
5543                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5544         } else /* Set File Size */  {
5545             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5546                     pSMB->InformationLevel =
5547                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5548             else
5549                     pSMB->InformationLevel =
5550                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5551         }
5552
5553         parm_data =
5554             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5555                                        offset);
5556         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5557         pSMB->DataOffset = cpu_to_le16(offset);
5558         pSMB->SetupCount = 1;
5559         pSMB->Reserved3 = 0;
5560         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5561         byte_count = 3 /* pad */  + params + data_count;
5562         pSMB->DataCount = cpu_to_le16(data_count);
5563         pSMB->TotalDataCount = pSMB->DataCount;
5564         pSMB->ParameterCount = cpu_to_le16(params);
5565         pSMB->TotalParameterCount = pSMB->ParameterCount;
5566         pSMB->Reserved4 = 0;
5567         inc_rfc1001_len(pSMB, byte_count);
5568         parm_data->FileSize = cpu_to_le64(size);
5569         pSMB->ByteCount = cpu_to_le16(byte_count);
5570         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5571                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5572         if (rc)
5573                 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5574
5575         cifs_buf_release(pSMB);
5576
5577         if (rc == -EAGAIN)
5578                 goto SetEOFRetry;
5579
5580         return rc;
5581 }
5582
5583 int
5584 CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5585                    __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5586 {
5587         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5588         struct file_end_of_file_info *parm_data;
5589         int rc = 0;
5590         __u16 params, param_offset, offset, byte_count, count;
5591
5592         cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5593                         (long long)size);
5594         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5595
5596         if (rc)
5597                 return rc;
5598
5599         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5600         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5601
5602         params = 6;
5603         pSMB->MaxSetupCount = 0;
5604         pSMB->Reserved = 0;
5605         pSMB->Flags = 0;
5606         pSMB->Timeout = 0;
5607         pSMB->Reserved2 = 0;
5608         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5609         offset = param_offset + params;
5610
5611         count = sizeof(struct file_end_of_file_info);
5612         pSMB->MaxParameterCount = cpu_to_le16(2);
5613         /* BB find exact max SMB PDU from sess structure BB */
5614         pSMB->MaxDataCount = cpu_to_le16(1000);
5615         pSMB->SetupCount = 1;
5616         pSMB->Reserved3 = 0;
5617         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5618         byte_count = 3 /* pad */  + params + count;
5619         pSMB->DataCount = cpu_to_le16(count);
5620         pSMB->ParameterCount = cpu_to_le16(params);
5621         pSMB->TotalDataCount = pSMB->DataCount;
5622         pSMB->TotalParameterCount = pSMB->ParameterCount;
5623         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5624         parm_data =
5625                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5626                                 + offset);
5627         pSMB->DataOffset = cpu_to_le16(offset);
5628         parm_data->FileSize = cpu_to_le64(size);
5629         pSMB->Fid = fid;
5630         if (SetAllocation) {
5631                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5632                         pSMB->InformationLevel =
5633                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5634                 else
5635                         pSMB->InformationLevel =
5636                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5637         } else /* Set File Size */  {
5638             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5639                     pSMB->InformationLevel =
5640                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5641             else
5642                     pSMB->InformationLevel =
5643                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5644         }
5645         pSMB->Reserved4 = 0;
5646         inc_rfc1001_len(pSMB, byte_count);
5647         pSMB->ByteCount = cpu_to_le16(byte_count);
5648         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5649         if (rc) {
5650                 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5651         }
5652
5653         /* Note: On -EAGAIN error only caller can retry on handle based calls
5654                 since file handle passed in no longer valid */
5655
5656         return rc;
5657 }
5658
5659 /* Some legacy servers such as NT4 require that the file times be set on
5660    an open handle, rather than by pathname - this is awkward due to
5661    potential access conflicts on the open, but it is unavoidable for these
5662    old servers since the only other choice is to go from 100 nanosecond DCE
5663    time and resort to the original setpathinfo level which takes the ancient
5664    DOS time format with 2 second granularity */
5665 int
5666 CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5667                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5668 {
5669         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5670         char *data_offset;
5671         int rc = 0;
5672         __u16 params, param_offset, offset, byte_count, count;
5673
5674         cFYI(1, "Set Times (via SetFileInfo)");
5675         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5676
5677         if (rc)
5678                 return rc;
5679
5680         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5681         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5682
5683         params = 6;
5684         pSMB->MaxSetupCount = 0;
5685         pSMB->Reserved = 0;
5686         pSMB->Flags = 0;
5687         pSMB->Timeout = 0;
5688         pSMB->Reserved2 = 0;
5689         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5690         offset = param_offset + params;
5691
5692         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5693
5694         count = sizeof(FILE_BASIC_INFO);
5695         pSMB->MaxParameterCount = cpu_to_le16(2);
5696         /* BB find max SMB PDU from sess */
5697         pSMB->MaxDataCount = cpu_to_le16(1000);
5698         pSMB->SetupCount = 1;
5699         pSMB->Reserved3 = 0;
5700         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5701         byte_count = 3 /* pad */  + params + count;
5702         pSMB->DataCount = cpu_to_le16(count);
5703         pSMB->ParameterCount = cpu_to_le16(params);
5704         pSMB->TotalDataCount = pSMB->DataCount;
5705         pSMB->TotalParameterCount = pSMB->ParameterCount;
5706         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5707         pSMB->DataOffset = cpu_to_le16(offset);
5708         pSMB->Fid = fid;
5709         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5710                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5711         else
5712                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5713         pSMB->Reserved4 = 0;
5714         inc_rfc1001_len(pSMB, byte_count);
5715         pSMB->ByteCount = cpu_to_le16(byte_count);
5716         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5717         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5718         if (rc)
5719                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5720
5721         /* Note: On -EAGAIN error only caller can retry on handle based calls
5722                 since file handle passed in no longer valid */
5723
5724         return rc;
5725 }
5726
5727 int
5728 CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5729                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5730 {
5731         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5732         char *data_offset;
5733         int rc = 0;
5734         __u16 params, param_offset, offset, byte_count, count;
5735
5736         cFYI(1, "Set File Disposition (via SetFileInfo)");
5737         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5738
5739         if (rc)
5740                 return rc;
5741
5742         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5743         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5744
5745         params = 6;
5746         pSMB->MaxSetupCount = 0;
5747         pSMB->Reserved = 0;
5748         pSMB->Flags = 0;
5749         pSMB->Timeout = 0;
5750         pSMB->Reserved2 = 0;
5751         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5752         offset = param_offset + params;
5753
5754         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5755
5756         count = 1;
5757         pSMB->MaxParameterCount = cpu_to_le16(2);
5758         /* BB find max SMB PDU from sess */
5759         pSMB->MaxDataCount = cpu_to_le16(1000);
5760         pSMB->SetupCount = 1;
5761         pSMB->Reserved3 = 0;
5762         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5763         byte_count = 3 /* pad */  + params + count;
5764         pSMB->DataCount = cpu_to_le16(count);
5765         pSMB->ParameterCount = cpu_to_le16(params);
5766         pSMB->TotalDataCount = pSMB->DataCount;
5767         pSMB->TotalParameterCount = pSMB->ParameterCount;
5768         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5769         pSMB->DataOffset = cpu_to_le16(offset);
5770         pSMB->Fid = fid;
5771         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5772         pSMB->Reserved4 = 0;
5773         inc_rfc1001_len(pSMB, byte_count);
5774         pSMB->ByteCount = cpu_to_le16(byte_count);
5775         *data_offset = delete_file ? 1 : 0;
5776         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5777         if (rc)
5778                 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5779
5780         return rc;
5781 }
5782
5783 int
5784 CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5785                    const char *fileName, const FILE_BASIC_INFO *data,
5786                    const struct nls_table *nls_codepage, int remap)
5787 {
5788         TRANSACTION2_SPI_REQ *pSMB = NULL;
5789         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5790         int name_len;
5791         int rc = 0;
5792         int bytes_returned = 0;
5793         char *data_offset;
5794         __u16 params, param_offset, offset, byte_count, count;
5795
5796         cFYI(1, "In SetTimes");
5797
5798 SetTimesRetry:
5799         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5800                       (void **) &pSMBr);
5801         if (rc)
5802                 return rc;
5803
5804         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5805                 name_len =
5806                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5807                                        PATH_MAX, nls_codepage, remap);
5808                 name_len++;     /* trailing null */
5809                 name_len *= 2;
5810         } else {        /* BB improve the check for buffer overruns BB */
5811                 name_len = strnlen(fileName, PATH_MAX);
5812                 name_len++;     /* trailing null */
5813                 strncpy(pSMB->FileName, fileName, name_len);
5814         }
5815
5816         params = 6 + name_len;
5817         count = sizeof(FILE_BASIC_INFO);
5818         pSMB->MaxParameterCount = cpu_to_le16(2);
5819         /* BB find max SMB PDU from sess structure BB */
5820         pSMB->MaxDataCount = cpu_to_le16(1000);
5821         pSMB->MaxSetupCount = 0;
5822         pSMB->Reserved = 0;
5823         pSMB->Flags = 0;
5824         pSMB->Timeout = 0;
5825         pSMB->Reserved2 = 0;
5826         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5827                                 InformationLevel) - 4;
5828         offset = param_offset + params;
5829         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5830         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5831         pSMB->DataOffset = cpu_to_le16(offset);
5832         pSMB->SetupCount = 1;
5833         pSMB->Reserved3 = 0;
5834         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5835         byte_count = 3 /* pad */  + params + count;
5836
5837         pSMB->DataCount = cpu_to_le16(count);
5838         pSMB->ParameterCount = cpu_to_le16(params);
5839         pSMB->TotalDataCount = pSMB->DataCount;
5840         pSMB->TotalParameterCount = pSMB->ParameterCount;
5841         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5842                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5843         else
5844                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5845         pSMB->Reserved4 = 0;
5846         inc_rfc1001_len(pSMB, byte_count);
5847         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5848         pSMB->ByteCount = cpu_to_le16(byte_count);
5849         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5850                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5851         if (rc)
5852                 cFYI(1, "SetPathInfo (times) returned %d", rc);
5853
5854         cifs_buf_release(pSMB);
5855
5856         if (rc == -EAGAIN)
5857                 goto SetTimesRetry;
5858
5859         return rc;
5860 }
5861
5862 /* Can not be used to set time stamps yet (due to old DOS time format) */
5863 /* Can be used to set attributes */
5864 #if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
5865           handling it anyway and NT4 was what we thought it would be needed for
5866           Do not delete it until we prove whether needed for Win9x though */
5867 int
5868 CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5869                 __u16 dos_attrs, const struct nls_table *nls_codepage)
5870 {
5871         SETATTR_REQ *pSMB = NULL;
5872         SETATTR_RSP *pSMBr = NULL;
5873         int rc = 0;
5874         int bytes_returned;
5875         int name_len;
5876
5877         cFYI(1, "In SetAttrLegacy");
5878
5879 SetAttrLgcyRetry:
5880         rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5881                       (void **) &pSMBr);
5882         if (rc)
5883                 return rc;
5884
5885         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5886                 name_len =
5887                         ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5888                                        PATH_MAX, nls_codepage);
5889                 name_len++;     /* trailing null */
5890                 name_len *= 2;
5891         } else {        /* BB improve the check for buffer overruns BB */
5892                 name_len = strnlen(fileName, PATH_MAX);
5893                 name_len++;     /* trailing null */
5894                 strncpy(pSMB->fileName, fileName, name_len);
5895         }
5896         pSMB->attr = cpu_to_le16(dos_attrs);
5897         pSMB->BufferFormat = 0x04;
5898         inc_rfc1001_len(pSMB, name_len + 1);
5899         pSMB->ByteCount = cpu_to_le16(name_len + 1);
5900         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5901                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5902         if (rc)
5903                 cFYI(1, "Error in LegacySetAttr = %d", rc);
5904
5905         cifs_buf_release(pSMB);
5906
5907         if (rc == -EAGAIN)
5908                 goto SetAttrLgcyRetry;
5909
5910         return rc;
5911 }
5912 #endif /* temporarily unneeded SetAttr legacy function */
5913
5914 static void
5915 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5916                         const struct cifs_unix_set_info_args *args)
5917 {
5918         u64 mode = args->mode;
5919
5920         /*
5921          * Samba server ignores set of file size to zero due to bugs in some
5922          * older clients, but we should be precise - we use SetFileSize to
5923          * set file size and do not want to truncate file size to zero
5924          * accidentally as happened on one Samba server beta by putting
5925          * zero instead of -1 here
5926          */
5927         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5928         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5929         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5930         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5931         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5932         data_offset->Uid = cpu_to_le64(args->uid);
5933         data_offset->Gid = cpu_to_le64(args->gid);
5934         /* better to leave device as zero when it is  */
5935         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5936         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5937         data_offset->Permissions = cpu_to_le64(mode);
5938
5939         if (S_ISREG(mode))
5940                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5941         else if (S_ISDIR(mode))
5942                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5943         else if (S_ISLNK(mode))
5944                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5945         else if (S_ISCHR(mode))
5946                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5947         else if (S_ISBLK(mode))
5948                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5949         else if (S_ISFIFO(mode))
5950                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5951         else if (S_ISSOCK(mode))
5952                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5953 }
5954
5955 int
5956 CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5957                        const struct cifs_unix_set_info_args *args,
5958                        u16 fid, u32 pid_of_opener)
5959 {
5960         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5961         FILE_UNIX_BASIC_INFO *data_offset;
5962         int rc = 0;
5963         u16 params, param_offset, offset, byte_count, count;
5964
5965         cFYI(1, "Set Unix Info (via SetFileInfo)");
5966         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5967
5968         if (rc)
5969                 return rc;
5970
5971         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5972         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5973
5974         params = 6;
5975         pSMB->MaxSetupCount = 0;
5976         pSMB->Reserved = 0;
5977         pSMB->Flags = 0;
5978         pSMB->Timeout = 0;
5979         pSMB->Reserved2 = 0;
5980         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5981         offset = param_offset + params;
5982
5983         data_offset = (FILE_UNIX_BASIC_INFO *)
5984                                 ((char *)(&pSMB->hdr.Protocol) + offset);
5985         count = sizeof(FILE_UNIX_BASIC_INFO);
5986
5987         pSMB->MaxParameterCount = cpu_to_le16(2);
5988         /* BB find max SMB PDU from sess */
5989         pSMB->MaxDataCount = cpu_to_le16(1000);
5990         pSMB->SetupCount = 1;
5991         pSMB->Reserved3 = 0;
5992         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5993         byte_count = 3 /* pad */  + params + count;
5994         pSMB->DataCount = cpu_to_le16(count);
5995         pSMB->ParameterCount = cpu_to_le16(params);
5996         pSMB->TotalDataCount = pSMB->DataCount;
5997         pSMB->TotalParameterCount = pSMB->ParameterCount;
5998         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5999         pSMB->DataOffset = cpu_to_le16(offset);
6000         pSMB->Fid = fid;
6001         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6002         pSMB->Reserved4 = 0;
6003         inc_rfc1001_len(pSMB, byte_count);
6004         pSMB->ByteCount = cpu_to_le16(byte_count);
6005
6006         cifs_fill_unix_set_info(data_offset, args);
6007
6008         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6009         if (rc)
6010                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
6011
6012         /* Note: On -EAGAIN error only caller can retry on handle based calls
6013                 since file handle passed in no longer valid */
6014
6015         return rc;
6016 }
6017
6018 int
6019 CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
6020                        const struct cifs_unix_set_info_args *args,
6021                        const struct nls_table *nls_codepage, int remap)
6022 {
6023         TRANSACTION2_SPI_REQ *pSMB = NULL;
6024         TRANSACTION2_SPI_RSP *pSMBr = NULL;
6025         int name_len;
6026         int rc = 0;
6027         int bytes_returned = 0;
6028         FILE_UNIX_BASIC_INFO *data_offset;
6029         __u16 params, param_offset, offset, count, byte_count;
6030
6031         cFYI(1, "In SetUID/GID/Mode");
6032 setPermsRetry:
6033         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6034                       (void **) &pSMBr);
6035         if (rc)
6036                 return rc;
6037
6038         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6039                 name_len =
6040                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6041                                        PATH_MAX, nls_codepage, remap);
6042                 name_len++;     /* trailing null */
6043                 name_len *= 2;
6044         } else {        /* BB improve the check for buffer overruns BB */
6045                 name_len = strnlen(fileName, PATH_MAX);
6046                 name_len++;     /* trailing null */
6047                 strncpy(pSMB->FileName, fileName, name_len);
6048         }
6049
6050         params = 6 + name_len;
6051         count = sizeof(FILE_UNIX_BASIC_INFO);
6052         pSMB->MaxParameterCount = cpu_to_le16(2);
6053         /* BB find max SMB PDU from sess structure BB */
6054         pSMB->MaxDataCount = cpu_to_le16(1000);
6055         pSMB->MaxSetupCount = 0;
6056         pSMB->Reserved = 0;
6057         pSMB->Flags = 0;
6058         pSMB->Timeout = 0;
6059         pSMB->Reserved2 = 0;
6060         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6061                                 InformationLevel) - 4;
6062         offset = param_offset + params;
6063         data_offset =
6064             (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6065                                       offset);
6066         memset(data_offset, 0, count);
6067         pSMB->DataOffset = cpu_to_le16(offset);
6068         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6069         pSMB->SetupCount = 1;
6070         pSMB->Reserved3 = 0;
6071         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6072         byte_count = 3 /* pad */  + params + count;
6073         pSMB->ParameterCount = cpu_to_le16(params);
6074         pSMB->DataCount = cpu_to_le16(count);
6075         pSMB->TotalParameterCount = pSMB->ParameterCount;
6076         pSMB->TotalDataCount = pSMB->DataCount;
6077         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6078         pSMB->Reserved4 = 0;
6079         inc_rfc1001_len(pSMB, byte_count);
6080
6081         cifs_fill_unix_set_info(data_offset, args);
6082
6083         pSMB->ByteCount = cpu_to_le16(byte_count);
6084         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6085                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6086         if (rc)
6087                 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6088
6089         cifs_buf_release(pSMB);
6090         if (rc == -EAGAIN)
6091                 goto setPermsRetry;
6092         return rc;
6093 }
6094
6095 #ifdef CONFIG_CIFS_XATTR
6096 /*
6097  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6098  * function used by listxattr and getxattr type calls. When ea_name is set,
6099  * it looks for that attribute name and stuffs that value into the EAData
6100  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6101  * buffer. In both cases, the return value is either the length of the
6102  * resulting data or a negative error code. If EAData is a NULL pointer then
6103  * the data isn't copied to it, but the length is returned.
6104  */
6105 ssize_t
6106 CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
6107                 const unsigned char *searchName, const unsigned char *ea_name,
6108                 char *EAData, size_t buf_size,
6109                 const struct nls_table *nls_codepage, int remap)
6110 {
6111                 /* BB assumes one setup word */
6112         TRANSACTION2_QPI_REQ *pSMB = NULL;
6113         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6114         int rc = 0;
6115         int bytes_returned;
6116         int list_len;
6117         struct fealist *ea_response_data;
6118         struct fea *temp_fea;
6119         char *temp_ptr;
6120         char *end_of_smb;
6121         __u16 params, byte_count, data_offset;
6122         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6123
6124         cFYI(1, "In Query All EAs path %s", searchName);
6125 QAllEAsRetry:
6126         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6127                       (void **) &pSMBr);
6128         if (rc)
6129                 return rc;
6130
6131         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6132                 list_len =
6133                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6134                                        PATH_MAX, nls_codepage, remap);
6135                 list_len++;     /* trailing null */
6136                 list_len *= 2;
6137         } else {        /* BB improve the check for buffer overruns BB */
6138                 list_len = strnlen(searchName, PATH_MAX);
6139                 list_len++;     /* trailing null */
6140                 strncpy(pSMB->FileName, searchName, list_len);
6141         }
6142
6143         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6144         pSMB->TotalDataCount = 0;
6145         pSMB->MaxParameterCount = cpu_to_le16(2);
6146         /* BB find exact max SMB PDU from sess structure BB */
6147         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6148         pSMB->MaxSetupCount = 0;
6149         pSMB->Reserved = 0;
6150         pSMB->Flags = 0;
6151         pSMB->Timeout = 0;
6152         pSMB->Reserved2 = 0;
6153         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6154         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6155         pSMB->DataCount = 0;
6156         pSMB->DataOffset = 0;
6157         pSMB->SetupCount = 1;
6158         pSMB->Reserved3 = 0;
6159         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6160         byte_count = params + 1 /* pad */ ;
6161         pSMB->TotalParameterCount = cpu_to_le16(params);
6162         pSMB->ParameterCount = pSMB->TotalParameterCount;
6163         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6164         pSMB->Reserved4 = 0;
6165         inc_rfc1001_len(pSMB, byte_count);
6166         pSMB->ByteCount = cpu_to_le16(byte_count);
6167
6168         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6169                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6170         if (rc) {
6171                 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6172                 goto QAllEAsOut;
6173         }
6174
6175
6176         /* BB also check enough total bytes returned */
6177         /* BB we need to improve the validity checking
6178         of these trans2 responses */
6179
6180         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6181         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6182                 rc = -EIO;      /* bad smb */
6183                 goto QAllEAsOut;
6184         }
6185
6186         /* check that length of list is not more than bcc */
6187         /* check that each entry does not go beyond length
6188            of list */
6189         /* check that each element of each entry does not
6190            go beyond end of list */
6191         /* validate_trans2_offsets() */
6192         /* BB check if start of smb + data_offset > &bcc+ bcc */
6193
6194         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6195         ea_response_data = (struct fealist *)
6196                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6197
6198         list_len = le32_to_cpu(ea_response_data->list_len);
6199         cFYI(1, "ea length %d", list_len);
6200         if (list_len <= 8) {
6201                 cFYI(1, "empty EA list returned from server");
6202                 goto QAllEAsOut;
6203         }
6204
6205         /* make sure list_len doesn't go past end of SMB */
6206         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6207         if ((char *)ea_response_data + list_len > end_of_smb) {
6208                 cFYI(1, "EA list appears to go beyond SMB");
6209                 rc = -EIO;
6210                 goto QAllEAsOut;
6211         }
6212
6213         /* account for ea list len */
6214         list_len -= 4;
6215         temp_fea = ea_response_data->list;
6216         temp_ptr = (char *)temp_fea;
6217         while (list_len > 0) {
6218                 unsigned int name_len;
6219                 __u16 value_len;
6220
6221                 list_len -= 4;
6222                 temp_ptr += 4;
6223                 /* make sure we can read name_len and value_len */
6224                 if (list_len < 0) {
6225                         cFYI(1, "EA entry goes beyond length of list");
6226                         rc = -EIO;
6227                         goto QAllEAsOut;
6228                 }
6229
6230                 name_len = temp_fea->name_len;
6231                 value_len = le16_to_cpu(temp_fea->value_len);
6232                 list_len -= name_len + 1 + value_len;
6233                 if (list_len < 0) {
6234                         cFYI(1, "EA entry goes beyond length of list");
6235                         rc = -EIO;
6236                         goto QAllEAsOut;
6237                 }
6238
6239                 if (ea_name) {
6240                         if (ea_name_len == name_len &&
6241                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6242                                 temp_ptr += name_len + 1;
6243                                 rc = value_len;
6244                                 if (buf_size == 0)
6245                                         goto QAllEAsOut;
6246                                 if ((size_t)value_len > buf_size) {
6247                                         rc = -ERANGE;
6248                                         goto QAllEAsOut;
6249                                 }
6250                                 memcpy(EAData, temp_ptr, value_len);
6251                                 goto QAllEAsOut;
6252                         }
6253                 } else {
6254                         /* account for prefix user. and trailing null */
6255                         rc += (5 + 1 + name_len);
6256                         if (rc < (int) buf_size) {
6257                                 memcpy(EAData, "user.", 5);
6258                                 EAData += 5;
6259                                 memcpy(EAData, temp_ptr, name_len);
6260                                 EAData += name_len;
6261                                 /* null terminate name */
6262                                 *EAData = 0;
6263                                 ++EAData;
6264                         } else if (buf_size == 0) {
6265                                 /* skip copy - calc size only */
6266                         } else {
6267                                 /* stop before overrun buffer */
6268                                 rc = -ERANGE;
6269                                 break;
6270                         }
6271                 }
6272                 temp_ptr += name_len + 1 + value_len;
6273                 temp_fea = (struct fea *)temp_ptr;
6274         }
6275
6276         /* didn't find the named attribute */
6277         if (ea_name)
6278                 rc = -ENODATA;
6279
6280 QAllEAsOut:
6281         cifs_buf_release(pSMB);
6282         if (rc == -EAGAIN)
6283                 goto QAllEAsRetry;
6284
6285         return (ssize_t)rc;
6286 }
6287
6288 int
6289 CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
6290              const char *ea_name, const void *ea_value,
6291              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6292              int remap)
6293 {
6294         struct smb_com_transaction2_spi_req *pSMB = NULL;
6295         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6296         struct fealist *parm_data;
6297         int name_len;
6298         int rc = 0;
6299         int bytes_returned = 0;
6300         __u16 params, param_offset, byte_count, offset, count;
6301
6302         cFYI(1, "In SetEA");
6303 SetEARetry:
6304         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6305                       (void **) &pSMBr);
6306         if (rc)
6307                 return rc;
6308
6309         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6310                 name_len =
6311                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6312                                        PATH_MAX, nls_codepage, remap);
6313                 name_len++;     /* trailing null */
6314                 name_len *= 2;
6315         } else {        /* BB improve the check for buffer overruns BB */
6316                 name_len = strnlen(fileName, PATH_MAX);
6317                 name_len++;     /* trailing null */
6318                 strncpy(pSMB->FileName, fileName, name_len);
6319         }
6320
6321         params = 6 + name_len;
6322
6323         /* done calculating parms using name_len of file name,
6324         now use name_len to calculate length of ea name
6325         we are going to create in the inode xattrs */
6326         if (ea_name == NULL)
6327                 name_len = 0;
6328         else
6329                 name_len = strnlen(ea_name, 255);
6330
6331         count = sizeof(*parm_data) + ea_value_len + name_len;
6332         pSMB->MaxParameterCount = cpu_to_le16(2);
6333         /* BB find max SMB PDU from sess */
6334         pSMB->MaxDataCount = cpu_to_le16(1000);
6335         pSMB->MaxSetupCount = 0;
6336         pSMB->Reserved = 0;
6337         pSMB->Flags = 0;
6338         pSMB->Timeout = 0;
6339         pSMB->Reserved2 = 0;
6340         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6341                                 InformationLevel) - 4;
6342         offset = param_offset + params;
6343         pSMB->InformationLevel =
6344                 cpu_to_le16(SMB_SET_FILE_EA);
6345
6346         parm_data =
6347                 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6348                                        offset);
6349         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6350         pSMB->DataOffset = cpu_to_le16(offset);
6351         pSMB->SetupCount = 1;
6352         pSMB->Reserved3 = 0;
6353         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6354         byte_count = 3 /* pad */  + params + count;
6355         pSMB->DataCount = cpu_to_le16(count);
6356         parm_data->list_len = cpu_to_le32(count);
6357         parm_data->list[0].EA_flags = 0;
6358         /* we checked above that name len is less than 255 */
6359         parm_data->list[0].name_len = (__u8)name_len;
6360         /* EA names are always ASCII */
6361         if (ea_name)
6362                 strncpy(parm_data->list[0].name, ea_name, name_len);
6363         parm_data->list[0].name[name_len] = 0;
6364         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6365         /* caller ensures that ea_value_len is less than 64K but
6366         we need to ensure that it fits within the smb */
6367
6368         /*BB add length check to see if it would fit in
6369              negotiated SMB buffer size BB */
6370         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6371         if (ea_value_len)
6372                 memcpy(parm_data->list[0].name+name_len+1,
6373                        ea_value, ea_value_len);
6374
6375         pSMB->TotalDataCount = pSMB->DataCount;
6376         pSMB->ParameterCount = cpu_to_le16(params);
6377         pSMB->TotalParameterCount = pSMB->ParameterCount;
6378         pSMB->Reserved4 = 0;
6379         inc_rfc1001_len(pSMB, byte_count);
6380         pSMB->ByteCount = cpu_to_le16(byte_count);
6381         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6382                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6383         if (rc)
6384                 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6385
6386         cifs_buf_release(pSMB);
6387
6388         if (rc == -EAGAIN)
6389                 goto SetEARetry;
6390
6391         return rc;
6392 }
6393 #endif
6394
6395 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6396 /*
6397  *      Years ago the kernel added a "dnotify" function for Samba server,
6398  *      to allow network clients (such as Windows) to display updated
6399  *      lists of files in directory listings automatically when
6400  *      files are added by one user when another user has the
6401  *      same directory open on their desktop.  The Linux cifs kernel
6402  *      client hooked into the kernel side of this interface for
6403  *      the same reason, but ironically when the VFS moved from
6404  *      "dnotify" to "inotify" it became harder to plug in Linux
6405  *      network file system clients (the most obvious use case
6406  *      for notify interfaces is when multiple users can update
6407  *      the contents of the same directory - exactly what network
6408  *      file systems can do) although the server (Samba) could
6409  *      still use it.  For the short term we leave the worker
6410  *      function ifdeffed out (below) until inotify is fixed
6411  *      in the VFS to make it easier to plug in network file
6412  *      system clients.  If inotify turns out to be permanently
6413  *      incompatible for network fs clients, we could instead simply
6414  *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
6415  */
6416 int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
6417                   const int notify_subdirs, const __u16 netfid,
6418                   __u32 filter, struct file *pfile, int multishot,
6419                   const struct nls_table *nls_codepage)
6420 {
6421         int rc = 0;
6422         struct smb_com_transaction_change_notify_req *pSMB = NULL;
6423         struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6424         struct dir_notify_req *dnotify_req;
6425         int bytes_returned;
6426
6427         cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6428         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6429                       (void **) &pSMBr);
6430         if (rc)
6431                 return rc;
6432
6433         pSMB->TotalParameterCount = 0 ;
6434         pSMB->TotalDataCount = 0;
6435         pSMB->MaxParameterCount = cpu_to_le32(2);
6436         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6437         pSMB->MaxSetupCount = 4;
6438         pSMB->Reserved = 0;
6439         pSMB->ParameterOffset = 0;
6440         pSMB->DataCount = 0;
6441         pSMB->DataOffset = 0;
6442         pSMB->SetupCount = 4; /* single byte does not need le conversion */
6443         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6444         pSMB->ParameterCount = pSMB->TotalParameterCount;
6445         if (notify_subdirs)
6446                 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6447         pSMB->Reserved2 = 0;
6448         pSMB->CompletionFilter = cpu_to_le32(filter);
6449         pSMB->Fid = netfid; /* file handle always le */
6450         pSMB->ByteCount = 0;
6451
6452         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6453                          (struct smb_hdr *)pSMBr, &bytes_returned,
6454                          CIFS_ASYNC_OP);
6455         if (rc) {
6456                 cFYI(1, "Error in Notify = %d", rc);
6457         } else {
6458                 /* Add file to outstanding requests */
6459                 /* BB change to kmem cache alloc */
6460                 dnotify_req = kmalloc(
6461                                                 sizeof(struct dir_notify_req),
6462                                                  GFP_KERNEL);
6463                 if (dnotify_req) {
6464                         dnotify_req->Pid = pSMB->hdr.Pid;
6465                         dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6466                         dnotify_req->Mid = pSMB->hdr.Mid;
6467                         dnotify_req->Tid = pSMB->hdr.Tid;
6468                         dnotify_req->Uid = pSMB->hdr.Uid;
6469                         dnotify_req->netfid = netfid;
6470                         dnotify_req->pfile = pfile;
6471                         dnotify_req->filter = filter;
6472                         dnotify_req->multishot = multishot;
6473                         spin_lock(&GlobalMid_Lock);
6474                         list_add_tail(&dnotify_req->lhead,
6475                                         &GlobalDnotifyReqList);
6476                         spin_unlock(&GlobalMid_Lock);
6477                 } else
6478                         rc = -ENOMEM;
6479         }
6480         cifs_buf_release(pSMB);
6481         return rc;
6482 }
6483 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */