]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/cifs/cifssmb.c
cifs: call cifs_update_eof with i_lock held
[karo-tx-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         unsigned int rfclen = get_rfc1002_length(server->smallbuf);
1418         int remaining = rfclen + 4 - server->total_read;
1419         struct cifs_readdata *rdata = mid->callback_data;
1420
1421         while (remaining > 0) {
1422                 int length;
1423
1424                 length = cifs_read_from_socket(server, server->bigbuf,
1425                                 min_t(unsigned int, remaining,
1426                                         CIFSMaxBufSize + max_header_size()));
1427                 if (length < 0)
1428                         return length;
1429                 server->total_read += length;
1430                 remaining -= length;
1431         }
1432
1433         dequeue_mid(mid, rdata->result);
1434         return 0;
1435 }
1436
1437 static inline size_t
1438 read_rsp_size(void)
1439 {
1440         return sizeof(READ_RSP);
1441 }
1442
1443 static inline unsigned int
1444 read_data_offset(char *buf)
1445 {
1446         READ_RSP *rsp = (READ_RSP *)buf;
1447         return le16_to_cpu(rsp->DataOffset);
1448 }
1449
1450 static inline unsigned int
1451 read_data_length(char *buf)
1452 {
1453         READ_RSP *rsp = (READ_RSP *)buf;
1454         return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
1455                le16_to_cpu(rsp->DataLength);
1456 }
1457
1458 static int
1459 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1460 {
1461         int length, len;
1462         unsigned int data_offset, remaining, data_len;
1463         struct cifs_readdata *rdata = mid->callback_data;
1464         char *buf = server->smallbuf;
1465         unsigned int buflen = get_rfc1002_length(buf) + 4;
1466         u64 eof;
1467         pgoff_t eof_index;
1468         struct page *page, *tpage;
1469
1470         cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__,
1471                 mid->mid, rdata->offset, rdata->bytes);
1472
1473         /*
1474          * read the rest of READ_RSP header (sans Data array), or whatever we
1475          * can if there's not enough data. At this point, we've read down to
1476          * the Mid.
1477          */
1478         len = min_t(unsigned int, buflen, read_rsp_size()) - header_size() + 1;
1479
1480         rdata->iov[0].iov_base = buf + header_size() - 1;
1481         rdata->iov[0].iov_len = len;
1482
1483         length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1484         if (length < 0)
1485                 return length;
1486         server->total_read += length;
1487
1488         /* Was the SMB read successful? */
1489         rdata->result = map_smb_to_linux_error(buf, false);
1490         if (rdata->result != 0) {
1491                 cFYI(1, "%s: server returned error %d", __func__,
1492                         rdata->result);
1493                 return cifs_readv_discard(server, mid);
1494         }
1495
1496         /* Is there enough to get to the rest of the READ_RSP header? */
1497         if (server->total_read < read_rsp_size()) {
1498                 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1499                         __func__, server->total_read, read_rsp_size());
1500                 rdata->result = -EIO;
1501                 return cifs_readv_discard(server, mid);
1502         }
1503
1504         data_offset = read_data_offset(buf) + 4;
1505         if (data_offset < server->total_read) {
1506                 /*
1507                  * win2k8 sometimes sends an offset of 0 when the read
1508                  * is beyond the EOF. Treat it as if the data starts just after
1509                  * the header.
1510                  */
1511                 cFYI(1, "%s: data offset (%u) inside read response header",
1512                         __func__, data_offset);
1513                 data_offset = server->total_read;
1514         } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1515                 /* data_offset is beyond the end of smallbuf */
1516                 cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
1517                         __func__, data_offset);
1518                 rdata->result = -EIO;
1519                 return cifs_readv_discard(server, mid);
1520         }
1521
1522         cFYI(1, "%s: total_read=%u data_offset=%u", __func__,
1523                 server->total_read, data_offset);
1524
1525         len = data_offset - server->total_read;
1526         if (len > 0) {
1527                 /* read any junk before data into the rest of smallbuf */
1528                 rdata->iov[0].iov_base = buf + server->total_read;
1529                 rdata->iov[0].iov_len = len;
1530                 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1531                 if (length < 0)
1532                         return length;
1533                 server->total_read += length;
1534         }
1535
1536         /* set up first iov for signature check */
1537         rdata->iov[0].iov_base = buf;
1538         rdata->iov[0].iov_len = server->total_read;
1539         cFYI(1, "0: iov_base=%p iov_len=%zu",
1540                 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1541
1542         /* how much data is in the response? */
1543         data_len = read_data_length(buf);
1544         if (data_offset + data_len > buflen) {
1545                 /* data_len is corrupt -- discard frame */
1546                 rdata->result = -EIO;
1547                 return cifs_readv_discard(server, mid);
1548         }
1549
1550         /* marshal up the page array */
1551         len = 0;
1552         remaining = data_len;
1553         rdata->nr_iov = 1;
1554
1555         /* determine the eof that the server (probably) has */
1556         eof = CIFS_I(rdata->mapping->host)->server_eof;
1557         eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
1558         cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
1559
1560         list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1561                 if (remaining >= PAGE_CACHE_SIZE) {
1562                         /* enough data to fill the page */
1563                         rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1564                         rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
1565                         cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1566                                 rdata->nr_iov, page->index,
1567                                 rdata->iov[rdata->nr_iov].iov_base,
1568                                 rdata->iov[rdata->nr_iov].iov_len);
1569                         ++rdata->nr_iov;
1570                         len += PAGE_CACHE_SIZE;
1571                         remaining -= PAGE_CACHE_SIZE;
1572                 } else if (remaining > 0) {
1573                         /* enough for partial page, fill and zero the rest */
1574                         rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1575                         rdata->iov[rdata->nr_iov].iov_len = remaining;
1576                         cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1577                                 rdata->nr_iov, page->index,
1578                                 rdata->iov[rdata->nr_iov].iov_base,
1579                                 rdata->iov[rdata->nr_iov].iov_len);
1580                         memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
1581                                 '\0', PAGE_CACHE_SIZE - remaining);
1582                         ++rdata->nr_iov;
1583                         len += remaining;
1584                         remaining = 0;
1585                 } else if (page->index > eof_index) {
1586                         /*
1587                          * The VFS will not try to do readahead past the
1588                          * i_size, but it's possible that we have outstanding
1589                          * writes with gaps in the middle and the i_size hasn't
1590                          * caught up yet. Populate those with zeroed out pages
1591                          * to prevent the VFS from repeatedly attempting to
1592                          * fill them until the writes are flushed.
1593                          */
1594                         zero_user(page, 0, PAGE_CACHE_SIZE);
1595                         list_del(&page->lru);
1596                         lru_cache_add_file(page);
1597                         flush_dcache_page(page);
1598                         SetPageUptodate(page);
1599                         unlock_page(page);
1600                         page_cache_release(page);
1601                 } else {
1602                         /* no need to hold page hostage */
1603                         list_del(&page->lru);
1604                         lru_cache_add_file(page);
1605                         unlock_page(page);
1606                         page_cache_release(page);
1607                 }
1608         }
1609
1610         /* issue the read if we have any iovecs left to fill */
1611         if (rdata->nr_iov > 1) {
1612                 length = cifs_readv_from_socket(server, &rdata->iov[1],
1613                                                 rdata->nr_iov - 1, len);
1614                 if (length < 0)
1615                         return length;
1616                 server->total_read += length;
1617         } else {
1618                 length = 0;
1619         }
1620
1621         rdata->bytes = length;
1622
1623         cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read,
1624                 buflen, remaining);
1625
1626         /* discard anything left over */
1627         if (server->total_read < buflen)
1628                 return cifs_readv_discard(server, mid);
1629
1630         dequeue_mid(mid, false);
1631         return length;
1632 }
1633
1634 static void
1635 cifs_readv_complete(struct work_struct *work)
1636 {
1637         struct cifs_readdata *rdata = container_of(work,
1638                                                 struct cifs_readdata, work);
1639         struct page *page, *tpage;
1640
1641         list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1642                 list_del(&page->lru);
1643                 lru_cache_add_file(page);
1644
1645                 if (rdata->result == 0) {
1646                         kunmap(page);
1647                         flush_dcache_page(page);
1648                         SetPageUptodate(page);
1649                 }
1650
1651                 unlock_page(page);
1652
1653                 if (rdata->result == 0)
1654                         cifs_readpage_to_fscache(rdata->mapping->host, page);
1655
1656                 page_cache_release(page);
1657         }
1658         cifs_readdata_free(rdata);
1659 }
1660
1661 static void
1662 cifs_readv_callback(struct mid_q_entry *mid)
1663 {
1664         struct cifs_readdata *rdata = mid->callback_data;
1665         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1666         struct TCP_Server_Info *server = tcon->ses->server;
1667
1668         cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__,
1669                 mid->mid, mid->mid_state, rdata->result, rdata->bytes);
1670
1671         switch (mid->mid_state) {
1672         case MID_RESPONSE_RECEIVED:
1673                 /* result already set, check signature */
1674                 if (server->sec_mode &
1675                     (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1676                         if (cifs_verify_signature(rdata->iov, rdata->nr_iov,
1677                                           server, mid->sequence_number + 1))
1678                                 cERROR(1, "Unexpected SMB signature");
1679                 }
1680                 /* FIXME: should this be counted toward the initiating task? */
1681                 task_io_account_read(rdata->bytes);
1682                 cifs_stats_bytes_read(tcon, rdata->bytes);
1683                 break;
1684         case MID_REQUEST_SUBMITTED:
1685         case MID_RETRY_NEEDED:
1686                 rdata->result = -EAGAIN;
1687                 break;
1688         default:
1689                 rdata->result = -EIO;
1690         }
1691
1692         queue_work(cifsiod_wq, &rdata->work);
1693         DeleteMidQEntry(mid);
1694         cifs_add_credits(server, 1);
1695 }
1696
1697 /* cifs_async_readv - send an async write, and set up mid to handle result */
1698 int
1699 cifs_async_readv(struct cifs_readdata *rdata)
1700 {
1701         int rc;
1702         READ_REQ *smb = NULL;
1703         int wct;
1704         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1705
1706         cFYI(1, "%s: offset=%llu bytes=%u", __func__,
1707                 rdata->offset, rdata->bytes);
1708
1709         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1710                 wct = 12;
1711         else {
1712                 wct = 10; /* old style read */
1713                 if ((rdata->offset >> 32) > 0)  {
1714                         /* can not handle this big offset for old */
1715                         return -EIO;
1716                 }
1717         }
1718
1719         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1720         if (rc)
1721                 return rc;
1722
1723         smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1724         smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1725
1726         smb->AndXCommand = 0xFF;        /* none */
1727         smb->Fid = rdata->cfile->netfid;
1728         smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1729         if (wct == 12)
1730                 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1731         smb->Remaining = 0;
1732         smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1733         smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1734         if (wct == 12)
1735                 smb->ByteCount = 0;
1736         else {
1737                 /* old style read */
1738                 struct smb_com_readx_req *smbr =
1739                         (struct smb_com_readx_req *)smb;
1740                 smbr->ByteCount = 0;
1741         }
1742
1743         /* 4 for RFC1001 length + 1 for BCC */
1744         rdata->iov[0].iov_base = smb;
1745         rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1746
1747         rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
1748                              cifs_readv_receive, cifs_readv_callback,
1749                              rdata, false);
1750
1751         if (rc == 0)
1752                 cifs_stats_inc(&tcon->num_reads);
1753
1754         cifs_small_buf_release(smb);
1755         return rc;
1756 }
1757
1758 int
1759 CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
1760             char **buf, int *pbuf_type)
1761 {
1762         int rc = -EACCES;
1763         READ_REQ *pSMB = NULL;
1764         READ_RSP *pSMBr = NULL;
1765         char *pReadData = NULL;
1766         int wct;
1767         int resp_buf_type = 0;
1768         struct kvec iov[1];
1769         __u32 pid = io_parms->pid;
1770         __u16 netfid = io_parms->netfid;
1771         __u64 offset = io_parms->offset;
1772         struct cifs_tcon *tcon = io_parms->tcon;
1773         unsigned int count = io_parms->length;
1774
1775         cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1776         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1777                 wct = 12;
1778         else {
1779                 wct = 10; /* old style read */
1780                 if ((offset >> 32) > 0)  {
1781                         /* can not handle this big offset for old */
1782                         return -EIO;
1783                 }
1784         }
1785
1786         *nbytes = 0;
1787         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1788         if (rc)
1789                 return rc;
1790
1791         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1792         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1793
1794         /* tcon and ses pointer are checked in smb_init */
1795         if (tcon->ses->server == NULL)
1796                 return -ECONNABORTED;
1797
1798         pSMB->AndXCommand = 0xFF;       /* none */
1799         pSMB->Fid = netfid;
1800         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1801         if (wct == 12)
1802                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1803
1804         pSMB->Remaining = 0;
1805         pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1806         pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1807         if (wct == 12)
1808                 pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1809         else {
1810                 /* old style read */
1811                 struct smb_com_readx_req *pSMBW =
1812                         (struct smb_com_readx_req *)pSMB;
1813                 pSMBW->ByteCount = 0;
1814         }
1815
1816         iov[0].iov_base = (char *)pSMB;
1817         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1818         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1819                          &resp_buf_type, CIFS_LOG_ERROR);
1820         cifs_stats_inc(&tcon->num_reads);
1821         pSMBr = (READ_RSP *)iov[0].iov_base;
1822         if (rc) {
1823                 cERROR(1, "Send error in read = %d", rc);
1824         } else {
1825                 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1826                 data_length = data_length << 16;
1827                 data_length += le16_to_cpu(pSMBr->DataLength);
1828                 *nbytes = data_length;
1829
1830                 /*check that DataLength would not go beyond end of SMB */
1831                 if ((data_length > CIFSMaxBufSize)
1832                                 || (data_length > count)) {
1833                         cFYI(1, "bad length %d for count %d",
1834                                  data_length, count);
1835                         rc = -EIO;
1836                         *nbytes = 0;
1837                 } else {
1838                         pReadData = (char *) (&pSMBr->hdr.Protocol) +
1839                                         le16_to_cpu(pSMBr->DataOffset);
1840 /*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
1841                                 cERROR(1, "Faulting on read rc = %d",rc);
1842                                 rc = -EFAULT;
1843                         }*/ /* can not use copy_to_user when using page cache*/
1844                         if (*buf)
1845                                 memcpy(*buf, pReadData, data_length);
1846                 }
1847         }
1848
1849 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1850         if (*buf) {
1851                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1852                         cifs_small_buf_release(iov[0].iov_base);
1853                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1854                         cifs_buf_release(iov[0].iov_base);
1855         } else if (resp_buf_type != CIFS_NO_BUFFER) {
1856                 /* return buffer to caller to free */
1857                 *buf = iov[0].iov_base;
1858                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1859                         *pbuf_type = CIFS_SMALL_BUFFER;
1860                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1861                         *pbuf_type = CIFS_LARGE_BUFFER;
1862         } /* else no valid buffer on return - leave as null */
1863
1864         /* Note: On -EAGAIN error only caller can retry on handle based calls
1865                 since file handle passed in no longer valid */
1866         return rc;
1867 }
1868
1869
1870 int
1871 CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
1872              unsigned int *nbytes, const char *buf,
1873              const char __user *ubuf, const int long_op)
1874 {
1875         int rc = -EACCES;
1876         WRITE_REQ *pSMB = NULL;
1877         WRITE_RSP *pSMBr = NULL;
1878         int bytes_returned, wct;
1879         __u32 bytes_sent;
1880         __u16 byte_count;
1881         __u32 pid = io_parms->pid;
1882         __u16 netfid = io_parms->netfid;
1883         __u64 offset = io_parms->offset;
1884         struct cifs_tcon *tcon = io_parms->tcon;
1885         unsigned int count = io_parms->length;
1886
1887         *nbytes = 0;
1888
1889         /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1890         if (tcon->ses == NULL)
1891                 return -ECONNABORTED;
1892
1893         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1894                 wct = 14;
1895         else {
1896                 wct = 12;
1897                 if ((offset >> 32) > 0) {
1898                         /* can not handle big offset for old srv */
1899                         return -EIO;
1900                 }
1901         }
1902
1903         rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1904                       (void **) &pSMBr);
1905         if (rc)
1906                 return rc;
1907
1908         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1909         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1910
1911         /* tcon and ses pointer are checked in smb_init */
1912         if (tcon->ses->server == NULL)
1913                 return -ECONNABORTED;
1914
1915         pSMB->AndXCommand = 0xFF;       /* none */
1916         pSMB->Fid = netfid;
1917         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1918         if (wct == 14)
1919                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1920
1921         pSMB->Reserved = 0xFFFFFFFF;
1922         pSMB->WriteMode = 0;
1923         pSMB->Remaining = 0;
1924
1925         /* Can increase buffer size if buffer is big enough in some cases ie we
1926         can send more if LARGE_WRITE_X capability returned by the server and if
1927         our buffer is big enough or if we convert to iovecs on socket writes
1928         and eliminate the copy to the CIFS buffer */
1929         if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1930                 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1931         } else {
1932                 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1933                          & ~0xFF;
1934         }
1935
1936         if (bytes_sent > count)
1937                 bytes_sent = count;
1938         pSMB->DataOffset =
1939                 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1940         if (buf)
1941                 memcpy(pSMB->Data, buf, bytes_sent);
1942         else if (ubuf) {
1943                 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1944                         cifs_buf_release(pSMB);
1945                         return -EFAULT;
1946                 }
1947         } else if (count != 0) {
1948                 /* No buffer */
1949                 cifs_buf_release(pSMB);
1950                 return -EINVAL;
1951         } /* else setting file size with write of zero bytes */
1952         if (wct == 14)
1953                 byte_count = bytes_sent + 1; /* pad */
1954         else /* wct == 12 */
1955                 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1956
1957         pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1958         pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1959         inc_rfc1001_len(pSMB, byte_count);
1960
1961         if (wct == 14)
1962                 pSMB->ByteCount = cpu_to_le16(byte_count);
1963         else { /* old style write has byte count 4 bytes earlier
1964                   so 4 bytes pad  */
1965                 struct smb_com_writex_req *pSMBW =
1966                         (struct smb_com_writex_req *)pSMB;
1967                 pSMBW->ByteCount = cpu_to_le16(byte_count);
1968         }
1969
1970         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1971                          (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1972         cifs_stats_inc(&tcon->num_writes);
1973         if (rc) {
1974                 cFYI(1, "Send error in write = %d", rc);
1975         } else {
1976                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1977                 *nbytes = (*nbytes) << 16;
1978                 *nbytes += le16_to_cpu(pSMBr->Count);
1979
1980                 /*
1981                  * Mask off high 16 bits when bytes written as returned by the
1982                  * server is greater than bytes requested by the client. Some
1983                  * OS/2 servers are known to set incorrect CountHigh values.
1984                  */
1985                 if (*nbytes > count)
1986                         *nbytes &= 0xFFFF;
1987         }
1988
1989         cifs_buf_release(pSMB);
1990
1991         /* Note: On -EAGAIN error only caller can retry on handle based calls
1992                 since file handle passed in no longer valid */
1993
1994         return rc;
1995 }
1996
1997 void
1998 cifs_writedata_release(struct kref *refcount)
1999 {
2000         struct cifs_writedata *wdata = container_of(refcount,
2001                                         struct cifs_writedata, refcount);
2002
2003         if (wdata->cfile)
2004                 cifsFileInfo_put(wdata->cfile);
2005
2006         kfree(wdata);
2007 }
2008
2009 /*
2010  * Write failed with a retryable error. Resend the write request. It's also
2011  * possible that the page was redirtied so re-clean the page.
2012  */
2013 static void
2014 cifs_writev_requeue(struct cifs_writedata *wdata)
2015 {
2016         int i, rc;
2017         struct inode *inode = wdata->cfile->dentry->d_inode;
2018
2019         for (i = 0; i < wdata->nr_pages; i++) {
2020                 lock_page(wdata->pages[i]);
2021                 clear_page_dirty_for_io(wdata->pages[i]);
2022         }
2023
2024         do {
2025                 rc = cifs_async_writev(wdata);
2026         } while (rc == -EAGAIN);
2027
2028         for (i = 0; i < wdata->nr_pages; i++) {
2029                 if (rc != 0)
2030                         SetPageError(wdata->pages[i]);
2031                 unlock_page(wdata->pages[i]);
2032         }
2033
2034         mapping_set_error(inode->i_mapping, rc);
2035         kref_put(&wdata->refcount, cifs_writedata_release);
2036 }
2037
2038 void
2039 cifs_writev_complete(struct work_struct *work)
2040 {
2041         struct cifs_writedata *wdata = container_of(work,
2042                                                 struct cifs_writedata, work);
2043         struct inode *inode = wdata->cfile->dentry->d_inode;
2044         int i = 0;
2045
2046         if (wdata->result == 0) {
2047                 spin_lock(&inode->i_lock);
2048                 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2049                 spin_unlock(&inode->i_lock);
2050                 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2051                                          wdata->bytes);
2052         } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2053                 return cifs_writev_requeue(wdata);
2054
2055         for (i = 0; i < wdata->nr_pages; i++) {
2056                 struct page *page = wdata->pages[i];
2057                 if (wdata->result == -EAGAIN)
2058                         __set_page_dirty_nobuffers(page);
2059                 else if (wdata->result < 0)
2060                         SetPageError(page);
2061                 end_page_writeback(page);
2062                 page_cache_release(page);
2063         }
2064         if (wdata->result != -EAGAIN)
2065                 mapping_set_error(inode->i_mapping, wdata->result);
2066         kref_put(&wdata->refcount, cifs_writedata_release);
2067 }
2068
2069 struct cifs_writedata *
2070 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2071 {
2072         struct cifs_writedata *wdata;
2073
2074         /* this would overflow */
2075         if (nr_pages == 0) {
2076                 cERROR(1, "%s: called with nr_pages == 0!", __func__);
2077                 return NULL;
2078         }
2079
2080         /* writedata + number of page pointers */
2081         wdata = kzalloc(sizeof(*wdata) +
2082                         sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
2083         if (wdata != NULL) {
2084                 INIT_WORK(&wdata->work, complete);
2085                 kref_init(&wdata->refcount);
2086         }
2087         return wdata;
2088 }
2089
2090 /*
2091  * Check the mid_state and signature on received buffer (if any), and queue the
2092  * workqueue completion task.
2093  */
2094 static void
2095 cifs_writev_callback(struct mid_q_entry *mid)
2096 {
2097         struct cifs_writedata *wdata = mid->callback_data;
2098         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2099         unsigned int written;
2100         WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2101
2102         switch (mid->mid_state) {
2103         case MID_RESPONSE_RECEIVED:
2104                 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2105                 if (wdata->result != 0)
2106                         break;
2107
2108                 written = le16_to_cpu(smb->CountHigh);
2109                 written <<= 16;
2110                 written += le16_to_cpu(smb->Count);
2111                 /*
2112                  * Mask off high 16 bits when bytes written as returned
2113                  * by the server is greater than bytes requested by the
2114                  * client. OS/2 servers are known to set incorrect
2115                  * CountHigh values.
2116                  */
2117                 if (written > wdata->bytes)
2118                         written &= 0xFFFF;
2119
2120                 if (written < wdata->bytes)
2121                         wdata->result = -ENOSPC;
2122                 else
2123                         wdata->bytes = written;
2124                 break;
2125         case MID_REQUEST_SUBMITTED:
2126         case MID_RETRY_NEEDED:
2127                 wdata->result = -EAGAIN;
2128                 break;
2129         default:
2130                 wdata->result = -EIO;
2131                 break;
2132         }
2133
2134         queue_work(cifsiod_wq, &wdata->work);
2135         DeleteMidQEntry(mid);
2136         cifs_add_credits(tcon->ses->server, 1);
2137 }
2138
2139 /* cifs_async_writev - send an async write, and set up mid to handle result */
2140 int
2141 cifs_async_writev(struct cifs_writedata *wdata)
2142 {
2143         int i, rc = -EACCES;
2144         WRITE_REQ *smb = NULL;
2145         int wct;
2146         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2147         struct kvec *iov = NULL;
2148
2149         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2150                 wct = 14;
2151         } else {
2152                 wct = 12;
2153                 if (wdata->offset >> 32 > 0) {
2154                         /* can not handle big offset for old srv */
2155                         return -EIO;
2156                 }
2157         }
2158
2159         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2160         if (rc)
2161                 goto async_writev_out;
2162
2163         /* 1 iov per page + 1 for header */
2164         iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
2165         if (iov == NULL) {
2166                 rc = -ENOMEM;
2167                 goto async_writev_out;
2168         }
2169
2170         smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2171         smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2172
2173         smb->AndXCommand = 0xFF;        /* none */
2174         smb->Fid = wdata->cfile->netfid;
2175         smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2176         if (wct == 14)
2177                 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2178         smb->Reserved = 0xFFFFFFFF;
2179         smb->WriteMode = 0;
2180         smb->Remaining = 0;
2181
2182         smb->DataOffset =
2183             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2184
2185         /* 4 for RFC1001 length + 1 for BCC */
2186         iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2187         iov[0].iov_base = smb;
2188
2189         /*
2190          * This function should marshal up the page array into the kvec
2191          * array, reserving [0] for the header. It should kmap the pages
2192          * and set the iov_len properly for each one. It may also set
2193          * wdata->bytes too.
2194          */
2195         wdata->marshal_iov(iov, wdata);
2196
2197         cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2198
2199         smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2200         smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2201
2202         if (wct == 14) {
2203                 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2204                 put_bcc(wdata->bytes + 1, &smb->hdr);
2205         } else {
2206                 /* wct == 12 */
2207                 struct smb_com_writex_req *smbw =
2208                                 (struct smb_com_writex_req *)smb;
2209                 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2210                 put_bcc(wdata->bytes + 5, &smbw->hdr);
2211                 iov[0].iov_len += 4; /* pad bigger by four bytes */
2212         }
2213
2214         kref_get(&wdata->refcount);
2215         rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
2216                              NULL, cifs_writev_callback, wdata, false);
2217
2218         if (rc == 0)
2219                 cifs_stats_inc(&tcon->num_writes);
2220         else
2221                 kref_put(&wdata->refcount, cifs_writedata_release);
2222
2223         /* send is done, unmap pages */
2224         for (i = 0; i < wdata->nr_pages; i++)
2225                 kunmap(wdata->pages[i]);
2226
2227 async_writev_out:
2228         cifs_small_buf_release(smb);
2229         kfree(iov);
2230         return rc;
2231 }
2232
2233 int
2234 CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
2235               unsigned int *nbytes, struct kvec *iov, int n_vec,
2236               const int long_op)
2237 {
2238         int rc = -EACCES;
2239         WRITE_REQ *pSMB = NULL;
2240         int wct;
2241         int smb_hdr_len;
2242         int resp_buf_type = 0;
2243         __u32 pid = io_parms->pid;
2244         __u16 netfid = io_parms->netfid;
2245         __u64 offset = io_parms->offset;
2246         struct cifs_tcon *tcon = io_parms->tcon;
2247         unsigned int count = io_parms->length;
2248
2249         *nbytes = 0;
2250
2251         cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
2252
2253         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2254                 wct = 14;
2255         } else {
2256                 wct = 12;
2257                 if ((offset >> 32) > 0) {
2258                         /* can not handle big offset for old srv */
2259                         return -EIO;
2260                 }
2261         }
2262         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2263         if (rc)
2264                 return rc;
2265
2266         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2267         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2268
2269         /* tcon and ses pointer are checked in smb_init */
2270         if (tcon->ses->server == NULL)
2271                 return -ECONNABORTED;
2272
2273         pSMB->AndXCommand = 0xFF;       /* none */
2274         pSMB->Fid = netfid;
2275         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2276         if (wct == 14)
2277                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2278         pSMB->Reserved = 0xFFFFFFFF;
2279         pSMB->WriteMode = 0;
2280         pSMB->Remaining = 0;
2281
2282         pSMB->DataOffset =
2283             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2284
2285         pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2286         pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2287         /* header + 1 byte pad */
2288         smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2289         if (wct == 14)
2290                 inc_rfc1001_len(pSMB, count + 1);
2291         else /* wct == 12 */
2292                 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2293         if (wct == 14)
2294                 pSMB->ByteCount = cpu_to_le16(count + 1);
2295         else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2296                 struct smb_com_writex_req *pSMBW =
2297                                 (struct smb_com_writex_req *)pSMB;
2298                 pSMBW->ByteCount = cpu_to_le16(count + 5);
2299         }
2300         iov[0].iov_base = pSMB;
2301         if (wct == 14)
2302                 iov[0].iov_len = smb_hdr_len + 4;
2303         else /* wct == 12 pad bigger by four bytes */
2304                 iov[0].iov_len = smb_hdr_len + 8;
2305
2306
2307         rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
2308                           long_op);
2309         cifs_stats_inc(&tcon->num_writes);
2310         if (rc) {
2311                 cFYI(1, "Send error Write2 = %d", rc);
2312         } else if (resp_buf_type == 0) {
2313                 /* presumably this can not happen, but best to be safe */
2314                 rc = -EIO;
2315         } else {
2316                 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2317                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2318                 *nbytes = (*nbytes) << 16;
2319                 *nbytes += le16_to_cpu(pSMBr->Count);
2320
2321                 /*
2322                  * Mask off high 16 bits when bytes written as returned by the
2323                  * server is greater than bytes requested by the client. OS/2
2324                  * servers are known to set incorrect CountHigh values.
2325                  */
2326                 if (*nbytes > count)
2327                         *nbytes &= 0xFFFF;
2328         }
2329
2330 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2331         if (resp_buf_type == CIFS_SMALL_BUFFER)
2332                 cifs_small_buf_release(iov[0].iov_base);
2333         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2334                 cifs_buf_release(iov[0].iov_base);
2335
2336         /* Note: On -EAGAIN error only caller can retry on handle based calls
2337                 since file handle passed in no longer valid */
2338
2339         return rc;
2340 }
2341
2342 int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
2343                const __u8 lock_type, const __u32 num_unlock,
2344                const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2345 {
2346         int rc = 0;
2347         LOCK_REQ *pSMB = NULL;
2348         struct kvec iov[2];
2349         int resp_buf_type;
2350         __u16 count;
2351
2352         cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2353
2354         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2355         if (rc)
2356                 return rc;
2357
2358         pSMB->Timeout = 0;
2359         pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2360         pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2361         pSMB->LockType = lock_type;
2362         pSMB->AndXCommand = 0xFF; /* none */
2363         pSMB->Fid = netfid; /* netfid stays le */
2364
2365         count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2366         inc_rfc1001_len(pSMB, count);
2367         pSMB->ByteCount = cpu_to_le16(count);
2368
2369         iov[0].iov_base = (char *)pSMB;
2370         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2371                          (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2372         iov[1].iov_base = (char *)buf;
2373         iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2374
2375         cifs_stats_inc(&tcon->num_locks);
2376         rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2377         if (rc)
2378                 cFYI(1, "Send error in cifs_lockv = %d", rc);
2379
2380         return rc;
2381 }
2382
2383 int
2384 CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
2385             const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2386             const __u64 offset, const __u32 numUnlock,
2387             const __u32 numLock, const __u8 lockType,
2388             const bool waitFlag, const __u8 oplock_level)
2389 {
2390         int rc = 0;
2391         LOCK_REQ *pSMB = NULL;
2392 /*      LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2393         int bytes_returned;
2394         int timeout = 0;
2395         __u16 count;
2396
2397         cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2398         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2399
2400         if (rc)
2401                 return rc;
2402
2403         if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2404                 timeout = CIFS_ASYNC_OP; /* no response expected */
2405                 pSMB->Timeout = 0;
2406         } else if (waitFlag) {
2407                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2408                 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2409         } else {
2410                 pSMB->Timeout = 0;
2411         }
2412
2413         pSMB->NumberOfLocks = cpu_to_le16(numLock);
2414         pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2415         pSMB->LockType = lockType;
2416         pSMB->OplockLevel = oplock_level;
2417         pSMB->AndXCommand = 0xFF;       /* none */
2418         pSMB->Fid = smb_file_id; /* netfid stays le */
2419
2420         if ((numLock != 0) || (numUnlock != 0)) {
2421                 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2422                 /* BB where to store pid high? */
2423                 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2424                 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2425                 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2426                 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2427                 count = sizeof(LOCKING_ANDX_RANGE);
2428         } else {
2429                 /* oplock break */
2430                 count = 0;
2431         }
2432         inc_rfc1001_len(pSMB, count);
2433         pSMB->ByteCount = cpu_to_le16(count);
2434
2435         if (waitFlag) {
2436                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2437                         (struct smb_hdr *) pSMB, &bytes_returned);
2438                 cifs_small_buf_release(pSMB);
2439         } else {
2440                 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, timeout);
2441                 /* SMB buffer freed by function above */
2442         }
2443         cifs_stats_inc(&tcon->num_locks);
2444         if (rc)
2445                 cFYI(1, "Send error in Lock = %d", rc);
2446
2447         /* Note: On -EAGAIN error only caller can retry on handle based calls
2448         since file handle passed in no longer valid */
2449         return rc;
2450 }
2451
2452 int
2453 CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
2454                 const __u16 smb_file_id, const __u32 netpid, const int get_flag,
2455                 const __u64 len, struct file_lock *pLockData,
2456                 const __u16 lock_type, const bool waitFlag)
2457 {
2458         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2459         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2460         struct cifs_posix_lock *parm_data;
2461         int rc = 0;
2462         int timeout = 0;
2463         int bytes_returned = 0;
2464         int resp_buf_type = 0;
2465         __u16 params, param_offset, offset, byte_count, count;
2466         struct kvec iov[1];
2467
2468         cFYI(1, "Posix Lock");
2469
2470         if (pLockData == NULL)
2471                 return -EINVAL;
2472
2473         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2474
2475         if (rc)
2476                 return rc;
2477
2478         pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2479
2480         params = 6;
2481         pSMB->MaxSetupCount = 0;
2482         pSMB->Reserved = 0;
2483         pSMB->Flags = 0;
2484         pSMB->Reserved2 = 0;
2485         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2486         offset = param_offset + params;
2487
2488         count = sizeof(struct cifs_posix_lock);
2489         pSMB->MaxParameterCount = cpu_to_le16(2);
2490         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2491         pSMB->SetupCount = 1;
2492         pSMB->Reserved3 = 0;
2493         if (get_flag)
2494                 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2495         else
2496                 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2497         byte_count = 3 /* pad */  + params + count;
2498         pSMB->DataCount = cpu_to_le16(count);
2499         pSMB->ParameterCount = cpu_to_le16(params);
2500         pSMB->TotalDataCount = pSMB->DataCount;
2501         pSMB->TotalParameterCount = pSMB->ParameterCount;
2502         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2503         parm_data = (struct cifs_posix_lock *)
2504                         (((char *) &pSMB->hdr.Protocol) + offset);
2505
2506         parm_data->lock_type = cpu_to_le16(lock_type);
2507         if (waitFlag) {
2508                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2509                 parm_data->lock_flags = cpu_to_le16(1);
2510                 pSMB->Timeout = cpu_to_le32(-1);
2511         } else
2512                 pSMB->Timeout = 0;
2513
2514         parm_data->pid = cpu_to_le32(netpid);
2515         parm_data->start = cpu_to_le64(pLockData->fl_start);
2516         parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2517
2518         pSMB->DataOffset = cpu_to_le16(offset);
2519         pSMB->Fid = smb_file_id;
2520         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2521         pSMB->Reserved4 = 0;
2522         inc_rfc1001_len(pSMB, byte_count);
2523         pSMB->ByteCount = cpu_to_le16(byte_count);
2524         if (waitFlag) {
2525                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2526                         (struct smb_hdr *) pSMBr, &bytes_returned);
2527         } else {
2528                 iov[0].iov_base = (char *)pSMB;
2529                 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2530                 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2531                                 &resp_buf_type, timeout);
2532                 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2533                                 not try to free it twice below on exit */
2534                 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2535         }
2536
2537         if (rc) {
2538                 cFYI(1, "Send error in Posix Lock = %d", rc);
2539         } else if (get_flag) {
2540                 /* lock structure can be returned on get */
2541                 __u16 data_offset;
2542                 __u16 data_count;
2543                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2544
2545                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2546                         rc = -EIO;      /* bad smb */
2547                         goto plk_err_exit;
2548                 }
2549                 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2550                 data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2551                 if (data_count < sizeof(struct cifs_posix_lock)) {
2552                         rc = -EIO;
2553                         goto plk_err_exit;
2554                 }
2555                 parm_data = (struct cifs_posix_lock *)
2556                         ((char *)&pSMBr->hdr.Protocol + data_offset);
2557                 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2558                         pLockData->fl_type = F_UNLCK;
2559                 else {
2560                         if (parm_data->lock_type ==
2561                                         __constant_cpu_to_le16(CIFS_RDLCK))
2562                                 pLockData->fl_type = F_RDLCK;
2563                         else if (parm_data->lock_type ==
2564                                         __constant_cpu_to_le16(CIFS_WRLCK))
2565                                 pLockData->fl_type = F_WRLCK;
2566
2567                         pLockData->fl_start = le64_to_cpu(parm_data->start);
2568                         pLockData->fl_end = pLockData->fl_start +
2569                                         le64_to_cpu(parm_data->length) - 1;
2570                         pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2571                 }
2572         }
2573
2574 plk_err_exit:
2575         if (pSMB)
2576                 cifs_small_buf_release(pSMB);
2577
2578         if (resp_buf_type == CIFS_SMALL_BUFFER)
2579                 cifs_small_buf_release(iov[0].iov_base);
2580         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2581                 cifs_buf_release(iov[0].iov_base);
2582
2583         /* Note: On -EAGAIN error only caller can retry on handle based calls
2584            since file handle passed in no longer valid */
2585
2586         return rc;
2587 }
2588
2589
2590 int
2591 CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2592 {
2593         int rc = 0;
2594         CLOSE_REQ *pSMB = NULL;
2595         cFYI(1, "In CIFSSMBClose");
2596
2597 /* do not retry on dead session on close */
2598         rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2599         if (rc == -EAGAIN)
2600                 return 0;
2601         if (rc)
2602                 return rc;
2603
2604         pSMB->FileID = (__u16) smb_file_id;
2605         pSMB->LastWriteTime = 0xFFFFFFFF;
2606         pSMB->ByteCount = 0;
2607         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2608         cifs_stats_inc(&tcon->num_closes);
2609         if (rc) {
2610                 if (rc != -EINTR) {
2611                         /* EINTR is expected when user ctl-c to kill app */
2612                         cERROR(1, "Send error in Close = %d", rc);
2613                 }
2614         }
2615
2616         /* Since session is dead, file will be closed on server already */
2617         if (rc == -EAGAIN)
2618                 rc = 0;
2619
2620         return rc;
2621 }
2622
2623 int
2624 CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2625 {
2626         int rc = 0;
2627         FLUSH_REQ *pSMB = NULL;
2628         cFYI(1, "In CIFSSMBFlush");
2629
2630         rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2631         if (rc)
2632                 return rc;
2633
2634         pSMB->FileID = (__u16) smb_file_id;
2635         pSMB->ByteCount = 0;
2636         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2637         cifs_stats_inc(&tcon->num_flushes);
2638         if (rc)
2639                 cERROR(1, "Send error in Flush = %d", rc);
2640
2641         return rc;
2642 }
2643
2644 int
2645 CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
2646               const char *fromName, const char *toName,
2647               const struct nls_table *nls_codepage, int remap)
2648 {
2649         int rc = 0;
2650         RENAME_REQ *pSMB = NULL;
2651         RENAME_RSP *pSMBr = NULL;
2652         int bytes_returned;
2653         int name_len, name_len2;
2654         __u16 count;
2655
2656         cFYI(1, "In CIFSSMBRename");
2657 renameRetry:
2658         rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2659                       (void **) &pSMBr);
2660         if (rc)
2661                 return rc;
2662
2663         pSMB->BufferFormat = 0x04;
2664         pSMB->SearchAttributes =
2665             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2666                         ATTR_DIRECTORY);
2667
2668         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2669                 name_len =
2670                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
2671                                        PATH_MAX, nls_codepage, remap);
2672                 name_len++;     /* trailing null */
2673                 name_len *= 2;
2674                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2675         /* protocol requires ASCII signature byte on Unicode string */
2676                 pSMB->OldFileName[name_len + 1] = 0x00;
2677                 name_len2 =
2678                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2679                                        toName, PATH_MAX, nls_codepage, remap);
2680                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2681                 name_len2 *= 2; /* convert to bytes */
2682         } else {        /* BB improve the check for buffer overruns BB */
2683                 name_len = strnlen(fromName, PATH_MAX);
2684                 name_len++;     /* trailing null */
2685                 strncpy(pSMB->OldFileName, fromName, name_len);
2686                 name_len2 = strnlen(toName, PATH_MAX);
2687                 name_len2++;    /* trailing null */
2688                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2689                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2690                 name_len2++;    /* trailing null */
2691                 name_len2++;    /* signature byte */
2692         }
2693
2694         count = 1 /* 1st signature byte */  + name_len + name_len2;
2695         inc_rfc1001_len(pSMB, count);
2696         pSMB->ByteCount = cpu_to_le16(count);
2697
2698         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2699                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2700         cifs_stats_inc(&tcon->num_renames);
2701         if (rc)
2702                 cFYI(1, "Send error in rename = %d", rc);
2703
2704         cifs_buf_release(pSMB);
2705
2706         if (rc == -EAGAIN)
2707                 goto renameRetry;
2708
2709         return rc;
2710 }
2711
2712 int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
2713                 int netfid, const char *target_name,
2714                 const struct nls_table *nls_codepage, int remap)
2715 {
2716         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2717         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2718         struct set_file_rename *rename_info;
2719         char *data_offset;
2720         char dummy_string[30];
2721         int rc = 0;
2722         int bytes_returned = 0;
2723         int len_of_str;
2724         __u16 params, param_offset, offset, count, byte_count;
2725
2726         cFYI(1, "Rename to File by handle");
2727         rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2728                         (void **) &pSMBr);
2729         if (rc)
2730                 return rc;
2731
2732         params = 6;
2733         pSMB->MaxSetupCount = 0;
2734         pSMB->Reserved = 0;
2735         pSMB->Flags = 0;
2736         pSMB->Timeout = 0;
2737         pSMB->Reserved2 = 0;
2738         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2739         offset = param_offset + params;
2740
2741         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2742         rename_info = (struct set_file_rename *) data_offset;
2743         pSMB->MaxParameterCount = cpu_to_le16(2);
2744         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2745         pSMB->SetupCount = 1;
2746         pSMB->Reserved3 = 0;
2747         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2748         byte_count = 3 /* pad */  + params;
2749         pSMB->ParameterCount = cpu_to_le16(params);
2750         pSMB->TotalParameterCount = pSMB->ParameterCount;
2751         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2752         pSMB->DataOffset = cpu_to_le16(offset);
2753         /* construct random name ".cifs_tmp<inodenum><mid>" */
2754         rename_info->overwrite = cpu_to_le32(1);
2755         rename_info->root_fid  = 0;
2756         /* unicode only call */
2757         if (target_name == NULL) {
2758                 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2759                 len_of_str =
2760                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2761                                         dummy_string, 24, nls_codepage, remap);
2762         } else {
2763                 len_of_str =
2764                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2765                                         target_name, PATH_MAX, nls_codepage,
2766                                         remap);
2767         }
2768         rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2769         count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2770         byte_count += count;
2771         pSMB->DataCount = cpu_to_le16(count);
2772         pSMB->TotalDataCount = pSMB->DataCount;
2773         pSMB->Fid = netfid;
2774         pSMB->InformationLevel =
2775                 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2776         pSMB->Reserved4 = 0;
2777         inc_rfc1001_len(pSMB, byte_count);
2778         pSMB->ByteCount = cpu_to_le16(byte_count);
2779         rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2780                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2781         cifs_stats_inc(&pTcon->num_t2renames);
2782         if (rc)
2783                 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2784
2785         cifs_buf_release(pSMB);
2786
2787         /* Note: On -EAGAIN error only caller can retry on handle based calls
2788                 since file handle passed in no longer valid */
2789
2790         return rc;
2791 }
2792
2793 int
2794 CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
2795             const __u16 target_tid, const char *toName, const int flags,
2796             const struct nls_table *nls_codepage, int remap)
2797 {
2798         int rc = 0;
2799         COPY_REQ *pSMB = NULL;
2800         COPY_RSP *pSMBr = NULL;
2801         int bytes_returned;
2802         int name_len, name_len2;
2803         __u16 count;
2804
2805         cFYI(1, "In CIFSSMBCopy");
2806 copyRetry:
2807         rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2808                         (void **) &pSMBr);
2809         if (rc)
2810                 return rc;
2811
2812         pSMB->BufferFormat = 0x04;
2813         pSMB->Tid2 = target_tid;
2814
2815         pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2816
2817         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2818                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2819                                               fromName, PATH_MAX, nls_codepage,
2820                                               remap);
2821                 name_len++;     /* trailing null */
2822                 name_len *= 2;
2823                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2824                 /* protocol requires ASCII signature byte on Unicode string */
2825                 pSMB->OldFileName[name_len + 1] = 0x00;
2826                 name_len2 =
2827                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2828                                        toName, PATH_MAX, nls_codepage, remap);
2829                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2830                 name_len2 *= 2; /* convert to bytes */
2831         } else {        /* BB improve the check for buffer overruns BB */
2832                 name_len = strnlen(fromName, PATH_MAX);
2833                 name_len++;     /* trailing null */
2834                 strncpy(pSMB->OldFileName, fromName, name_len);
2835                 name_len2 = strnlen(toName, PATH_MAX);
2836                 name_len2++;    /* trailing null */
2837                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2838                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2839                 name_len2++;    /* trailing null */
2840                 name_len2++;    /* signature byte */
2841         }
2842
2843         count = 1 /* 1st signature byte */  + name_len + name_len2;
2844         inc_rfc1001_len(pSMB, count);
2845         pSMB->ByteCount = cpu_to_le16(count);
2846
2847         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2848                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2849         if (rc) {
2850                 cFYI(1, "Send error in copy = %d with %d files copied",
2851                         rc, le16_to_cpu(pSMBr->CopyCount));
2852         }
2853         cifs_buf_release(pSMB);
2854
2855         if (rc == -EAGAIN)
2856                 goto copyRetry;
2857
2858         return rc;
2859 }
2860
2861 int
2862 CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
2863                       const char *fromName, const char *toName,
2864                       const struct nls_table *nls_codepage)
2865 {
2866         TRANSACTION2_SPI_REQ *pSMB = NULL;
2867         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2868         char *data_offset;
2869         int name_len;
2870         int name_len_target;
2871         int rc = 0;
2872         int bytes_returned = 0;
2873         __u16 params, param_offset, offset, byte_count;
2874
2875         cFYI(1, "In Symlink Unix style");
2876 createSymLinkRetry:
2877         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2878                       (void **) &pSMBr);
2879         if (rc)
2880                 return rc;
2881
2882         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2883                 name_len =
2884                     cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2885                                     /* find define for this maxpathcomponent */
2886                                     PATH_MAX, nls_codepage);
2887                 name_len++;     /* trailing null */
2888                 name_len *= 2;
2889
2890         } else {        /* BB improve the check for buffer overruns BB */
2891                 name_len = strnlen(fromName, PATH_MAX);
2892                 name_len++;     /* trailing null */
2893                 strncpy(pSMB->FileName, fromName, name_len);
2894         }
2895         params = 6 + name_len;
2896         pSMB->MaxSetupCount = 0;
2897         pSMB->Reserved = 0;
2898         pSMB->Flags = 0;
2899         pSMB->Timeout = 0;
2900         pSMB->Reserved2 = 0;
2901         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2902                                 InformationLevel) - 4;
2903         offset = param_offset + params;
2904
2905         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2906         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2907                 name_len_target =
2908                     cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2909                                     /* find define for this maxpathcomponent */
2910                                     , nls_codepage);
2911                 name_len_target++;      /* trailing null */
2912                 name_len_target *= 2;
2913         } else {        /* BB improve the check for buffer overruns BB */
2914                 name_len_target = strnlen(toName, PATH_MAX);
2915                 name_len_target++;      /* trailing null */
2916                 strncpy(data_offset, toName, name_len_target);
2917         }
2918
2919         pSMB->MaxParameterCount = cpu_to_le16(2);
2920         /* BB find exact max on data count below from sess */
2921         pSMB->MaxDataCount = cpu_to_le16(1000);
2922         pSMB->SetupCount = 1;
2923         pSMB->Reserved3 = 0;
2924         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2925         byte_count = 3 /* pad */  + params + name_len_target;
2926         pSMB->DataCount = cpu_to_le16(name_len_target);
2927         pSMB->ParameterCount = cpu_to_le16(params);
2928         pSMB->TotalDataCount = pSMB->DataCount;
2929         pSMB->TotalParameterCount = pSMB->ParameterCount;
2930         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2931         pSMB->DataOffset = cpu_to_le16(offset);
2932         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2933         pSMB->Reserved4 = 0;
2934         inc_rfc1001_len(pSMB, byte_count);
2935         pSMB->ByteCount = cpu_to_le16(byte_count);
2936         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2937                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2938         cifs_stats_inc(&tcon->num_symlinks);
2939         if (rc)
2940                 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2941
2942         cifs_buf_release(pSMB);
2943
2944         if (rc == -EAGAIN)
2945                 goto createSymLinkRetry;
2946
2947         return rc;
2948 }
2949
2950 int
2951 CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
2952                        const char *fromName, const char *toName,
2953                        const struct nls_table *nls_codepage, int remap)
2954 {
2955         TRANSACTION2_SPI_REQ *pSMB = NULL;
2956         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2957         char *data_offset;
2958         int name_len;
2959         int name_len_target;
2960         int rc = 0;
2961         int bytes_returned = 0;
2962         __u16 params, param_offset, offset, byte_count;
2963
2964         cFYI(1, "In Create Hard link Unix style");
2965 createHardLinkRetry:
2966         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2967                       (void **) &pSMBr);
2968         if (rc)
2969                 return rc;
2970
2971         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2972                 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2973                                               PATH_MAX, nls_codepage, remap);
2974                 name_len++;     /* trailing null */
2975                 name_len *= 2;
2976
2977         } else {        /* BB improve the check for buffer overruns BB */
2978                 name_len = strnlen(toName, PATH_MAX);
2979                 name_len++;     /* trailing null */
2980                 strncpy(pSMB->FileName, toName, name_len);
2981         }
2982         params = 6 + name_len;
2983         pSMB->MaxSetupCount = 0;
2984         pSMB->Reserved = 0;
2985         pSMB->Flags = 0;
2986         pSMB->Timeout = 0;
2987         pSMB->Reserved2 = 0;
2988         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2989                                 InformationLevel) - 4;
2990         offset = param_offset + params;
2991
2992         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2993         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2994                 name_len_target =
2995                     cifsConvertToUTF16((__le16 *) data_offset, fromName,
2996                                        PATH_MAX, nls_codepage, remap);
2997                 name_len_target++;      /* trailing null */
2998                 name_len_target *= 2;
2999         } else {        /* BB improve the check for buffer overruns BB */
3000                 name_len_target = strnlen(fromName, PATH_MAX);
3001                 name_len_target++;      /* trailing null */
3002                 strncpy(data_offset, fromName, name_len_target);
3003         }
3004
3005         pSMB->MaxParameterCount = cpu_to_le16(2);
3006         /* BB find exact max on data count below from sess*/
3007         pSMB->MaxDataCount = cpu_to_le16(1000);
3008         pSMB->SetupCount = 1;
3009         pSMB->Reserved3 = 0;
3010         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3011         byte_count = 3 /* pad */  + params + name_len_target;
3012         pSMB->ParameterCount = cpu_to_le16(params);
3013         pSMB->TotalParameterCount = pSMB->ParameterCount;
3014         pSMB->DataCount = cpu_to_le16(name_len_target);
3015         pSMB->TotalDataCount = pSMB->DataCount;
3016         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3017         pSMB->DataOffset = cpu_to_le16(offset);
3018         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3019         pSMB->Reserved4 = 0;
3020         inc_rfc1001_len(pSMB, byte_count);
3021         pSMB->ByteCount = cpu_to_le16(byte_count);
3022         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3023                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3024         cifs_stats_inc(&tcon->num_hardlinks);
3025         if (rc)
3026                 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
3027
3028         cifs_buf_release(pSMB);
3029         if (rc == -EAGAIN)
3030                 goto createHardLinkRetry;
3031
3032         return rc;
3033 }
3034
3035 int
3036 CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
3037                    const char *fromName, const char *toName,
3038                    const struct nls_table *nls_codepage, int remap)
3039 {
3040         int rc = 0;
3041         NT_RENAME_REQ *pSMB = NULL;
3042         RENAME_RSP *pSMBr = NULL;
3043         int bytes_returned;
3044         int name_len, name_len2;
3045         __u16 count;
3046
3047         cFYI(1, "In CIFSCreateHardLink");
3048 winCreateHardLinkRetry:
3049
3050         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3051                       (void **) &pSMBr);
3052         if (rc)
3053                 return rc;
3054
3055         pSMB->SearchAttributes =
3056             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3057                         ATTR_DIRECTORY);
3058         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3059         pSMB->ClusterCount = 0;
3060
3061         pSMB->BufferFormat = 0x04;
3062
3063         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3064                 name_len =
3065                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
3066                                        PATH_MAX, nls_codepage, remap);
3067                 name_len++;     /* trailing null */
3068                 name_len *= 2;
3069
3070                 /* protocol specifies ASCII buffer format (0x04) for unicode */
3071                 pSMB->OldFileName[name_len] = 0x04;
3072                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3073                 name_len2 =
3074                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3075                                        toName, PATH_MAX, nls_codepage, remap);
3076                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
3077                 name_len2 *= 2; /* convert to bytes */
3078         } else {        /* BB improve the check for buffer overruns BB */
3079                 name_len = strnlen(fromName, PATH_MAX);
3080                 name_len++;     /* trailing null */
3081                 strncpy(pSMB->OldFileName, fromName, name_len);
3082                 name_len2 = strnlen(toName, PATH_MAX);
3083                 name_len2++;    /* trailing null */
3084                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
3085                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
3086                 name_len2++;    /* trailing null */
3087                 name_len2++;    /* signature byte */
3088         }
3089
3090         count = 1 /* string type byte */  + name_len + name_len2;
3091         inc_rfc1001_len(pSMB, count);
3092         pSMB->ByteCount = cpu_to_le16(count);
3093
3094         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3095                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3096         cifs_stats_inc(&tcon->num_hardlinks);
3097         if (rc)
3098                 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
3099
3100         cifs_buf_release(pSMB);
3101         if (rc == -EAGAIN)
3102                 goto winCreateHardLinkRetry;
3103
3104         return rc;
3105 }
3106
3107 int
3108 CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
3109                         const unsigned char *searchName, char **symlinkinfo,
3110                         const struct nls_table *nls_codepage)
3111 {
3112 /* SMB_QUERY_FILE_UNIX_LINK */
3113         TRANSACTION2_QPI_REQ *pSMB = NULL;
3114         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3115         int rc = 0;
3116         int bytes_returned;
3117         int name_len;
3118         __u16 params, byte_count;
3119         char *data_start;
3120
3121         cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
3122
3123 querySymLinkRetry:
3124         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3125                       (void **) &pSMBr);
3126         if (rc)
3127                 return rc;
3128
3129         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3130                 name_len =
3131                         cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3132                                         PATH_MAX, nls_codepage);
3133                 name_len++;     /* trailing null */
3134                 name_len *= 2;
3135         } else {        /* BB improve the check for buffer overruns BB */
3136                 name_len = strnlen(searchName, PATH_MAX);
3137                 name_len++;     /* trailing null */
3138                 strncpy(pSMB->FileName, searchName, name_len);
3139         }
3140
3141         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3142         pSMB->TotalDataCount = 0;
3143         pSMB->MaxParameterCount = cpu_to_le16(2);
3144         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3145         pSMB->MaxSetupCount = 0;
3146         pSMB->Reserved = 0;
3147         pSMB->Flags = 0;
3148         pSMB->Timeout = 0;
3149         pSMB->Reserved2 = 0;
3150         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3151         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3152         pSMB->DataCount = 0;
3153         pSMB->DataOffset = 0;
3154         pSMB->SetupCount = 1;
3155         pSMB->Reserved3 = 0;
3156         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3157         byte_count = params + 1 /* pad */ ;
3158         pSMB->TotalParameterCount = cpu_to_le16(params);
3159         pSMB->ParameterCount = pSMB->TotalParameterCount;
3160         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3161         pSMB->Reserved4 = 0;
3162         inc_rfc1001_len(pSMB, byte_count);
3163         pSMB->ByteCount = cpu_to_le16(byte_count);
3164
3165         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3166                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3167         if (rc) {
3168                 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3169         } else {
3170                 /* decode response */
3171
3172                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3173                 /* BB also check enough total bytes returned */
3174                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3175                         rc = -EIO;
3176                 else {
3177                         bool is_unicode;
3178                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3179
3180                         data_start = ((char *) &pSMBr->hdr.Protocol) +
3181                                            le16_to_cpu(pSMBr->t2.DataOffset);
3182
3183                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3184                                 is_unicode = true;
3185                         else
3186                                 is_unicode = false;
3187
3188                         /* BB FIXME investigate remapping reserved chars here */
3189                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
3190                                         count, is_unicode, nls_codepage);
3191                         if (!*symlinkinfo)
3192                                 rc = -ENOMEM;
3193                 }
3194         }
3195         cifs_buf_release(pSMB);
3196         if (rc == -EAGAIN)
3197                 goto querySymLinkRetry;
3198         return rc;
3199 }
3200
3201 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3202 /*
3203  *      Recent Windows versions now create symlinks more frequently
3204  *      and they use the "reparse point" mechanism below.  We can of course
3205  *      do symlinks nicely to Samba and other servers which support the
3206  *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3207  *      "MF" symlinks optionally, but for recent Windows we really need to
3208  *      reenable the code below and fix the cifs_symlink callers to handle this.
3209  *      In the interim this code has been moved to its own config option so
3210  *      it is not compiled in by default until callers fixed up and more tested.
3211  */
3212 int
3213 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
3214                         const unsigned char *searchName,
3215                         char *symlinkinfo, const int buflen, __u16 fid,
3216                         const struct nls_table *nls_codepage)
3217 {
3218         int rc = 0;
3219         int bytes_returned;
3220         struct smb_com_transaction_ioctl_req *pSMB;
3221         struct smb_com_transaction_ioctl_rsp *pSMBr;
3222
3223         cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3224         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3225                       (void **) &pSMBr);
3226         if (rc)
3227                 return rc;
3228
3229         pSMB->TotalParameterCount = 0 ;
3230         pSMB->TotalDataCount = 0;
3231         pSMB->MaxParameterCount = cpu_to_le32(2);
3232         /* BB find exact data count max from sess structure BB */
3233         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3234         pSMB->MaxSetupCount = 4;
3235         pSMB->Reserved = 0;
3236         pSMB->ParameterOffset = 0;
3237         pSMB->DataCount = 0;
3238         pSMB->DataOffset = 0;
3239         pSMB->SetupCount = 4;
3240         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3241         pSMB->ParameterCount = pSMB->TotalParameterCount;
3242         pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3243         pSMB->IsFsctl = 1; /* FSCTL */
3244         pSMB->IsRootFlag = 0;
3245         pSMB->Fid = fid; /* file handle always le */
3246         pSMB->ByteCount = 0;
3247
3248         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3249                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3250         if (rc) {
3251                 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3252         } else {                /* decode response */
3253                 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3254                 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3255                 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3256                         /* BB also check enough total bytes returned */
3257                         rc = -EIO;      /* bad smb */
3258                         goto qreparse_out;
3259                 }
3260                 if (data_count && (data_count < 2048)) {
3261                         char *end_of_smb = 2 /* sizeof byte count */ +
3262                                get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3263
3264                         struct reparse_data *reparse_buf =
3265                                                 (struct reparse_data *)
3266                                                 ((char *)&pSMBr->hdr.Protocol
3267                                                                  + data_offset);
3268                         if ((char *)reparse_buf >= end_of_smb) {
3269                                 rc = -EIO;
3270                                 goto qreparse_out;
3271                         }
3272                         if ((reparse_buf->LinkNamesBuf +
3273                                 reparse_buf->TargetNameOffset +
3274                                 reparse_buf->TargetNameLen) > end_of_smb) {
3275                                 cFYI(1, "reparse buf beyond SMB");
3276                                 rc = -EIO;
3277                                 goto qreparse_out;
3278                         }
3279
3280                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3281                                 cifs_from_ucs2(symlinkinfo, (__le16 *)
3282                                                 (reparse_buf->LinkNamesBuf +
3283                                                 reparse_buf->TargetNameOffset),
3284                                                 buflen,
3285                                                 reparse_buf->TargetNameLen,
3286                                                 nls_codepage, 0);
3287                         } else { /* ASCII names */
3288                                 strncpy(symlinkinfo,
3289                                         reparse_buf->LinkNamesBuf +
3290                                         reparse_buf->TargetNameOffset,
3291                                         min_t(const int, buflen,
3292                                            reparse_buf->TargetNameLen));
3293                         }
3294                 } else {
3295                         rc = -EIO;
3296                         cFYI(1, "Invalid return data count on "
3297                                  "get reparse info ioctl");
3298                 }
3299                 symlinkinfo[buflen] = 0; /* just in case so the caller
3300                                         does not go off the end of the buffer */
3301                 cFYI(1, "readlink result - %s", symlinkinfo);
3302         }
3303
3304 qreparse_out:
3305         cifs_buf_release(pSMB);
3306
3307         /* Note: On -EAGAIN error only caller can retry on handle based calls
3308                 since file handle passed in no longer valid */
3309
3310         return rc;
3311 }
3312 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3313
3314 #ifdef CONFIG_CIFS_POSIX
3315
3316 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3317 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3318                              struct cifs_posix_ace *cifs_ace)
3319 {
3320         /* u8 cifs fields do not need le conversion */
3321         ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3322         ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3323         ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3324         /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3325
3326         return;
3327 }
3328
3329 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3330 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3331                                const int acl_type, const int size_of_data_area)
3332 {
3333         int size =  0;
3334         int i;
3335         __u16 count;
3336         struct cifs_posix_ace *pACE;
3337         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3338         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3339
3340         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3341                 return -EOPNOTSUPP;
3342
3343         if (acl_type & ACL_TYPE_ACCESS) {
3344                 count = le16_to_cpu(cifs_acl->access_entry_count);
3345                 pACE = &cifs_acl->ace_array[0];
3346                 size = sizeof(struct cifs_posix_acl);
3347                 size += sizeof(struct cifs_posix_ace) * count;
3348                 /* check if we would go beyond end of SMB */
3349                 if (size_of_data_area < size) {
3350                         cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3351                                 size_of_data_area, size);
3352                         return -EINVAL;
3353                 }
3354         } else if (acl_type & ACL_TYPE_DEFAULT) {
3355                 count = le16_to_cpu(cifs_acl->access_entry_count);
3356                 size = sizeof(struct cifs_posix_acl);
3357                 size += sizeof(struct cifs_posix_ace) * count;
3358 /* skip past access ACEs to get to default ACEs */
3359                 pACE = &cifs_acl->ace_array[count];
3360                 count = le16_to_cpu(cifs_acl->default_entry_count);
3361                 size += sizeof(struct cifs_posix_ace) * count;
3362                 /* check if we would go beyond end of SMB */
3363                 if (size_of_data_area < size)
3364                         return -EINVAL;
3365         } else {
3366                 /* illegal type */
3367                 return -EINVAL;
3368         }
3369
3370         size = posix_acl_xattr_size(count);
3371         if ((buflen == 0) || (local_acl == NULL)) {
3372                 /* used to query ACL EA size */
3373         } else if (size > buflen) {
3374                 return -ERANGE;
3375         } else /* buffer big enough */ {
3376                 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3377                 for (i = 0; i < count ; i++) {
3378                         cifs_convert_ace(&local_acl->a_entries[i], pACE);
3379                         pACE++;
3380                 }
3381         }
3382         return size;
3383 }
3384
3385 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3386                                      const posix_acl_xattr_entry *local_ace)
3387 {
3388         __u16 rc = 0; /* 0 = ACL converted ok */
3389
3390         cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3391         cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
3392         /* BB is there a better way to handle the large uid? */
3393         if (local_ace->e_id == cpu_to_le32(-1)) {
3394         /* Probably no need to le convert -1 on any arch but can not hurt */
3395                 cifs_ace->cifs_uid = cpu_to_le64(-1);
3396         } else
3397                 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3398         /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3399         return rc;
3400 }
3401
3402 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3403 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3404                                const int buflen, const int acl_type)
3405 {
3406         __u16 rc = 0;
3407         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3408         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3409         int count;
3410         int i;
3411
3412         if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3413                 return 0;
3414
3415         count = posix_acl_xattr_count((size_t)buflen);
3416         cFYI(1, "setting acl with %d entries from buf of length %d and "
3417                 "version of %d",
3418                 count, buflen, le32_to_cpu(local_acl->a_version));
3419         if (le32_to_cpu(local_acl->a_version) != 2) {
3420                 cFYI(1, "unknown POSIX ACL version %d",
3421                      le32_to_cpu(local_acl->a_version));
3422                 return 0;
3423         }
3424         cifs_acl->version = cpu_to_le16(1);
3425         if (acl_type == ACL_TYPE_ACCESS)
3426                 cifs_acl->access_entry_count = cpu_to_le16(count);
3427         else if (acl_type == ACL_TYPE_DEFAULT)
3428                 cifs_acl->default_entry_count = cpu_to_le16(count);
3429         else {
3430                 cFYI(1, "unknown ACL type %d", acl_type);
3431                 return 0;
3432         }
3433         for (i = 0; i < count; i++) {
3434                 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3435                                         &local_acl->a_entries[i]);
3436                 if (rc != 0) {
3437                         /* ACE not converted */
3438                         break;
3439                 }
3440         }
3441         if (rc == 0) {
3442                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3443                 rc += sizeof(struct cifs_posix_acl);
3444                 /* BB add check to make sure ACL does not overflow SMB */
3445         }
3446         return rc;
3447 }
3448
3449 int
3450 CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
3451                    const unsigned char *searchName,
3452                    char *acl_inf, const int buflen, const int acl_type,
3453                    const struct nls_table *nls_codepage, int remap)
3454 {
3455 /* SMB_QUERY_POSIX_ACL */
3456         TRANSACTION2_QPI_REQ *pSMB = NULL;
3457         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3458         int rc = 0;
3459         int bytes_returned;
3460         int name_len;
3461         __u16 params, byte_count;
3462
3463         cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3464
3465 queryAclRetry:
3466         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3467                 (void **) &pSMBr);
3468         if (rc)
3469                 return rc;
3470
3471         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3472                 name_len =
3473                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3474                                            searchName, PATH_MAX, nls_codepage,
3475                                            remap);
3476                 name_len++;     /* trailing null */
3477                 name_len *= 2;
3478                 pSMB->FileName[name_len] = 0;
3479                 pSMB->FileName[name_len+1] = 0;
3480         } else {        /* BB improve the check for buffer overruns BB */
3481                 name_len = strnlen(searchName, PATH_MAX);
3482                 name_len++;     /* trailing null */
3483                 strncpy(pSMB->FileName, searchName, name_len);
3484         }
3485
3486         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3487         pSMB->TotalDataCount = 0;
3488         pSMB->MaxParameterCount = cpu_to_le16(2);
3489         /* BB find exact max data count below from sess structure BB */
3490         pSMB->MaxDataCount = cpu_to_le16(4000);
3491         pSMB->MaxSetupCount = 0;
3492         pSMB->Reserved = 0;
3493         pSMB->Flags = 0;
3494         pSMB->Timeout = 0;
3495         pSMB->Reserved2 = 0;
3496         pSMB->ParameterOffset = cpu_to_le16(
3497                 offsetof(struct smb_com_transaction2_qpi_req,
3498                          InformationLevel) - 4);
3499         pSMB->DataCount = 0;
3500         pSMB->DataOffset = 0;
3501         pSMB->SetupCount = 1;
3502         pSMB->Reserved3 = 0;
3503         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3504         byte_count = params + 1 /* pad */ ;
3505         pSMB->TotalParameterCount = cpu_to_le16(params);
3506         pSMB->ParameterCount = pSMB->TotalParameterCount;
3507         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3508         pSMB->Reserved4 = 0;
3509         inc_rfc1001_len(pSMB, byte_count);
3510         pSMB->ByteCount = cpu_to_le16(byte_count);
3511
3512         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3513                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3514         cifs_stats_inc(&tcon->num_acl_get);
3515         if (rc) {
3516                 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3517         } else {
3518                 /* decode response */
3519
3520                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3521                 /* BB also check enough total bytes returned */
3522                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3523                         rc = -EIO;      /* bad smb */
3524                 else {
3525                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3526                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3527                         rc = cifs_copy_posix_acl(acl_inf,
3528                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3529                                 buflen, acl_type, count);
3530                 }
3531         }
3532         cifs_buf_release(pSMB);
3533         if (rc == -EAGAIN)
3534                 goto queryAclRetry;
3535         return rc;
3536 }
3537
3538 int
3539 CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
3540                    const unsigned char *fileName,
3541                    const char *local_acl, const int buflen,
3542                    const int acl_type,
3543                    const struct nls_table *nls_codepage, int remap)
3544 {
3545         struct smb_com_transaction2_spi_req *pSMB = NULL;
3546         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3547         char *parm_data;
3548         int name_len;
3549         int rc = 0;
3550         int bytes_returned = 0;
3551         __u16 params, byte_count, data_count, param_offset, offset;
3552
3553         cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3554 setAclRetry:
3555         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3556                       (void **) &pSMBr);
3557         if (rc)
3558                 return rc;
3559         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3560                 name_len =
3561                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3562                                            PATH_MAX, nls_codepage, remap);
3563                 name_len++;     /* trailing null */
3564                 name_len *= 2;
3565         } else {        /* BB improve the check for buffer overruns BB */
3566                 name_len = strnlen(fileName, PATH_MAX);
3567                 name_len++;     /* trailing null */
3568                 strncpy(pSMB->FileName, fileName, name_len);
3569         }
3570         params = 6 + name_len;
3571         pSMB->MaxParameterCount = cpu_to_le16(2);
3572         /* BB find max SMB size from sess */
3573         pSMB->MaxDataCount = cpu_to_le16(1000);
3574         pSMB->MaxSetupCount = 0;
3575         pSMB->Reserved = 0;
3576         pSMB->Flags = 0;
3577         pSMB->Timeout = 0;
3578         pSMB->Reserved2 = 0;
3579         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3580                                 InformationLevel) - 4;
3581         offset = param_offset + params;
3582         parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3583         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3584
3585         /* convert to on the wire format for POSIX ACL */
3586         data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3587
3588         if (data_count == 0) {
3589                 rc = -EOPNOTSUPP;
3590                 goto setACLerrorExit;
3591         }
3592         pSMB->DataOffset = cpu_to_le16(offset);
3593         pSMB->SetupCount = 1;
3594         pSMB->Reserved3 = 0;
3595         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3596         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3597         byte_count = 3 /* pad */  + params + data_count;
3598         pSMB->DataCount = cpu_to_le16(data_count);
3599         pSMB->TotalDataCount = pSMB->DataCount;
3600         pSMB->ParameterCount = cpu_to_le16(params);
3601         pSMB->TotalParameterCount = pSMB->ParameterCount;
3602         pSMB->Reserved4 = 0;
3603         inc_rfc1001_len(pSMB, byte_count);
3604         pSMB->ByteCount = cpu_to_le16(byte_count);
3605         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3606                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3607         if (rc)
3608                 cFYI(1, "Set POSIX ACL returned %d", rc);
3609
3610 setACLerrorExit:
3611         cifs_buf_release(pSMB);
3612         if (rc == -EAGAIN)
3613                 goto setAclRetry;
3614         return rc;
3615 }
3616
3617 /* BB fix tabs in this function FIXME BB */
3618 int
3619 CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
3620                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3621 {
3622         int rc = 0;
3623         struct smb_t2_qfi_req *pSMB = NULL;
3624         struct smb_t2_qfi_rsp *pSMBr = NULL;
3625         int bytes_returned;
3626         __u16 params, byte_count;
3627
3628         cFYI(1, "In GetExtAttr");
3629         if (tcon == NULL)
3630                 return -ENODEV;
3631
3632 GetExtAttrRetry:
3633         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3634                         (void **) &pSMBr);
3635         if (rc)
3636                 return rc;
3637
3638         params = 2 /* level */ + 2 /* fid */;
3639         pSMB->t2.TotalDataCount = 0;
3640         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3641         /* BB find exact max data count below from sess structure BB */
3642         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3643         pSMB->t2.MaxSetupCount = 0;
3644         pSMB->t2.Reserved = 0;
3645         pSMB->t2.Flags = 0;
3646         pSMB->t2.Timeout = 0;
3647         pSMB->t2.Reserved2 = 0;
3648         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3649                                                Fid) - 4);
3650         pSMB->t2.DataCount = 0;
3651         pSMB->t2.DataOffset = 0;
3652         pSMB->t2.SetupCount = 1;
3653         pSMB->t2.Reserved3 = 0;
3654         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3655         byte_count = params + 1 /* pad */ ;
3656         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3657         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3658         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3659         pSMB->Pad = 0;
3660         pSMB->Fid = netfid;
3661         inc_rfc1001_len(pSMB, byte_count);
3662         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3663
3664         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3665                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3666         if (rc) {
3667                 cFYI(1, "error %d in GetExtAttr", rc);
3668         } else {
3669                 /* decode response */
3670                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3671                 /* BB also check enough total bytes returned */
3672                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3673                         /* If rc should we check for EOPNOSUPP and
3674                            disable the srvino flag? or in caller? */
3675                         rc = -EIO;      /* bad smb */
3676                 else {
3677                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3678                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3679                         struct file_chattr_info *pfinfo;
3680                         /* BB Do we need a cast or hash here ? */
3681                         if (count != 16) {
3682                                 cFYI(1, "Illegal size ret in GetExtAttr");
3683                                 rc = -EIO;
3684                                 goto GetExtAttrOut;
3685                         }
3686                         pfinfo = (struct file_chattr_info *)
3687                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3688                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3689                         *pMask = le64_to_cpu(pfinfo->mask);
3690                 }
3691         }
3692 GetExtAttrOut:
3693         cifs_buf_release(pSMB);
3694         if (rc == -EAGAIN)
3695                 goto GetExtAttrRetry;
3696         return rc;
3697 }
3698
3699 #endif /* CONFIG_POSIX */
3700
3701 #ifdef CONFIG_CIFS_ACL
3702 /*
3703  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3704  * all NT TRANSACTS that we init here have total parm and data under about 400
3705  * bytes (to fit in small cifs buffer size), which is the case so far, it
3706  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3707  * returned setup area) and MaxParameterCount (returned parms size) must be set
3708  * by caller
3709  */
3710 static int
3711 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3712                    const int parm_len, struct cifs_tcon *tcon,
3713                    void **ret_buf)
3714 {
3715         int rc;
3716         __u32 temp_offset;
3717         struct smb_com_ntransact_req *pSMB;
3718
3719         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3720                                 (void **)&pSMB);
3721         if (rc)
3722                 return rc;
3723         *ret_buf = (void *)pSMB;
3724         pSMB->Reserved = 0;
3725         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3726         pSMB->TotalDataCount  = 0;
3727         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3728         pSMB->ParameterCount = pSMB->TotalParameterCount;
3729         pSMB->DataCount  = pSMB->TotalDataCount;
3730         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3731                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3732         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3733         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3734         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3735         pSMB->SubCommand = cpu_to_le16(sub_command);
3736         return 0;
3737 }
3738
3739 static int
3740 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3741                    __u32 *pparmlen, __u32 *pdatalen)
3742 {
3743         char *end_of_smb;
3744         __u32 data_count, data_offset, parm_count, parm_offset;
3745         struct smb_com_ntransact_rsp *pSMBr;
3746         u16 bcc;
3747
3748         *pdatalen = 0;
3749         *pparmlen = 0;
3750
3751         if (buf == NULL)
3752                 return -EINVAL;
3753
3754         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3755
3756         bcc = get_bcc(&pSMBr->hdr);
3757         end_of_smb = 2 /* sizeof byte count */ + bcc +
3758                         (char *)&pSMBr->ByteCount;
3759
3760         data_offset = le32_to_cpu(pSMBr->DataOffset);
3761         data_count = le32_to_cpu(pSMBr->DataCount);
3762         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3763         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3764
3765         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3766         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3767
3768         /* should we also check that parm and data areas do not overlap? */
3769         if (*ppparm > end_of_smb) {
3770                 cFYI(1, "parms start after end of smb");
3771                 return -EINVAL;
3772         } else if (parm_count + *ppparm > end_of_smb) {
3773                 cFYI(1, "parm end after end of smb");
3774                 return -EINVAL;
3775         } else if (*ppdata > end_of_smb) {
3776                 cFYI(1, "data starts after end of smb");
3777                 return -EINVAL;
3778         } else if (data_count + *ppdata > end_of_smb) {
3779                 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3780                         *ppdata, data_count, (data_count + *ppdata),
3781                         end_of_smb, pSMBr);
3782                 return -EINVAL;
3783         } else if (parm_count + data_count > bcc) {
3784                 cFYI(1, "parm count and data count larger than SMB");
3785                 return -EINVAL;
3786         }
3787         *pdatalen = data_count;
3788         *pparmlen = parm_count;
3789         return 0;
3790 }
3791
3792 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3793 int
3794 CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3795                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3796 {
3797         int rc = 0;
3798         int buf_type = 0;
3799         QUERY_SEC_DESC_REQ *pSMB;
3800         struct kvec iov[1];
3801
3802         cFYI(1, "GetCifsACL");
3803
3804         *pbuflen = 0;
3805         *acl_inf = NULL;
3806
3807         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3808                         8 /* parm len */, tcon, (void **) &pSMB);
3809         if (rc)
3810                 return rc;
3811
3812         pSMB->MaxParameterCount = cpu_to_le32(4);
3813         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3814         pSMB->MaxSetupCount = 0;
3815         pSMB->Fid = fid; /* file handle always le */
3816         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3817                                      CIFS_ACL_DACL);
3818         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3819         inc_rfc1001_len(pSMB, 11);
3820         iov[0].iov_base = (char *)pSMB;
3821         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3822
3823         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3824                          0);
3825         cifs_stats_inc(&tcon->num_acl_get);
3826         if (rc) {
3827                 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3828         } else {                /* decode response */
3829                 __le32 *parm;
3830                 __u32 parm_len;
3831                 __u32 acl_len;
3832                 struct smb_com_ntransact_rsp *pSMBr;
3833                 char *pdata;
3834
3835 /* validate_nttransact */
3836                 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3837                                         &pdata, &parm_len, pbuflen);
3838                 if (rc)
3839                         goto qsec_out;
3840                 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3841
3842                 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3843
3844                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3845                         rc = -EIO;      /* bad smb */
3846                         *pbuflen = 0;
3847                         goto qsec_out;
3848                 }
3849
3850 /* BB check that data area is minimum length and as big as acl_len */
3851
3852                 acl_len = le32_to_cpu(*parm);
3853                 if (acl_len != *pbuflen) {
3854                         cERROR(1, "acl length %d does not match %d",
3855                                    acl_len, *pbuflen);
3856                         if (*pbuflen > acl_len)
3857                                 *pbuflen = acl_len;
3858                 }
3859
3860                 /* check if buffer is big enough for the acl
3861                    header followed by the smallest SID */
3862                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3863                     (*pbuflen >= 64 * 1024)) {
3864                         cERROR(1, "bad acl length %d", *pbuflen);
3865                         rc = -EINVAL;
3866                         *pbuflen = 0;
3867                 } else {
3868                         *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3869                         if (*acl_inf == NULL) {
3870                                 *pbuflen = 0;
3871                                 rc = -ENOMEM;
3872                         }
3873                         memcpy(*acl_inf, pdata, *pbuflen);
3874                 }
3875         }
3876 qsec_out:
3877         if (buf_type == CIFS_SMALL_BUFFER)
3878                 cifs_small_buf_release(iov[0].iov_base);
3879         else if (buf_type == CIFS_LARGE_BUFFER)
3880                 cifs_buf_release(iov[0].iov_base);
3881 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3882         return rc;
3883 }
3884
3885 int
3886 CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3887                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3888 {
3889         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3890         int rc = 0;
3891         int bytes_returned = 0;
3892         SET_SEC_DESC_REQ *pSMB = NULL;
3893         NTRANSACT_RSP *pSMBr = NULL;
3894
3895 setCifsAclRetry:
3896         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
3897                         (void **) &pSMBr);
3898         if (rc)
3899                         return (rc);
3900
3901         pSMB->MaxSetupCount = 0;
3902         pSMB->Reserved = 0;
3903
3904         param_count = 8;
3905         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3906         data_count = acllen;
3907         data_offset = param_offset + param_count;
3908         byte_count = 3 /* pad */  + param_count;
3909
3910         pSMB->DataCount = cpu_to_le32(data_count);
3911         pSMB->TotalDataCount = pSMB->DataCount;
3912         pSMB->MaxParameterCount = cpu_to_le32(4);
3913         pSMB->MaxDataCount = cpu_to_le32(16384);
3914         pSMB->ParameterCount = cpu_to_le32(param_count);
3915         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3916         pSMB->TotalParameterCount = pSMB->ParameterCount;
3917         pSMB->DataOffset = cpu_to_le32(data_offset);
3918         pSMB->SetupCount = 0;
3919         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3920         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3921
3922         pSMB->Fid = fid; /* file handle always le */
3923         pSMB->Reserved2 = 0;
3924         pSMB->AclFlags = cpu_to_le32(aclflag);
3925
3926         if (pntsd && acllen) {
3927                 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3928                         (char *) pntsd,
3929                         acllen);
3930                 inc_rfc1001_len(pSMB, byte_count + data_count);
3931         } else
3932                 inc_rfc1001_len(pSMB, byte_count);
3933
3934         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3935                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3936
3937         cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3938         if (rc)
3939                 cFYI(1, "Set CIFS ACL returned %d", rc);
3940         cifs_buf_release(pSMB);
3941
3942         if (rc == -EAGAIN)
3943                 goto setCifsAclRetry;
3944
3945         return (rc);
3946 }
3947
3948 #endif /* CONFIG_CIFS_ACL */
3949
3950 /* Legacy Query Path Information call for lookup to old servers such
3951    as Win9x/WinME */
3952 int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3953                         const unsigned char *searchName,
3954                         FILE_ALL_INFO *pFinfo,
3955                         const struct nls_table *nls_codepage, int remap)
3956 {
3957         QUERY_INFORMATION_REQ *pSMB;
3958         QUERY_INFORMATION_RSP *pSMBr;
3959         int rc = 0;
3960         int bytes_returned;
3961         int name_len;
3962
3963         cFYI(1, "In SMBQPath path %s", searchName);
3964 QInfRetry:
3965         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3966                       (void **) &pSMBr);
3967         if (rc)
3968                 return rc;
3969
3970         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3971                 name_len =
3972                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3973                                            searchName, PATH_MAX, nls_codepage,
3974                                            remap);
3975                 name_len++;     /* trailing null */
3976                 name_len *= 2;
3977         } else {
3978                 name_len = strnlen(searchName, PATH_MAX);
3979                 name_len++;     /* trailing null */
3980                 strncpy(pSMB->FileName, searchName, name_len);
3981         }
3982         pSMB->BufferFormat = 0x04;
3983         name_len++; /* account for buffer type byte */
3984         inc_rfc1001_len(pSMB, (__u16)name_len);
3985         pSMB->ByteCount = cpu_to_le16(name_len);
3986
3987         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3988                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3989         if (rc) {
3990                 cFYI(1, "Send error in QueryInfo = %d", rc);
3991         } else if (pFinfo) {
3992                 struct timespec ts;
3993                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3994
3995                 /* decode response */
3996                 /* BB FIXME - add time zone adjustment BB */
3997                 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
3998                 ts.tv_nsec = 0;
3999                 ts.tv_sec = time;
4000                 /* decode time fields */
4001                 pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4002                 pFinfo->LastWriteTime = pFinfo->ChangeTime;
4003                 pFinfo->LastAccessTime = 0;
4004                 pFinfo->AllocationSize =
4005                         cpu_to_le64(le32_to_cpu(pSMBr->size));
4006                 pFinfo->EndOfFile = pFinfo->AllocationSize;
4007                 pFinfo->Attributes =
4008                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
4009         } else
4010                 rc = -EIO; /* bad buffer passed in */
4011
4012         cifs_buf_release(pSMB);
4013
4014         if (rc == -EAGAIN)
4015                 goto QInfRetry;
4016
4017         return rc;
4018 }
4019
4020 int
4021 CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
4022                  u16 netfid, FILE_ALL_INFO *pFindData)
4023 {
4024         struct smb_t2_qfi_req *pSMB = NULL;
4025         struct smb_t2_qfi_rsp *pSMBr = NULL;
4026         int rc = 0;
4027         int bytes_returned;
4028         __u16 params, byte_count;
4029
4030 QFileInfoRetry:
4031         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4032                       (void **) &pSMBr);
4033         if (rc)
4034                 return rc;
4035
4036         params = 2 /* level */ + 2 /* fid */;
4037         pSMB->t2.TotalDataCount = 0;
4038         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4039         /* BB find exact max data count below from sess structure BB */
4040         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4041         pSMB->t2.MaxSetupCount = 0;
4042         pSMB->t2.Reserved = 0;
4043         pSMB->t2.Flags = 0;
4044         pSMB->t2.Timeout = 0;
4045         pSMB->t2.Reserved2 = 0;
4046         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4047                                                Fid) - 4);
4048         pSMB->t2.DataCount = 0;
4049         pSMB->t2.DataOffset = 0;
4050         pSMB->t2.SetupCount = 1;
4051         pSMB->t2.Reserved3 = 0;
4052         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4053         byte_count = params + 1 /* pad */ ;
4054         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4055         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4056         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4057         pSMB->Pad = 0;
4058         pSMB->Fid = netfid;
4059         inc_rfc1001_len(pSMB, byte_count);
4060
4061         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4062                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4063         if (rc) {
4064                 cFYI(1, "Send error in QPathInfo = %d", rc);
4065         } else {                /* decode response */
4066                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4067
4068                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4069                         rc = -EIO;
4070                 else if (get_bcc(&pSMBr->hdr) < 40)
4071                         rc = -EIO;      /* bad smb */
4072                 else if (pFindData) {
4073                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4074                         memcpy((char *) pFindData,
4075                                (char *) &pSMBr->hdr.Protocol +
4076                                data_offset, sizeof(FILE_ALL_INFO));
4077                 } else
4078                     rc = -ENOMEM;
4079         }
4080         cifs_buf_release(pSMB);
4081         if (rc == -EAGAIN)
4082                 goto QFileInfoRetry;
4083
4084         return rc;
4085 }
4086
4087 int
4088 CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
4089                  const unsigned char *searchName,
4090                  FILE_ALL_INFO *pFindData,
4091                  int legacy /* old style infolevel */,
4092                  const struct nls_table *nls_codepage, int remap)
4093 {
4094 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4095         TRANSACTION2_QPI_REQ *pSMB = NULL;
4096         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4097         int rc = 0;
4098         int bytes_returned;
4099         int name_len;
4100         __u16 params, byte_count;
4101
4102 /* cFYI(1, "In QPathInfo path %s", searchName); */
4103 QPathInfoRetry:
4104         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4105                       (void **) &pSMBr);
4106         if (rc)
4107                 return rc;
4108
4109         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4110                 name_len =
4111                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4112                                        PATH_MAX, nls_codepage, remap);
4113                 name_len++;     /* trailing null */
4114                 name_len *= 2;
4115         } else {        /* BB improve the check for buffer overruns BB */
4116                 name_len = strnlen(searchName, PATH_MAX);
4117                 name_len++;     /* trailing null */
4118                 strncpy(pSMB->FileName, searchName, name_len);
4119         }
4120
4121         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4122         pSMB->TotalDataCount = 0;
4123         pSMB->MaxParameterCount = cpu_to_le16(2);
4124         /* BB find exact max SMB PDU from sess structure BB */
4125         pSMB->MaxDataCount = cpu_to_le16(4000);
4126         pSMB->MaxSetupCount = 0;
4127         pSMB->Reserved = 0;
4128         pSMB->Flags = 0;
4129         pSMB->Timeout = 0;
4130         pSMB->Reserved2 = 0;
4131         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4132         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4133         pSMB->DataCount = 0;
4134         pSMB->DataOffset = 0;
4135         pSMB->SetupCount = 1;
4136         pSMB->Reserved3 = 0;
4137         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4138         byte_count = params + 1 /* pad */ ;
4139         pSMB->TotalParameterCount = cpu_to_le16(params);
4140         pSMB->ParameterCount = pSMB->TotalParameterCount;
4141         if (legacy)
4142                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4143         else
4144                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4145         pSMB->Reserved4 = 0;
4146         inc_rfc1001_len(pSMB, byte_count);
4147         pSMB->ByteCount = cpu_to_le16(byte_count);
4148
4149         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4150                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4151         if (rc) {
4152                 cFYI(1, "Send error in QPathInfo = %d", rc);
4153         } else {                /* decode response */
4154                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4155
4156                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4157                         rc = -EIO;
4158                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4159                         rc = -EIO;      /* bad smb */
4160                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4161                         rc = -EIO;  /* 24 or 26 expected but we do not read
4162                                         last field */
4163                 else if (pFindData) {
4164                         int size;
4165                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4166
4167                         /* On legacy responses we do not read the last field,
4168                         EAsize, fortunately since it varies by subdialect and
4169                         also note it differs on Set vs. Get, ie two bytes or 4
4170                         bytes depending but we don't care here */
4171                         if (legacy)
4172                                 size = sizeof(FILE_INFO_STANDARD);
4173                         else
4174                                 size = sizeof(FILE_ALL_INFO);
4175                         memcpy((char *) pFindData,
4176                                (char *) &pSMBr->hdr.Protocol +
4177                                data_offset, size);
4178                 } else
4179                     rc = -ENOMEM;
4180         }
4181         cifs_buf_release(pSMB);
4182         if (rc == -EAGAIN)
4183                 goto QPathInfoRetry;
4184
4185         return rc;
4186 }
4187
4188 int
4189 CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
4190                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4191 {
4192         struct smb_t2_qfi_req *pSMB = NULL;
4193         struct smb_t2_qfi_rsp *pSMBr = NULL;
4194         int rc = 0;
4195         int bytes_returned;
4196         __u16 params, byte_count;
4197
4198 UnixQFileInfoRetry:
4199         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4200                       (void **) &pSMBr);
4201         if (rc)
4202                 return rc;
4203
4204         params = 2 /* level */ + 2 /* fid */;
4205         pSMB->t2.TotalDataCount = 0;
4206         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4207         /* BB find exact max data count below from sess structure BB */
4208         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4209         pSMB->t2.MaxSetupCount = 0;
4210         pSMB->t2.Reserved = 0;
4211         pSMB->t2.Flags = 0;
4212         pSMB->t2.Timeout = 0;
4213         pSMB->t2.Reserved2 = 0;
4214         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4215                                                Fid) - 4);
4216         pSMB->t2.DataCount = 0;
4217         pSMB->t2.DataOffset = 0;
4218         pSMB->t2.SetupCount = 1;
4219         pSMB->t2.Reserved3 = 0;
4220         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4221         byte_count = params + 1 /* pad */ ;
4222         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4223         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4224         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4225         pSMB->Pad = 0;
4226         pSMB->Fid = netfid;
4227         inc_rfc1001_len(pSMB, byte_count);
4228
4229         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4230                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4231         if (rc) {
4232                 cFYI(1, "Send error in QPathInfo = %d", rc);
4233         } else {                /* decode response */
4234                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4235
4236                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4237                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4238                                    "Unix Extensions can be disabled on mount "
4239                                    "by specifying the nosfu mount option.");
4240                         rc = -EIO;      /* bad smb */
4241                 } else {
4242                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4243                         memcpy((char *) pFindData,
4244                                (char *) &pSMBr->hdr.Protocol +
4245                                data_offset,
4246                                sizeof(FILE_UNIX_BASIC_INFO));
4247                 }
4248         }
4249
4250         cifs_buf_release(pSMB);
4251         if (rc == -EAGAIN)
4252                 goto UnixQFileInfoRetry;
4253
4254         return rc;
4255 }
4256
4257 int
4258 CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
4259                      const unsigned char *searchName,
4260                      FILE_UNIX_BASIC_INFO *pFindData,
4261                      const struct nls_table *nls_codepage, int remap)
4262 {
4263 /* SMB_QUERY_FILE_UNIX_BASIC */
4264         TRANSACTION2_QPI_REQ *pSMB = NULL;
4265         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4266         int rc = 0;
4267         int bytes_returned = 0;
4268         int name_len;
4269         __u16 params, byte_count;
4270
4271         cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4272 UnixQPathInfoRetry:
4273         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4274                       (void **) &pSMBr);
4275         if (rc)
4276                 return rc;
4277
4278         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4279                 name_len =
4280                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4281                                        PATH_MAX, nls_codepage, remap);
4282                 name_len++;     /* trailing null */
4283                 name_len *= 2;
4284         } else {        /* BB improve the check for buffer overruns BB */
4285                 name_len = strnlen(searchName, PATH_MAX);
4286                 name_len++;     /* trailing null */
4287                 strncpy(pSMB->FileName, searchName, name_len);
4288         }
4289
4290         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4291         pSMB->TotalDataCount = 0;
4292         pSMB->MaxParameterCount = cpu_to_le16(2);
4293         /* BB find exact max SMB PDU from sess structure BB */
4294         pSMB->MaxDataCount = cpu_to_le16(4000);
4295         pSMB->MaxSetupCount = 0;
4296         pSMB->Reserved = 0;
4297         pSMB->Flags = 0;
4298         pSMB->Timeout = 0;
4299         pSMB->Reserved2 = 0;
4300         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4301         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4302         pSMB->DataCount = 0;
4303         pSMB->DataOffset = 0;
4304         pSMB->SetupCount = 1;
4305         pSMB->Reserved3 = 0;
4306         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4307         byte_count = params + 1 /* pad */ ;
4308         pSMB->TotalParameterCount = cpu_to_le16(params);
4309         pSMB->ParameterCount = pSMB->TotalParameterCount;
4310         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4311         pSMB->Reserved4 = 0;
4312         inc_rfc1001_len(pSMB, byte_count);
4313         pSMB->ByteCount = cpu_to_le16(byte_count);
4314
4315         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4316                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4317         if (rc) {
4318                 cFYI(1, "Send error in QPathInfo = %d", rc);
4319         } else {                /* decode response */
4320                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4321
4322                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4323                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4324                                    "Unix Extensions can be disabled on mount "
4325                                    "by specifying the nosfu mount option.");
4326                         rc = -EIO;      /* bad smb */
4327                 } else {
4328                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4329                         memcpy((char *) pFindData,
4330                                (char *) &pSMBr->hdr.Protocol +
4331                                data_offset,
4332                                sizeof(FILE_UNIX_BASIC_INFO));
4333                 }
4334         }
4335         cifs_buf_release(pSMB);
4336         if (rc == -EAGAIN)
4337                 goto UnixQPathInfoRetry;
4338
4339         return rc;
4340 }
4341
4342 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4343 int
4344 CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
4345               const char *searchName,
4346               const struct nls_table *nls_codepage,
4347               __u16 *pnetfid,
4348               struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4349 {
4350 /* level 257 SMB_ */
4351         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4352         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4353         T2_FFIRST_RSP_PARMS *parms;
4354         int rc = 0;
4355         int bytes_returned = 0;
4356         int name_len;
4357         __u16 params, byte_count;
4358
4359         cFYI(1, "In FindFirst for %s", searchName);
4360
4361 findFirstRetry:
4362         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4363                       (void **) &pSMBr);
4364         if (rc)
4365                 return rc;
4366
4367         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4368                 name_len =
4369                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4370                                        PATH_MAX, nls_codepage, remap);
4371                 /* We can not add the asterik earlier in case
4372                 it got remapped to 0xF03A as if it were part of the
4373                 directory name instead of a wildcard */
4374                 name_len *= 2;
4375                 pSMB->FileName[name_len] = dirsep;
4376                 pSMB->FileName[name_len+1] = 0;
4377                 pSMB->FileName[name_len+2] = '*';
4378                 pSMB->FileName[name_len+3] = 0;
4379                 name_len += 4; /* now the trailing null */
4380                 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4381                 pSMB->FileName[name_len+1] = 0;
4382                 name_len += 2;
4383         } else {        /* BB add check for overrun of SMB buf BB */
4384                 name_len = strnlen(searchName, PATH_MAX);
4385 /* BB fix here and in unicode clause above ie
4386                 if (name_len > buffersize-header)
4387                         free buffer exit; BB */
4388                 strncpy(pSMB->FileName, searchName, name_len);
4389                 pSMB->FileName[name_len] = dirsep;
4390                 pSMB->FileName[name_len+1] = '*';
4391                 pSMB->FileName[name_len+2] = 0;
4392                 name_len += 3;
4393         }
4394
4395         params = 12 + name_len /* includes null */ ;
4396         pSMB->TotalDataCount = 0;       /* no EAs */
4397         pSMB->MaxParameterCount = cpu_to_le16(10);
4398         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4399         pSMB->MaxSetupCount = 0;
4400         pSMB->Reserved = 0;
4401         pSMB->Flags = 0;
4402         pSMB->Timeout = 0;
4403         pSMB->Reserved2 = 0;
4404         byte_count = params + 1 /* pad */ ;
4405         pSMB->TotalParameterCount = cpu_to_le16(params);
4406         pSMB->ParameterCount = pSMB->TotalParameterCount;
4407         pSMB->ParameterOffset = cpu_to_le16(
4408               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4409                 - 4);
4410         pSMB->DataCount = 0;
4411         pSMB->DataOffset = 0;
4412         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4413         pSMB->Reserved3 = 0;
4414         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4415         pSMB->SearchAttributes =
4416             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4417                         ATTR_DIRECTORY);
4418         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4419         pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END |
4420                 CIFS_SEARCH_RETURN_RESUME);
4421         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4422
4423         /* BB what should we set StorageType to? Does it matter? BB */
4424         pSMB->SearchStorageType = 0;
4425         inc_rfc1001_len(pSMB, byte_count);
4426         pSMB->ByteCount = cpu_to_le16(byte_count);
4427
4428         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4429                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4430         cifs_stats_inc(&tcon->num_ffirst);
4431
4432         if (rc) {/* BB add logic to retry regular search if Unix search
4433                         rejected unexpectedly by server */
4434                 /* BB Add code to handle unsupported level rc */
4435                 cFYI(1, "Error in FindFirst = %d", rc);
4436
4437                 cifs_buf_release(pSMB);
4438
4439                 /* BB eventually could optimize out free and realloc of buf */
4440                 /*    for this case */
4441                 if (rc == -EAGAIN)
4442                         goto findFirstRetry;
4443         } else { /* decode response */
4444                 /* BB remember to free buffer if error BB */
4445                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4446                 if (rc == 0) {
4447                         unsigned int lnoff;
4448
4449                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4450                                 psrch_inf->unicode = true;
4451                         else
4452                                 psrch_inf->unicode = false;
4453
4454                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4455                         psrch_inf->smallBuf = 0;
4456                         psrch_inf->srch_entries_start =
4457                                 (char *) &pSMBr->hdr.Protocol +
4458                                         le16_to_cpu(pSMBr->t2.DataOffset);
4459                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4460                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4461
4462                         if (parms->EndofSearch)
4463                                 psrch_inf->endOfSearch = true;
4464                         else
4465                                 psrch_inf->endOfSearch = false;
4466
4467                         psrch_inf->entries_in_buffer =
4468                                         le16_to_cpu(parms->SearchCount);
4469                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4470                                 psrch_inf->entries_in_buffer;
4471                         lnoff = le16_to_cpu(parms->LastNameOffset);
4472                         if (CIFSMaxBufSize < lnoff) {
4473                                 cERROR(1, "ignoring corrupt resume name");
4474                                 psrch_inf->last_entry = NULL;
4475                                 return rc;
4476                         }
4477
4478                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4479                                                         lnoff;
4480
4481                         *pnetfid = parms->SearchHandle;
4482                 } else {
4483                         cifs_buf_release(pSMB);
4484                 }
4485         }
4486
4487         return rc;
4488 }
4489
4490 int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
4491                  __u16 searchHandle, struct cifs_search_info *psrch_inf)
4492 {
4493         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4494         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4495         T2_FNEXT_RSP_PARMS *parms;
4496         char *response_data;
4497         int rc = 0;
4498         int bytes_returned;
4499         unsigned int name_len;
4500         __u16 params, byte_count;
4501
4502         cFYI(1, "In FindNext");
4503
4504         if (psrch_inf->endOfSearch)
4505                 return -ENOENT;
4506
4507         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4508                 (void **) &pSMBr);
4509         if (rc)
4510                 return rc;
4511
4512         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4513         byte_count = 0;
4514         pSMB->TotalDataCount = 0;       /* no EAs */
4515         pSMB->MaxParameterCount = cpu_to_le16(8);
4516         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4517         pSMB->MaxSetupCount = 0;
4518         pSMB->Reserved = 0;
4519         pSMB->Flags = 0;
4520         pSMB->Timeout = 0;
4521         pSMB->Reserved2 = 0;
4522         pSMB->ParameterOffset =  cpu_to_le16(
4523               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4524         pSMB->DataCount = 0;
4525         pSMB->DataOffset = 0;
4526         pSMB->SetupCount = 1;
4527         pSMB->Reserved3 = 0;
4528         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4529         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4530         pSMB->SearchCount =
4531                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4532         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4533         pSMB->ResumeKey = psrch_inf->resume_key;
4534         pSMB->SearchFlags =
4535               cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
4536
4537         name_len = psrch_inf->resume_name_len;
4538         params += name_len;
4539         if (name_len < PATH_MAX) {
4540                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4541                 byte_count += name_len;
4542                 /* 14 byte parm len above enough for 2 byte null terminator */
4543                 pSMB->ResumeFileName[name_len] = 0;
4544                 pSMB->ResumeFileName[name_len+1] = 0;
4545         } else {
4546                 rc = -EINVAL;
4547                 goto FNext2_err_exit;
4548         }
4549         byte_count = params + 1 /* pad */ ;
4550         pSMB->TotalParameterCount = cpu_to_le16(params);
4551         pSMB->ParameterCount = pSMB->TotalParameterCount;
4552         inc_rfc1001_len(pSMB, byte_count);
4553         pSMB->ByteCount = cpu_to_le16(byte_count);
4554
4555         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4556                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4557         cifs_stats_inc(&tcon->num_fnext);
4558         if (rc) {
4559                 if (rc == -EBADF) {
4560                         psrch_inf->endOfSearch = true;
4561                         cifs_buf_release(pSMB);
4562                         rc = 0; /* search probably was closed at end of search*/
4563                 } else
4564                         cFYI(1, "FindNext returned = %d", rc);
4565         } else {                /* decode response */
4566                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4567
4568                 if (rc == 0) {
4569                         unsigned int lnoff;
4570
4571                         /* BB fixme add lock for file (srch_info) struct here */
4572                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4573                                 psrch_inf->unicode = true;
4574                         else
4575                                 psrch_inf->unicode = false;
4576                         response_data = (char *) &pSMBr->hdr.Protocol +
4577                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4578                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4579                         response_data = (char *)&pSMBr->hdr.Protocol +
4580                                 le16_to_cpu(pSMBr->t2.DataOffset);
4581                         if (psrch_inf->smallBuf)
4582                                 cifs_small_buf_release(
4583                                         psrch_inf->ntwrk_buf_start);
4584                         else
4585                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4586                         psrch_inf->srch_entries_start = response_data;
4587                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4588                         psrch_inf->smallBuf = 0;
4589                         if (parms->EndofSearch)
4590                                 psrch_inf->endOfSearch = true;
4591                         else
4592                                 psrch_inf->endOfSearch = false;
4593                         psrch_inf->entries_in_buffer =
4594                                                 le16_to_cpu(parms->SearchCount);
4595                         psrch_inf->index_of_last_entry +=
4596                                 psrch_inf->entries_in_buffer;
4597                         lnoff = le16_to_cpu(parms->LastNameOffset);
4598                         if (CIFSMaxBufSize < lnoff) {
4599                                 cERROR(1, "ignoring corrupt resume name");
4600                                 psrch_inf->last_entry = NULL;
4601                                 return rc;
4602                         } else
4603                                 psrch_inf->last_entry =
4604                                         psrch_inf->srch_entries_start + lnoff;
4605
4606 /*  cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4607             psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4608
4609                         /* BB fixme add unlock here */
4610                 }
4611
4612         }
4613
4614         /* BB On error, should we leave previous search buf (and count and
4615         last entry fields) intact or free the previous one? */
4616
4617         /* Note: On -EAGAIN error only caller can retry on handle based calls
4618         since file handle passed in no longer valid */
4619 FNext2_err_exit:
4620         if (rc != 0)
4621                 cifs_buf_release(pSMB);
4622         return rc;
4623 }
4624
4625 int
4626 CIFSFindClose(const int xid, struct cifs_tcon *tcon,
4627               const __u16 searchHandle)
4628 {
4629         int rc = 0;
4630         FINDCLOSE_REQ *pSMB = NULL;
4631
4632         cFYI(1, "In CIFSSMBFindClose");
4633         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4634
4635         /* no sense returning error if session restarted
4636                 as file handle has been closed */
4637         if (rc == -EAGAIN)
4638                 return 0;
4639         if (rc)
4640                 return rc;
4641
4642         pSMB->FileID = searchHandle;
4643         pSMB->ByteCount = 0;
4644         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4645         if (rc)
4646                 cERROR(1, "Send error in FindClose = %d", rc);
4647
4648         cifs_stats_inc(&tcon->num_fclose);
4649
4650         /* Since session is dead, search handle closed on server already */
4651         if (rc == -EAGAIN)
4652                 rc = 0;
4653
4654         return rc;
4655 }
4656
4657 int
4658 CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
4659                       const unsigned char *searchName,
4660                       __u64 *inode_number,
4661                       const struct nls_table *nls_codepage, int remap)
4662 {
4663         int rc = 0;
4664         TRANSACTION2_QPI_REQ *pSMB = NULL;
4665         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4666         int name_len, bytes_returned;
4667         __u16 params, byte_count;
4668
4669         cFYI(1, "In GetSrvInodeNum for %s", searchName);
4670         if (tcon == NULL)
4671                 return -ENODEV;
4672
4673 GetInodeNumberRetry:
4674         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4675                       (void **) &pSMBr);
4676         if (rc)
4677                 return rc;
4678
4679         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4680                 name_len =
4681                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4682                                            searchName, PATH_MAX, nls_codepage,
4683                                            remap);
4684                 name_len++;     /* trailing null */
4685                 name_len *= 2;
4686         } else {        /* BB improve the check for buffer overruns BB */
4687                 name_len = strnlen(searchName, PATH_MAX);
4688                 name_len++;     /* trailing null */
4689                 strncpy(pSMB->FileName, searchName, name_len);
4690         }
4691
4692         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4693         pSMB->TotalDataCount = 0;
4694         pSMB->MaxParameterCount = cpu_to_le16(2);
4695         /* BB find exact max data count below from sess structure BB */
4696         pSMB->MaxDataCount = cpu_to_le16(4000);
4697         pSMB->MaxSetupCount = 0;
4698         pSMB->Reserved = 0;
4699         pSMB->Flags = 0;
4700         pSMB->Timeout = 0;
4701         pSMB->Reserved2 = 0;
4702         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4703                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4704         pSMB->DataCount = 0;
4705         pSMB->DataOffset = 0;
4706         pSMB->SetupCount = 1;
4707         pSMB->Reserved3 = 0;
4708         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4709         byte_count = params + 1 /* pad */ ;
4710         pSMB->TotalParameterCount = cpu_to_le16(params);
4711         pSMB->ParameterCount = pSMB->TotalParameterCount;
4712         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4713         pSMB->Reserved4 = 0;
4714         inc_rfc1001_len(pSMB, byte_count);
4715         pSMB->ByteCount = cpu_to_le16(byte_count);
4716
4717         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4718                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4719         if (rc) {
4720                 cFYI(1, "error %d in QueryInternalInfo", rc);
4721         } else {
4722                 /* decode response */
4723                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4724                 /* BB also check enough total bytes returned */
4725                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4726                         /* If rc should we check for EOPNOSUPP and
4727                         disable the srvino flag? or in caller? */
4728                         rc = -EIO;      /* bad smb */
4729                 else {
4730                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4731                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4732                         struct file_internal_info *pfinfo;
4733                         /* BB Do we need a cast or hash here ? */
4734                         if (count < 8) {
4735                                 cFYI(1, "Illegal size ret in QryIntrnlInf");
4736                                 rc = -EIO;
4737                                 goto GetInodeNumOut;
4738                         }
4739                         pfinfo = (struct file_internal_info *)
4740                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4741                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4742                 }
4743         }
4744 GetInodeNumOut:
4745         cifs_buf_release(pSMB);
4746         if (rc == -EAGAIN)
4747                 goto GetInodeNumberRetry;
4748         return rc;
4749 }
4750
4751 /* parses DFS refferal V3 structure
4752  * caller is responsible for freeing target_nodes
4753  * returns:
4754  *      on success - 0
4755  *      on failure - errno
4756  */
4757 static int
4758 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4759                 unsigned int *num_of_nodes,
4760                 struct dfs_info3_param **target_nodes,
4761                 const struct nls_table *nls_codepage, int remap,
4762                 const char *searchName)
4763 {
4764         int i, rc = 0;
4765         char *data_end;
4766         bool is_unicode;
4767         struct dfs_referral_level_3 *ref;
4768
4769         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4770                 is_unicode = true;
4771         else
4772                 is_unicode = false;
4773         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4774
4775         if (*num_of_nodes < 1) {
4776                 cERROR(1, "num_referrals: must be at least > 0,"
4777                         "but we get num_referrals = %d\n", *num_of_nodes);
4778                 rc = -EINVAL;
4779                 goto parse_DFS_referrals_exit;
4780         }
4781
4782         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4783         if (ref->VersionNumber != cpu_to_le16(3)) {
4784                 cERROR(1, "Referrals of V%d version are not supported,"
4785                         "should be V3", le16_to_cpu(ref->VersionNumber));
4786                 rc = -EINVAL;
4787                 goto parse_DFS_referrals_exit;
4788         }
4789
4790         /* get the upper boundary of the resp buffer */
4791         data_end = (char *)(&(pSMBr->PathConsumed)) +
4792                                 le16_to_cpu(pSMBr->t2.DataCount);
4793
4794         cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
4795                         *num_of_nodes,
4796                         le32_to_cpu(pSMBr->DFSFlags));
4797
4798         *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4799                         *num_of_nodes, GFP_KERNEL);
4800         if (*target_nodes == NULL) {
4801                 cERROR(1, "Failed to allocate buffer for target_nodes\n");
4802                 rc = -ENOMEM;
4803                 goto parse_DFS_referrals_exit;
4804         }
4805
4806         /* collect necessary data from referrals */
4807         for (i = 0; i < *num_of_nodes; i++) {
4808                 char *temp;
4809                 int max_len;
4810                 struct dfs_info3_param *node = (*target_nodes)+i;
4811
4812                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4813                 if (is_unicode) {
4814                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4815                                                 GFP_KERNEL);
4816                         if (tmp == NULL) {
4817                                 rc = -ENOMEM;
4818                                 goto parse_DFS_referrals_exit;
4819                         }
4820                         cifsConvertToUTF16((__le16 *) tmp, searchName,
4821                                            PATH_MAX, nls_codepage, remap);
4822                         node->path_consumed = cifs_utf16_bytes(tmp,
4823                                         le16_to_cpu(pSMBr->PathConsumed),
4824                                         nls_codepage);
4825                         kfree(tmp);
4826                 } else
4827                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4828
4829                 node->server_type = le16_to_cpu(ref->ServerType);
4830                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4831
4832                 /* copy DfsPath */
4833                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4834                 max_len = data_end - temp;
4835                 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4836                                                 is_unicode, nls_codepage);
4837                 if (!node->path_name) {
4838                         rc = -ENOMEM;
4839                         goto parse_DFS_referrals_exit;
4840                 }
4841
4842                 /* copy link target UNC */
4843                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4844                 max_len = data_end - temp;
4845                 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4846                                                 is_unicode, nls_codepage);
4847                 if (!node->node_name)
4848                         rc = -ENOMEM;
4849         }
4850
4851 parse_DFS_referrals_exit:
4852         if (rc) {
4853                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4854                 *target_nodes = NULL;
4855                 *num_of_nodes = 0;
4856         }
4857         return rc;
4858 }
4859
4860 int
4861 CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4862                 const unsigned char *searchName,
4863                 struct dfs_info3_param **target_nodes,
4864                 unsigned int *num_of_nodes,
4865                 const struct nls_table *nls_codepage, int remap)
4866 {
4867 /* TRANS2_GET_DFS_REFERRAL */
4868         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4869         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4870         int rc = 0;
4871         int bytes_returned;
4872         int name_len;
4873         __u16 params, byte_count;
4874         *num_of_nodes = 0;
4875         *target_nodes = NULL;
4876
4877         cFYI(1, "In GetDFSRefer the path %s", searchName);
4878         if (ses == NULL)
4879                 return -ENODEV;
4880 getDFSRetry:
4881         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4882                       (void **) &pSMBr);
4883         if (rc)
4884                 return rc;
4885
4886         /* server pointer checked in called function,
4887         but should never be null here anyway */
4888         pSMB->hdr.Mid = GetNextMid(ses->server);
4889         pSMB->hdr.Tid = ses->ipc_tid;
4890         pSMB->hdr.Uid = ses->Suid;
4891         if (ses->capabilities & CAP_STATUS32)
4892                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4893         if (ses->capabilities & CAP_DFS)
4894                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4895
4896         if (ses->capabilities & CAP_UNICODE) {
4897                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4898                 name_len =
4899                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4900                                        searchName, PATH_MAX, nls_codepage,
4901                                        remap);
4902                 name_len++;     /* trailing null */
4903                 name_len *= 2;
4904         } else {        /* BB improve the check for buffer overruns BB */
4905                 name_len = strnlen(searchName, PATH_MAX);
4906                 name_len++;     /* trailing null */
4907                 strncpy(pSMB->RequestFileName, searchName, name_len);
4908         }
4909
4910         if (ses->server) {
4911                 if (ses->server->sec_mode &
4912                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4913                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4914         }
4915
4916         pSMB->hdr.Uid = ses->Suid;
4917
4918         params = 2 /* level */  + name_len /*includes null */ ;
4919         pSMB->TotalDataCount = 0;
4920         pSMB->DataCount = 0;
4921         pSMB->DataOffset = 0;
4922         pSMB->MaxParameterCount = 0;
4923         /* BB find exact max SMB PDU from sess structure BB */
4924         pSMB->MaxDataCount = cpu_to_le16(4000);
4925         pSMB->MaxSetupCount = 0;
4926         pSMB->Reserved = 0;
4927         pSMB->Flags = 0;
4928         pSMB->Timeout = 0;
4929         pSMB->Reserved2 = 0;
4930         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4931           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4932         pSMB->SetupCount = 1;
4933         pSMB->Reserved3 = 0;
4934         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4935         byte_count = params + 3 /* pad */ ;
4936         pSMB->ParameterCount = cpu_to_le16(params);
4937         pSMB->TotalParameterCount = pSMB->ParameterCount;
4938         pSMB->MaxReferralLevel = cpu_to_le16(3);
4939         inc_rfc1001_len(pSMB, byte_count);
4940         pSMB->ByteCount = cpu_to_le16(byte_count);
4941
4942         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4943                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4944         if (rc) {
4945                 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4946                 goto GetDFSRefExit;
4947         }
4948         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4949
4950         /* BB Also check if enough total bytes returned? */
4951         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4952                 rc = -EIO;      /* bad smb */
4953                 goto GetDFSRefExit;
4954         }
4955
4956         cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
4957                                 get_bcc(&pSMBr->hdr),
4958                                 le16_to_cpu(pSMBr->t2.DataOffset));
4959
4960         /* parse returned result into more usable form */
4961         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4962                                  target_nodes, nls_codepage, remap,
4963                                  searchName);
4964
4965 GetDFSRefExit:
4966         cifs_buf_release(pSMB);
4967
4968         if (rc == -EAGAIN)
4969                 goto getDFSRetry;
4970
4971         return rc;
4972 }
4973
4974 /* Query File System Info such as free space to old servers such as Win 9x */
4975 int
4976 SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4977 {
4978 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4979         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4980         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4981         FILE_SYSTEM_ALLOC_INFO *response_data;
4982         int rc = 0;
4983         int bytes_returned = 0;
4984         __u16 params, byte_count;
4985
4986         cFYI(1, "OldQFSInfo");
4987 oldQFSInfoRetry:
4988         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4989                 (void **) &pSMBr);
4990         if (rc)
4991                 return rc;
4992
4993         params = 2;     /* level */
4994         pSMB->TotalDataCount = 0;
4995         pSMB->MaxParameterCount = cpu_to_le16(2);
4996         pSMB->MaxDataCount = cpu_to_le16(1000);
4997         pSMB->MaxSetupCount = 0;
4998         pSMB->Reserved = 0;
4999         pSMB->Flags = 0;
5000         pSMB->Timeout = 0;
5001         pSMB->Reserved2 = 0;
5002         byte_count = params + 1 /* pad */ ;
5003         pSMB->TotalParameterCount = cpu_to_le16(params);
5004         pSMB->ParameterCount = pSMB->TotalParameterCount;
5005         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5006         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5007         pSMB->DataCount = 0;
5008         pSMB->DataOffset = 0;
5009         pSMB->SetupCount = 1;
5010         pSMB->Reserved3 = 0;
5011         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5012         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5013         inc_rfc1001_len(pSMB, byte_count);
5014         pSMB->ByteCount = cpu_to_le16(byte_count);
5015
5016         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5017                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5018         if (rc) {
5019                 cFYI(1, "Send error in QFSInfo = %d", rc);
5020         } else {                /* decode response */
5021                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5022
5023                 if (rc || get_bcc(&pSMBr->hdr) < 18)
5024                         rc = -EIO;      /* bad smb */
5025                 else {
5026                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5027                         cFYI(1, "qfsinf resp BCC: %d  Offset %d",
5028                                  get_bcc(&pSMBr->hdr), data_offset);
5029
5030                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
5031                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5032                         FSData->f_bsize =
5033                                 le16_to_cpu(response_data->BytesPerSector) *
5034                                 le32_to_cpu(response_data->
5035                                         SectorsPerAllocationUnit);
5036                         FSData->f_blocks =
5037                                le32_to_cpu(response_data->TotalAllocationUnits);
5038                         FSData->f_bfree = FSData->f_bavail =
5039                                 le32_to_cpu(response_data->FreeAllocationUnits);
5040                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5041                              (unsigned long long)FSData->f_blocks,
5042                              (unsigned long long)FSData->f_bfree,
5043                              FSData->f_bsize);
5044                 }
5045         }
5046         cifs_buf_release(pSMB);
5047
5048         if (rc == -EAGAIN)
5049                 goto oldQFSInfoRetry;
5050
5051         return rc;
5052 }
5053
5054 int
5055 CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
5056 {
5057 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5058         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5059         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5060         FILE_SYSTEM_INFO *response_data;
5061         int rc = 0;
5062         int bytes_returned = 0;
5063         __u16 params, byte_count;
5064
5065         cFYI(1, "In QFSInfo");
5066 QFSInfoRetry:
5067         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5068                       (void **) &pSMBr);
5069         if (rc)
5070                 return rc;
5071
5072         params = 2;     /* level */
5073         pSMB->TotalDataCount = 0;
5074         pSMB->MaxParameterCount = cpu_to_le16(2);
5075         pSMB->MaxDataCount = cpu_to_le16(1000);
5076         pSMB->MaxSetupCount = 0;
5077         pSMB->Reserved = 0;
5078         pSMB->Flags = 0;
5079         pSMB->Timeout = 0;
5080         pSMB->Reserved2 = 0;
5081         byte_count = params + 1 /* pad */ ;
5082         pSMB->TotalParameterCount = cpu_to_le16(params);
5083         pSMB->ParameterCount = pSMB->TotalParameterCount;
5084         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5085                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5086         pSMB->DataCount = 0;
5087         pSMB->DataOffset = 0;
5088         pSMB->SetupCount = 1;
5089         pSMB->Reserved3 = 0;
5090         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5091         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5092         inc_rfc1001_len(pSMB, byte_count);
5093         pSMB->ByteCount = cpu_to_le16(byte_count);
5094
5095         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5096                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5097         if (rc) {
5098                 cFYI(1, "Send error in QFSInfo = %d", rc);
5099         } else {                /* decode response */
5100                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5101
5102                 if (rc || get_bcc(&pSMBr->hdr) < 24)
5103                         rc = -EIO;      /* bad smb */
5104                 else {
5105                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5106
5107                         response_data =
5108                             (FILE_SYSTEM_INFO
5109                              *) (((char *) &pSMBr->hdr.Protocol) +
5110                                  data_offset);
5111                         FSData->f_bsize =
5112                             le32_to_cpu(response_data->BytesPerSector) *
5113                             le32_to_cpu(response_data->
5114                                         SectorsPerAllocationUnit);
5115                         FSData->f_blocks =
5116                             le64_to_cpu(response_data->TotalAllocationUnits);
5117                         FSData->f_bfree = FSData->f_bavail =
5118                             le64_to_cpu(response_data->FreeAllocationUnits);
5119                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5120                              (unsigned long long)FSData->f_blocks,
5121                              (unsigned long long)FSData->f_bfree,
5122                              FSData->f_bsize);
5123                 }
5124         }
5125         cifs_buf_release(pSMB);
5126
5127         if (rc == -EAGAIN)
5128                 goto QFSInfoRetry;
5129
5130         return rc;
5131 }
5132
5133 int
5134 CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
5135 {
5136 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5137         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5138         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5139         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5140         int rc = 0;
5141         int bytes_returned = 0;
5142         __u16 params, byte_count;
5143
5144         cFYI(1, "In QFSAttributeInfo");
5145 QFSAttributeRetry:
5146         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5147                       (void **) &pSMBr);
5148         if (rc)
5149                 return rc;
5150
5151         params = 2;     /* level */
5152         pSMB->TotalDataCount = 0;
5153         pSMB->MaxParameterCount = cpu_to_le16(2);
5154         /* BB find exact max SMB PDU from sess structure BB */
5155         pSMB->MaxDataCount = cpu_to_le16(1000);
5156         pSMB->MaxSetupCount = 0;
5157         pSMB->Reserved = 0;
5158         pSMB->Flags = 0;
5159         pSMB->Timeout = 0;
5160         pSMB->Reserved2 = 0;
5161         byte_count = params + 1 /* pad */ ;
5162         pSMB->TotalParameterCount = cpu_to_le16(params);
5163         pSMB->ParameterCount = pSMB->TotalParameterCount;
5164         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5165                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5166         pSMB->DataCount = 0;
5167         pSMB->DataOffset = 0;
5168         pSMB->SetupCount = 1;
5169         pSMB->Reserved3 = 0;
5170         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5171         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5172         inc_rfc1001_len(pSMB, byte_count);
5173         pSMB->ByteCount = cpu_to_le16(byte_count);
5174
5175         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5176                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5177         if (rc) {
5178                 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5179         } else {                /* decode response */
5180                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5181
5182                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5183                         /* BB also check if enough bytes returned */
5184                         rc = -EIO;      /* bad smb */
5185                 } else {
5186                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5187                         response_data =
5188                             (FILE_SYSTEM_ATTRIBUTE_INFO
5189                              *) (((char *) &pSMBr->hdr.Protocol) +
5190                                  data_offset);
5191                         memcpy(&tcon->fsAttrInfo, response_data,
5192                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5193                 }
5194         }
5195         cifs_buf_release(pSMB);
5196
5197         if (rc == -EAGAIN)
5198                 goto QFSAttributeRetry;
5199
5200         return rc;
5201 }
5202
5203 int
5204 CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
5205 {
5206 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5207         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5208         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5209         FILE_SYSTEM_DEVICE_INFO *response_data;
5210         int rc = 0;
5211         int bytes_returned = 0;
5212         __u16 params, byte_count;
5213
5214         cFYI(1, "In QFSDeviceInfo");
5215 QFSDeviceRetry:
5216         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5217                       (void **) &pSMBr);
5218         if (rc)
5219                 return rc;
5220
5221         params = 2;     /* level */
5222         pSMB->TotalDataCount = 0;
5223         pSMB->MaxParameterCount = cpu_to_le16(2);
5224         /* BB find exact max SMB PDU from sess structure BB */
5225         pSMB->MaxDataCount = cpu_to_le16(1000);
5226         pSMB->MaxSetupCount = 0;
5227         pSMB->Reserved = 0;
5228         pSMB->Flags = 0;
5229         pSMB->Timeout = 0;
5230         pSMB->Reserved2 = 0;
5231         byte_count = params + 1 /* pad */ ;
5232         pSMB->TotalParameterCount = cpu_to_le16(params);
5233         pSMB->ParameterCount = pSMB->TotalParameterCount;
5234         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5235                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5236
5237         pSMB->DataCount = 0;
5238         pSMB->DataOffset = 0;
5239         pSMB->SetupCount = 1;
5240         pSMB->Reserved3 = 0;
5241         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5242         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5243         inc_rfc1001_len(pSMB, byte_count);
5244         pSMB->ByteCount = cpu_to_le16(byte_count);
5245
5246         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5247                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5248         if (rc) {
5249                 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5250         } else {                /* decode response */
5251                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5252
5253                 if (rc || get_bcc(&pSMBr->hdr) <
5254                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5255                         rc = -EIO;      /* bad smb */
5256                 else {
5257                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5258                         response_data =
5259                             (FILE_SYSTEM_DEVICE_INFO *)
5260                                 (((char *) &pSMBr->hdr.Protocol) +
5261                                  data_offset);
5262                         memcpy(&tcon->fsDevInfo, response_data,
5263                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5264                 }
5265         }
5266         cifs_buf_release(pSMB);
5267
5268         if (rc == -EAGAIN)
5269                 goto QFSDeviceRetry;
5270
5271         return rc;
5272 }
5273
5274 int
5275 CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
5276 {
5277 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5278         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5279         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5280         FILE_SYSTEM_UNIX_INFO *response_data;
5281         int rc = 0;
5282         int bytes_returned = 0;
5283         __u16 params, byte_count;
5284
5285         cFYI(1, "In QFSUnixInfo");
5286 QFSUnixRetry:
5287         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5288                                    (void **) &pSMB, (void **) &pSMBr);
5289         if (rc)
5290                 return rc;
5291
5292         params = 2;     /* level */
5293         pSMB->TotalDataCount = 0;
5294         pSMB->DataCount = 0;
5295         pSMB->DataOffset = 0;
5296         pSMB->MaxParameterCount = cpu_to_le16(2);
5297         /* BB find exact max SMB PDU from sess structure BB */
5298         pSMB->MaxDataCount = cpu_to_le16(100);
5299         pSMB->MaxSetupCount = 0;
5300         pSMB->Reserved = 0;
5301         pSMB->Flags = 0;
5302         pSMB->Timeout = 0;
5303         pSMB->Reserved2 = 0;
5304         byte_count = params + 1 /* pad */ ;
5305         pSMB->ParameterCount = cpu_to_le16(params);
5306         pSMB->TotalParameterCount = pSMB->ParameterCount;
5307         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5308                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5309         pSMB->SetupCount = 1;
5310         pSMB->Reserved3 = 0;
5311         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5312         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5313         inc_rfc1001_len(pSMB, byte_count);
5314         pSMB->ByteCount = cpu_to_le16(byte_count);
5315
5316         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5317                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5318         if (rc) {
5319                 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5320         } else {                /* decode response */
5321                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5322
5323                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5324                         rc = -EIO;      /* bad smb */
5325                 } else {
5326                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5327                         response_data =
5328                             (FILE_SYSTEM_UNIX_INFO
5329                              *) (((char *) &pSMBr->hdr.Protocol) +
5330                                  data_offset);
5331                         memcpy(&tcon->fsUnixInfo, response_data,
5332                                sizeof(FILE_SYSTEM_UNIX_INFO));
5333                 }
5334         }
5335         cifs_buf_release(pSMB);
5336
5337         if (rc == -EAGAIN)
5338                 goto QFSUnixRetry;
5339
5340
5341         return rc;
5342 }
5343
5344 int
5345 CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
5346 {
5347 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5348         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5349         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5350         int rc = 0;
5351         int bytes_returned = 0;
5352         __u16 params, param_offset, offset, byte_count;
5353
5354         cFYI(1, "In SETFSUnixInfo");
5355 SETFSUnixRetry:
5356         /* BB switch to small buf init to save memory */
5357         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5358                                         (void **) &pSMB, (void **) &pSMBr);
5359         if (rc)
5360                 return rc;
5361
5362         params = 4;     /* 2 bytes zero followed by info level. */
5363         pSMB->MaxSetupCount = 0;
5364         pSMB->Reserved = 0;
5365         pSMB->Flags = 0;
5366         pSMB->Timeout = 0;
5367         pSMB->Reserved2 = 0;
5368         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5369                                 - 4;
5370         offset = param_offset + params;
5371
5372         pSMB->MaxParameterCount = cpu_to_le16(4);
5373         /* BB find exact max SMB PDU from sess structure BB */
5374         pSMB->MaxDataCount = cpu_to_le16(100);
5375         pSMB->SetupCount = 1;
5376         pSMB->Reserved3 = 0;
5377         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5378         byte_count = 1 /* pad */ + params + 12;
5379
5380         pSMB->DataCount = cpu_to_le16(12);
5381         pSMB->ParameterCount = cpu_to_le16(params);
5382         pSMB->TotalDataCount = pSMB->DataCount;
5383         pSMB->TotalParameterCount = pSMB->ParameterCount;
5384         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5385         pSMB->DataOffset = cpu_to_le16(offset);
5386
5387         /* Params. */
5388         pSMB->FileNum = 0;
5389         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5390
5391         /* Data. */
5392         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5393         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5394         pSMB->ClientUnixCap = cpu_to_le64(cap);
5395
5396         inc_rfc1001_len(pSMB, byte_count);
5397         pSMB->ByteCount = cpu_to_le16(byte_count);
5398
5399         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5400                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5401         if (rc) {
5402                 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5403         } else {                /* decode response */
5404                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5405                 if (rc)
5406                         rc = -EIO;      /* bad smb */
5407         }
5408         cifs_buf_release(pSMB);
5409
5410         if (rc == -EAGAIN)
5411                 goto SETFSUnixRetry;
5412
5413         return rc;
5414 }
5415
5416
5417
5418 int
5419 CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
5420                    struct kstatfs *FSData)
5421 {
5422 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5423         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5424         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5425         FILE_SYSTEM_POSIX_INFO *response_data;
5426         int rc = 0;
5427         int bytes_returned = 0;
5428         __u16 params, byte_count;
5429
5430         cFYI(1, "In QFSPosixInfo");
5431 QFSPosixRetry:
5432         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5433                       (void **) &pSMBr);
5434         if (rc)
5435                 return rc;
5436
5437         params = 2;     /* level */
5438         pSMB->TotalDataCount = 0;
5439         pSMB->DataCount = 0;
5440         pSMB->DataOffset = 0;
5441         pSMB->MaxParameterCount = cpu_to_le16(2);
5442         /* BB find exact max SMB PDU from sess structure BB */
5443         pSMB->MaxDataCount = cpu_to_le16(100);
5444         pSMB->MaxSetupCount = 0;
5445         pSMB->Reserved = 0;
5446         pSMB->Flags = 0;
5447         pSMB->Timeout = 0;
5448         pSMB->Reserved2 = 0;
5449         byte_count = params + 1 /* pad */ ;
5450         pSMB->ParameterCount = cpu_to_le16(params);
5451         pSMB->TotalParameterCount = pSMB->ParameterCount;
5452         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5453                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5454         pSMB->SetupCount = 1;
5455         pSMB->Reserved3 = 0;
5456         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5457         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5458         inc_rfc1001_len(pSMB, byte_count);
5459         pSMB->ByteCount = cpu_to_le16(byte_count);
5460
5461         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5462                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5463         if (rc) {
5464                 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5465         } else {                /* decode response */
5466                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5467
5468                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5469                         rc = -EIO;      /* bad smb */
5470                 } else {
5471                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5472                         response_data =
5473                             (FILE_SYSTEM_POSIX_INFO
5474                              *) (((char *) &pSMBr->hdr.Protocol) +
5475                                  data_offset);
5476                         FSData->f_bsize =
5477                                         le32_to_cpu(response_data->BlockSize);
5478                         FSData->f_blocks =
5479                                         le64_to_cpu(response_data->TotalBlocks);
5480                         FSData->f_bfree =
5481                             le64_to_cpu(response_data->BlocksAvail);
5482                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5483                                 FSData->f_bavail = FSData->f_bfree;
5484                         } else {
5485                                 FSData->f_bavail =
5486                                     le64_to_cpu(response_data->UserBlocksAvail);
5487                         }
5488                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5489                                 FSData->f_files =
5490                                      le64_to_cpu(response_data->TotalFileNodes);
5491                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5492                                 FSData->f_ffree =
5493                                       le64_to_cpu(response_data->FreeFileNodes);
5494                 }
5495         }
5496         cifs_buf_release(pSMB);
5497
5498         if (rc == -EAGAIN)
5499                 goto QFSPosixRetry;
5500
5501         return rc;
5502 }
5503
5504
5505 /* We can not use write of zero bytes trick to
5506    set file size due to need for large file support.  Also note that
5507    this SetPathInfo is preferred to SetFileInfo based method in next
5508    routine which is only needed to work around a sharing violation bug
5509    in Samba which this routine can run into */
5510
5511 int
5512 CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
5513               __u64 size, bool SetAllocation,
5514               const struct nls_table *nls_codepage, int remap)
5515 {
5516         struct smb_com_transaction2_spi_req *pSMB = NULL;
5517         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5518         struct file_end_of_file_info *parm_data;
5519         int name_len;
5520         int rc = 0;
5521         int bytes_returned = 0;
5522         __u16 params, byte_count, data_count, param_offset, offset;
5523
5524         cFYI(1, "In SetEOF");
5525 SetEOFRetry:
5526         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5527                       (void **) &pSMBr);
5528         if (rc)
5529                 return rc;
5530
5531         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5532                 name_len =
5533                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5534                                        PATH_MAX, nls_codepage, remap);
5535                 name_len++;     /* trailing null */
5536                 name_len *= 2;
5537         } else {        /* BB improve the check for buffer overruns BB */
5538                 name_len = strnlen(fileName, PATH_MAX);
5539                 name_len++;     /* trailing null */
5540                 strncpy(pSMB->FileName, fileName, name_len);
5541         }
5542         params = 6 + name_len;
5543         data_count = sizeof(struct file_end_of_file_info);
5544         pSMB->MaxParameterCount = cpu_to_le16(2);
5545         pSMB->MaxDataCount = cpu_to_le16(4100);
5546         pSMB->MaxSetupCount = 0;
5547         pSMB->Reserved = 0;
5548         pSMB->Flags = 0;
5549         pSMB->Timeout = 0;
5550         pSMB->Reserved2 = 0;
5551         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5552                                 InformationLevel) - 4;
5553         offset = param_offset + params;
5554         if (SetAllocation) {
5555                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5556                         pSMB->InformationLevel =
5557                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5558                 else
5559                         pSMB->InformationLevel =
5560                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5561         } else /* Set File Size */  {
5562             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5563                     pSMB->InformationLevel =
5564                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5565             else
5566                     pSMB->InformationLevel =
5567                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5568         }
5569
5570         parm_data =
5571             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5572                                        offset);
5573         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5574         pSMB->DataOffset = cpu_to_le16(offset);
5575         pSMB->SetupCount = 1;
5576         pSMB->Reserved3 = 0;
5577         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5578         byte_count = 3 /* pad */  + params + data_count;
5579         pSMB->DataCount = cpu_to_le16(data_count);
5580         pSMB->TotalDataCount = pSMB->DataCount;
5581         pSMB->ParameterCount = cpu_to_le16(params);
5582         pSMB->TotalParameterCount = pSMB->ParameterCount;
5583         pSMB->Reserved4 = 0;
5584         inc_rfc1001_len(pSMB, byte_count);
5585         parm_data->FileSize = cpu_to_le64(size);
5586         pSMB->ByteCount = cpu_to_le16(byte_count);
5587         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5588                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5589         if (rc)
5590                 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5591
5592         cifs_buf_release(pSMB);
5593
5594         if (rc == -EAGAIN)
5595                 goto SetEOFRetry;
5596
5597         return rc;
5598 }
5599
5600 int
5601 CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5602                    __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5603 {
5604         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5605         struct file_end_of_file_info *parm_data;
5606         int rc = 0;
5607         __u16 params, param_offset, offset, byte_count, count;
5608
5609         cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5610                         (long long)size);
5611         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5612
5613         if (rc)
5614                 return rc;
5615
5616         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5617         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5618
5619         params = 6;
5620         pSMB->MaxSetupCount = 0;
5621         pSMB->Reserved = 0;
5622         pSMB->Flags = 0;
5623         pSMB->Timeout = 0;
5624         pSMB->Reserved2 = 0;
5625         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5626         offset = param_offset + params;
5627
5628         count = sizeof(struct file_end_of_file_info);
5629         pSMB->MaxParameterCount = cpu_to_le16(2);
5630         /* BB find exact max SMB PDU from sess structure BB */
5631         pSMB->MaxDataCount = cpu_to_le16(1000);
5632         pSMB->SetupCount = 1;
5633         pSMB->Reserved3 = 0;
5634         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5635         byte_count = 3 /* pad */  + params + count;
5636         pSMB->DataCount = cpu_to_le16(count);
5637         pSMB->ParameterCount = cpu_to_le16(params);
5638         pSMB->TotalDataCount = pSMB->DataCount;
5639         pSMB->TotalParameterCount = pSMB->ParameterCount;
5640         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5641         parm_data =
5642                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5643                                 + offset);
5644         pSMB->DataOffset = cpu_to_le16(offset);
5645         parm_data->FileSize = cpu_to_le64(size);
5646         pSMB->Fid = fid;
5647         if (SetAllocation) {
5648                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5649                         pSMB->InformationLevel =
5650                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5651                 else
5652                         pSMB->InformationLevel =
5653                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5654         } else /* Set File Size */  {
5655             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5656                     pSMB->InformationLevel =
5657                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5658             else
5659                     pSMB->InformationLevel =
5660                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5661         }
5662         pSMB->Reserved4 = 0;
5663         inc_rfc1001_len(pSMB, byte_count);
5664         pSMB->ByteCount = cpu_to_le16(byte_count);
5665         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5666         if (rc) {
5667                 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5668         }
5669
5670         /* Note: On -EAGAIN error only caller can retry on handle based calls
5671                 since file handle passed in no longer valid */
5672
5673         return rc;
5674 }
5675
5676 /* Some legacy servers such as NT4 require that the file times be set on
5677    an open handle, rather than by pathname - this is awkward due to
5678    potential access conflicts on the open, but it is unavoidable for these
5679    old servers since the only other choice is to go from 100 nanosecond DCE
5680    time and resort to the original setpathinfo level which takes the ancient
5681    DOS time format with 2 second granularity */
5682 int
5683 CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5684                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5685 {
5686         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5687         char *data_offset;
5688         int rc = 0;
5689         __u16 params, param_offset, offset, byte_count, count;
5690
5691         cFYI(1, "Set Times (via SetFileInfo)");
5692         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5693
5694         if (rc)
5695                 return rc;
5696
5697         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5698         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5699
5700         params = 6;
5701         pSMB->MaxSetupCount = 0;
5702         pSMB->Reserved = 0;
5703         pSMB->Flags = 0;
5704         pSMB->Timeout = 0;
5705         pSMB->Reserved2 = 0;
5706         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5707         offset = param_offset + params;
5708
5709         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5710
5711         count = sizeof(FILE_BASIC_INFO);
5712         pSMB->MaxParameterCount = cpu_to_le16(2);
5713         /* BB find max SMB PDU from sess */
5714         pSMB->MaxDataCount = cpu_to_le16(1000);
5715         pSMB->SetupCount = 1;
5716         pSMB->Reserved3 = 0;
5717         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5718         byte_count = 3 /* pad */  + params + count;
5719         pSMB->DataCount = cpu_to_le16(count);
5720         pSMB->ParameterCount = cpu_to_le16(params);
5721         pSMB->TotalDataCount = pSMB->DataCount;
5722         pSMB->TotalParameterCount = pSMB->ParameterCount;
5723         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5724         pSMB->DataOffset = cpu_to_le16(offset);
5725         pSMB->Fid = fid;
5726         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5727                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5728         else
5729                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5730         pSMB->Reserved4 = 0;
5731         inc_rfc1001_len(pSMB, byte_count);
5732         pSMB->ByteCount = cpu_to_le16(byte_count);
5733         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5734         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5735         if (rc)
5736                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5737
5738         /* Note: On -EAGAIN error only caller can retry on handle based calls
5739                 since file handle passed in no longer valid */
5740
5741         return rc;
5742 }
5743
5744 int
5745 CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5746                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5747 {
5748         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5749         char *data_offset;
5750         int rc = 0;
5751         __u16 params, param_offset, offset, byte_count, count;
5752
5753         cFYI(1, "Set File Disposition (via SetFileInfo)");
5754         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5755
5756         if (rc)
5757                 return rc;
5758
5759         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5760         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5761
5762         params = 6;
5763         pSMB->MaxSetupCount = 0;
5764         pSMB->Reserved = 0;
5765         pSMB->Flags = 0;
5766         pSMB->Timeout = 0;
5767         pSMB->Reserved2 = 0;
5768         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5769         offset = param_offset + params;
5770
5771         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5772
5773         count = 1;
5774         pSMB->MaxParameterCount = cpu_to_le16(2);
5775         /* BB find max SMB PDU from sess */
5776         pSMB->MaxDataCount = cpu_to_le16(1000);
5777         pSMB->SetupCount = 1;
5778         pSMB->Reserved3 = 0;
5779         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5780         byte_count = 3 /* pad */  + params + count;
5781         pSMB->DataCount = cpu_to_le16(count);
5782         pSMB->ParameterCount = cpu_to_le16(params);
5783         pSMB->TotalDataCount = pSMB->DataCount;
5784         pSMB->TotalParameterCount = pSMB->ParameterCount;
5785         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5786         pSMB->DataOffset = cpu_to_le16(offset);
5787         pSMB->Fid = fid;
5788         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5789         pSMB->Reserved4 = 0;
5790         inc_rfc1001_len(pSMB, byte_count);
5791         pSMB->ByteCount = cpu_to_le16(byte_count);
5792         *data_offset = delete_file ? 1 : 0;
5793         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5794         if (rc)
5795                 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5796
5797         return rc;
5798 }
5799
5800 int
5801 CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5802                    const char *fileName, const FILE_BASIC_INFO *data,
5803                    const struct nls_table *nls_codepage, int remap)
5804 {
5805         TRANSACTION2_SPI_REQ *pSMB = NULL;
5806         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5807         int name_len;
5808         int rc = 0;
5809         int bytes_returned = 0;
5810         char *data_offset;
5811         __u16 params, param_offset, offset, byte_count, count;
5812
5813         cFYI(1, "In SetTimes");
5814
5815 SetTimesRetry:
5816         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5817                       (void **) &pSMBr);
5818         if (rc)
5819                 return rc;
5820
5821         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5822                 name_len =
5823                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5824                                        PATH_MAX, nls_codepage, remap);
5825                 name_len++;     /* trailing null */
5826                 name_len *= 2;
5827         } else {        /* BB improve the check for buffer overruns BB */
5828                 name_len = strnlen(fileName, PATH_MAX);
5829                 name_len++;     /* trailing null */
5830                 strncpy(pSMB->FileName, fileName, name_len);
5831         }
5832
5833         params = 6 + name_len;
5834         count = sizeof(FILE_BASIC_INFO);
5835         pSMB->MaxParameterCount = cpu_to_le16(2);
5836         /* BB find max SMB PDU from sess structure BB */
5837         pSMB->MaxDataCount = cpu_to_le16(1000);
5838         pSMB->MaxSetupCount = 0;
5839         pSMB->Reserved = 0;
5840         pSMB->Flags = 0;
5841         pSMB->Timeout = 0;
5842         pSMB->Reserved2 = 0;
5843         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5844                                 InformationLevel) - 4;
5845         offset = param_offset + params;
5846         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5847         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5848         pSMB->DataOffset = cpu_to_le16(offset);
5849         pSMB->SetupCount = 1;
5850         pSMB->Reserved3 = 0;
5851         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5852         byte_count = 3 /* pad */  + params + count;
5853
5854         pSMB->DataCount = cpu_to_le16(count);
5855         pSMB->ParameterCount = cpu_to_le16(params);
5856         pSMB->TotalDataCount = pSMB->DataCount;
5857         pSMB->TotalParameterCount = pSMB->ParameterCount;
5858         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5859                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5860         else
5861                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5862         pSMB->Reserved4 = 0;
5863         inc_rfc1001_len(pSMB, byte_count);
5864         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5865         pSMB->ByteCount = cpu_to_le16(byte_count);
5866         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5867                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5868         if (rc)
5869                 cFYI(1, "SetPathInfo (times) returned %d", rc);
5870
5871         cifs_buf_release(pSMB);
5872
5873         if (rc == -EAGAIN)
5874                 goto SetTimesRetry;
5875
5876         return rc;
5877 }
5878
5879 /* Can not be used to set time stamps yet (due to old DOS time format) */
5880 /* Can be used to set attributes */
5881 #if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
5882           handling it anyway and NT4 was what we thought it would be needed for
5883           Do not delete it until we prove whether needed for Win9x though */
5884 int
5885 CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5886                 __u16 dos_attrs, const struct nls_table *nls_codepage)
5887 {
5888         SETATTR_REQ *pSMB = NULL;
5889         SETATTR_RSP *pSMBr = NULL;
5890         int rc = 0;
5891         int bytes_returned;
5892         int name_len;
5893
5894         cFYI(1, "In SetAttrLegacy");
5895
5896 SetAttrLgcyRetry:
5897         rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5898                       (void **) &pSMBr);
5899         if (rc)
5900                 return rc;
5901
5902         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5903                 name_len =
5904                         ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5905                                        PATH_MAX, nls_codepage);
5906                 name_len++;     /* trailing null */
5907                 name_len *= 2;
5908         } else {        /* BB improve the check for buffer overruns BB */
5909                 name_len = strnlen(fileName, PATH_MAX);
5910                 name_len++;     /* trailing null */
5911                 strncpy(pSMB->fileName, fileName, name_len);
5912         }
5913         pSMB->attr = cpu_to_le16(dos_attrs);
5914         pSMB->BufferFormat = 0x04;
5915         inc_rfc1001_len(pSMB, name_len + 1);
5916         pSMB->ByteCount = cpu_to_le16(name_len + 1);
5917         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5918                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5919         if (rc)
5920                 cFYI(1, "Error in LegacySetAttr = %d", rc);
5921
5922         cifs_buf_release(pSMB);
5923
5924         if (rc == -EAGAIN)
5925                 goto SetAttrLgcyRetry;
5926
5927         return rc;
5928 }
5929 #endif /* temporarily unneeded SetAttr legacy function */
5930
5931 static void
5932 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5933                         const struct cifs_unix_set_info_args *args)
5934 {
5935         u64 mode = args->mode;
5936
5937         /*
5938          * Samba server ignores set of file size to zero due to bugs in some
5939          * older clients, but we should be precise - we use SetFileSize to
5940          * set file size and do not want to truncate file size to zero
5941          * accidentally as happened on one Samba server beta by putting
5942          * zero instead of -1 here
5943          */
5944         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5945         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5946         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5947         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5948         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5949         data_offset->Uid = cpu_to_le64(args->uid);
5950         data_offset->Gid = cpu_to_le64(args->gid);
5951         /* better to leave device as zero when it is  */
5952         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5953         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5954         data_offset->Permissions = cpu_to_le64(mode);
5955
5956         if (S_ISREG(mode))
5957                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5958         else if (S_ISDIR(mode))
5959                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5960         else if (S_ISLNK(mode))
5961                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5962         else if (S_ISCHR(mode))
5963                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5964         else if (S_ISBLK(mode))
5965                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5966         else if (S_ISFIFO(mode))
5967                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5968         else if (S_ISSOCK(mode))
5969                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5970 }
5971
5972 int
5973 CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5974                        const struct cifs_unix_set_info_args *args,
5975                        u16 fid, u32 pid_of_opener)
5976 {
5977         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5978         FILE_UNIX_BASIC_INFO *data_offset;
5979         int rc = 0;
5980         u16 params, param_offset, offset, byte_count, count;
5981
5982         cFYI(1, "Set Unix Info (via SetFileInfo)");
5983         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5984
5985         if (rc)
5986                 return rc;
5987
5988         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5989         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5990
5991         params = 6;
5992         pSMB->MaxSetupCount = 0;
5993         pSMB->Reserved = 0;
5994         pSMB->Flags = 0;
5995         pSMB->Timeout = 0;
5996         pSMB->Reserved2 = 0;
5997         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5998         offset = param_offset + params;
5999
6000         data_offset = (FILE_UNIX_BASIC_INFO *)
6001                                 ((char *)(&pSMB->hdr.Protocol) + offset);
6002         count = sizeof(FILE_UNIX_BASIC_INFO);
6003
6004         pSMB->MaxParameterCount = cpu_to_le16(2);
6005         /* BB find max SMB PDU from sess */
6006         pSMB->MaxDataCount = cpu_to_le16(1000);
6007         pSMB->SetupCount = 1;
6008         pSMB->Reserved3 = 0;
6009         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6010         byte_count = 3 /* pad */  + params + count;
6011         pSMB->DataCount = cpu_to_le16(count);
6012         pSMB->ParameterCount = cpu_to_le16(params);
6013         pSMB->TotalDataCount = pSMB->DataCount;
6014         pSMB->TotalParameterCount = pSMB->ParameterCount;
6015         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6016         pSMB->DataOffset = cpu_to_le16(offset);
6017         pSMB->Fid = fid;
6018         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6019         pSMB->Reserved4 = 0;
6020         inc_rfc1001_len(pSMB, byte_count);
6021         pSMB->ByteCount = cpu_to_le16(byte_count);
6022
6023         cifs_fill_unix_set_info(data_offset, args);
6024
6025         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6026         if (rc)
6027                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
6028
6029         /* Note: On -EAGAIN error only caller can retry on handle based calls
6030                 since file handle passed in no longer valid */
6031
6032         return rc;
6033 }
6034
6035 int
6036 CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
6037                        const struct cifs_unix_set_info_args *args,
6038                        const struct nls_table *nls_codepage, int remap)
6039 {
6040         TRANSACTION2_SPI_REQ *pSMB = NULL;
6041         TRANSACTION2_SPI_RSP *pSMBr = NULL;
6042         int name_len;
6043         int rc = 0;
6044         int bytes_returned = 0;
6045         FILE_UNIX_BASIC_INFO *data_offset;
6046         __u16 params, param_offset, offset, count, byte_count;
6047
6048         cFYI(1, "In SetUID/GID/Mode");
6049 setPermsRetry:
6050         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6051                       (void **) &pSMBr);
6052         if (rc)
6053                 return rc;
6054
6055         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6056                 name_len =
6057                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6058                                        PATH_MAX, nls_codepage, remap);
6059                 name_len++;     /* trailing null */
6060                 name_len *= 2;
6061         } else {        /* BB improve the check for buffer overruns BB */
6062                 name_len = strnlen(fileName, PATH_MAX);
6063                 name_len++;     /* trailing null */
6064                 strncpy(pSMB->FileName, fileName, name_len);
6065         }
6066
6067         params = 6 + name_len;
6068         count = sizeof(FILE_UNIX_BASIC_INFO);
6069         pSMB->MaxParameterCount = cpu_to_le16(2);
6070         /* BB find max SMB PDU from sess structure BB */
6071         pSMB->MaxDataCount = cpu_to_le16(1000);
6072         pSMB->MaxSetupCount = 0;
6073         pSMB->Reserved = 0;
6074         pSMB->Flags = 0;
6075         pSMB->Timeout = 0;
6076         pSMB->Reserved2 = 0;
6077         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6078                                 InformationLevel) - 4;
6079         offset = param_offset + params;
6080         data_offset =
6081             (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
6082                                       offset);
6083         memset(data_offset, 0, count);
6084         pSMB->DataOffset = cpu_to_le16(offset);
6085         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6086         pSMB->SetupCount = 1;
6087         pSMB->Reserved3 = 0;
6088         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6089         byte_count = 3 /* pad */  + params + count;
6090         pSMB->ParameterCount = cpu_to_le16(params);
6091         pSMB->DataCount = cpu_to_le16(count);
6092         pSMB->TotalParameterCount = pSMB->ParameterCount;
6093         pSMB->TotalDataCount = pSMB->DataCount;
6094         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6095         pSMB->Reserved4 = 0;
6096         inc_rfc1001_len(pSMB, byte_count);
6097
6098         cifs_fill_unix_set_info(data_offset, args);
6099
6100         pSMB->ByteCount = cpu_to_le16(byte_count);
6101         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6102                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6103         if (rc)
6104                 cFYI(1, "SetPathInfo (perms) returned %d", rc);
6105
6106         cifs_buf_release(pSMB);
6107         if (rc == -EAGAIN)
6108                 goto setPermsRetry;
6109         return rc;
6110 }
6111
6112 #ifdef CONFIG_CIFS_XATTR
6113 /*
6114  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6115  * function used by listxattr and getxattr type calls. When ea_name is set,
6116  * it looks for that attribute name and stuffs that value into the EAData
6117  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6118  * buffer. In both cases, the return value is either the length of the
6119  * resulting data or a negative error code. If EAData is a NULL pointer then
6120  * the data isn't copied to it, but the length is returned.
6121  */
6122 ssize_t
6123 CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
6124                 const unsigned char *searchName, const unsigned char *ea_name,
6125                 char *EAData, size_t buf_size,
6126                 const struct nls_table *nls_codepage, int remap)
6127 {
6128                 /* BB assumes one setup word */
6129         TRANSACTION2_QPI_REQ *pSMB = NULL;
6130         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6131         int rc = 0;
6132         int bytes_returned;
6133         int list_len;
6134         struct fealist *ea_response_data;
6135         struct fea *temp_fea;
6136         char *temp_ptr;
6137         char *end_of_smb;
6138         __u16 params, byte_count, data_offset;
6139         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6140
6141         cFYI(1, "In Query All EAs path %s", searchName);
6142 QAllEAsRetry:
6143         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6144                       (void **) &pSMBr);
6145         if (rc)
6146                 return rc;
6147
6148         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6149                 list_len =
6150                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6151                                        PATH_MAX, nls_codepage, remap);
6152                 list_len++;     /* trailing null */
6153                 list_len *= 2;
6154         } else {        /* BB improve the check for buffer overruns BB */
6155                 list_len = strnlen(searchName, PATH_MAX);
6156                 list_len++;     /* trailing null */
6157                 strncpy(pSMB->FileName, searchName, list_len);
6158         }
6159
6160         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6161         pSMB->TotalDataCount = 0;
6162         pSMB->MaxParameterCount = cpu_to_le16(2);
6163         /* BB find exact max SMB PDU from sess structure BB */
6164         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6165         pSMB->MaxSetupCount = 0;
6166         pSMB->Reserved = 0;
6167         pSMB->Flags = 0;
6168         pSMB->Timeout = 0;
6169         pSMB->Reserved2 = 0;
6170         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6171         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6172         pSMB->DataCount = 0;
6173         pSMB->DataOffset = 0;
6174         pSMB->SetupCount = 1;
6175         pSMB->Reserved3 = 0;
6176         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6177         byte_count = params + 1 /* pad */ ;
6178         pSMB->TotalParameterCount = cpu_to_le16(params);
6179         pSMB->ParameterCount = pSMB->TotalParameterCount;
6180         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6181         pSMB->Reserved4 = 0;
6182         inc_rfc1001_len(pSMB, byte_count);
6183         pSMB->ByteCount = cpu_to_le16(byte_count);
6184
6185         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6186                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6187         if (rc) {
6188                 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6189                 goto QAllEAsOut;
6190         }
6191
6192
6193         /* BB also check enough total bytes returned */
6194         /* BB we need to improve the validity checking
6195         of these trans2 responses */
6196
6197         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6198         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6199                 rc = -EIO;      /* bad smb */
6200                 goto QAllEAsOut;
6201         }
6202
6203         /* check that length of list is not more than bcc */
6204         /* check that each entry does not go beyond length
6205            of list */
6206         /* check that each element of each entry does not
6207            go beyond end of list */
6208         /* validate_trans2_offsets() */
6209         /* BB check if start of smb + data_offset > &bcc+ bcc */
6210
6211         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6212         ea_response_data = (struct fealist *)
6213                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6214
6215         list_len = le32_to_cpu(ea_response_data->list_len);
6216         cFYI(1, "ea length %d", list_len);
6217         if (list_len <= 8) {
6218                 cFYI(1, "empty EA list returned from server");
6219                 goto QAllEAsOut;
6220         }
6221
6222         /* make sure list_len doesn't go past end of SMB */
6223         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6224         if ((char *)ea_response_data + list_len > end_of_smb) {
6225                 cFYI(1, "EA list appears to go beyond SMB");
6226                 rc = -EIO;
6227                 goto QAllEAsOut;
6228         }
6229
6230         /* account for ea list len */
6231         list_len -= 4;
6232         temp_fea = ea_response_data->list;
6233         temp_ptr = (char *)temp_fea;
6234         while (list_len > 0) {
6235                 unsigned int name_len;
6236                 __u16 value_len;
6237
6238                 list_len -= 4;
6239                 temp_ptr += 4;
6240                 /* make sure we can read name_len and value_len */
6241                 if (list_len < 0) {
6242                         cFYI(1, "EA entry goes beyond length of list");
6243                         rc = -EIO;
6244                         goto QAllEAsOut;
6245                 }
6246
6247                 name_len = temp_fea->name_len;
6248                 value_len = le16_to_cpu(temp_fea->value_len);
6249                 list_len -= name_len + 1 + value_len;
6250                 if (list_len < 0) {
6251                         cFYI(1, "EA entry goes beyond length of list");
6252                         rc = -EIO;
6253                         goto QAllEAsOut;
6254                 }
6255
6256                 if (ea_name) {
6257                         if (ea_name_len == name_len &&
6258                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6259                                 temp_ptr += name_len + 1;
6260                                 rc = value_len;
6261                                 if (buf_size == 0)
6262                                         goto QAllEAsOut;
6263                                 if ((size_t)value_len > buf_size) {
6264                                         rc = -ERANGE;
6265                                         goto QAllEAsOut;
6266                                 }
6267                                 memcpy(EAData, temp_ptr, value_len);
6268                                 goto QAllEAsOut;
6269                         }
6270                 } else {
6271                         /* account for prefix user. and trailing null */
6272                         rc += (5 + 1 + name_len);
6273                         if (rc < (int) buf_size) {
6274                                 memcpy(EAData, "user.", 5);
6275                                 EAData += 5;
6276                                 memcpy(EAData, temp_ptr, name_len);
6277                                 EAData += name_len;
6278                                 /* null terminate name */
6279                                 *EAData = 0;
6280                                 ++EAData;
6281                         } else if (buf_size == 0) {
6282                                 /* skip copy - calc size only */
6283                         } else {
6284                                 /* stop before overrun buffer */
6285                                 rc = -ERANGE;
6286                                 break;
6287                         }
6288                 }
6289                 temp_ptr += name_len + 1 + value_len;
6290                 temp_fea = (struct fea *)temp_ptr;
6291         }
6292
6293         /* didn't find the named attribute */
6294         if (ea_name)
6295                 rc = -ENODATA;
6296
6297 QAllEAsOut:
6298         cifs_buf_release(pSMB);
6299         if (rc == -EAGAIN)
6300                 goto QAllEAsRetry;
6301
6302         return (ssize_t)rc;
6303 }
6304
6305 int
6306 CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
6307              const char *ea_name, const void *ea_value,
6308              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6309              int remap)
6310 {
6311         struct smb_com_transaction2_spi_req *pSMB = NULL;
6312         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6313         struct fealist *parm_data;
6314         int name_len;
6315         int rc = 0;
6316         int bytes_returned = 0;
6317         __u16 params, param_offset, byte_count, offset, count;
6318
6319         cFYI(1, "In SetEA");
6320 SetEARetry:
6321         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6322                       (void **) &pSMBr);
6323         if (rc)
6324                 return rc;
6325
6326         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6327                 name_len =
6328                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6329                                        PATH_MAX, nls_codepage, remap);
6330                 name_len++;     /* trailing null */
6331                 name_len *= 2;
6332         } else {        /* BB improve the check for buffer overruns BB */
6333                 name_len = strnlen(fileName, PATH_MAX);
6334                 name_len++;     /* trailing null */
6335                 strncpy(pSMB->FileName, fileName, name_len);
6336         }
6337
6338         params = 6 + name_len;
6339
6340         /* done calculating parms using name_len of file name,
6341         now use name_len to calculate length of ea name
6342         we are going to create in the inode xattrs */
6343         if (ea_name == NULL)
6344                 name_len = 0;
6345         else
6346                 name_len = strnlen(ea_name, 255);
6347
6348         count = sizeof(*parm_data) + ea_value_len + name_len;
6349         pSMB->MaxParameterCount = cpu_to_le16(2);
6350         /* BB find max SMB PDU from sess */
6351         pSMB->MaxDataCount = cpu_to_le16(1000);
6352         pSMB->MaxSetupCount = 0;
6353         pSMB->Reserved = 0;
6354         pSMB->Flags = 0;
6355         pSMB->Timeout = 0;
6356         pSMB->Reserved2 = 0;
6357         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6358                                 InformationLevel) - 4;
6359         offset = param_offset + params;
6360         pSMB->InformationLevel =
6361                 cpu_to_le16(SMB_SET_FILE_EA);
6362
6363         parm_data =
6364                 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6365                                        offset);
6366         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6367         pSMB->DataOffset = cpu_to_le16(offset);
6368         pSMB->SetupCount = 1;
6369         pSMB->Reserved3 = 0;
6370         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6371         byte_count = 3 /* pad */  + params + count;
6372         pSMB->DataCount = cpu_to_le16(count);
6373         parm_data->list_len = cpu_to_le32(count);
6374         parm_data->list[0].EA_flags = 0;
6375         /* we checked above that name len is less than 255 */
6376         parm_data->list[0].name_len = (__u8)name_len;
6377         /* EA names are always ASCII */
6378         if (ea_name)
6379                 strncpy(parm_data->list[0].name, ea_name, name_len);
6380         parm_data->list[0].name[name_len] = 0;
6381         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6382         /* caller ensures that ea_value_len is less than 64K but
6383         we need to ensure that it fits within the smb */
6384
6385         /*BB add length check to see if it would fit in
6386              negotiated SMB buffer size BB */
6387         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6388         if (ea_value_len)
6389                 memcpy(parm_data->list[0].name+name_len+1,
6390                        ea_value, ea_value_len);
6391
6392         pSMB->TotalDataCount = pSMB->DataCount;
6393         pSMB->ParameterCount = cpu_to_le16(params);
6394         pSMB->TotalParameterCount = pSMB->ParameterCount;
6395         pSMB->Reserved4 = 0;
6396         inc_rfc1001_len(pSMB, byte_count);
6397         pSMB->ByteCount = cpu_to_le16(byte_count);
6398         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6399                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6400         if (rc)
6401                 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6402
6403         cifs_buf_release(pSMB);
6404
6405         if (rc == -EAGAIN)
6406                 goto SetEARetry;
6407
6408         return rc;
6409 }
6410 #endif
6411
6412 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6413 /*
6414  *      Years ago the kernel added a "dnotify" function for Samba server,
6415  *      to allow network clients (such as Windows) to display updated
6416  *      lists of files in directory listings automatically when
6417  *      files are added by one user when another user has the
6418  *      same directory open on their desktop.  The Linux cifs kernel
6419  *      client hooked into the kernel side of this interface for
6420  *      the same reason, but ironically when the VFS moved from
6421  *      "dnotify" to "inotify" it became harder to plug in Linux
6422  *      network file system clients (the most obvious use case
6423  *      for notify interfaces is when multiple users can update
6424  *      the contents of the same directory - exactly what network
6425  *      file systems can do) although the server (Samba) could
6426  *      still use it.  For the short term we leave the worker
6427  *      function ifdeffed out (below) until inotify is fixed
6428  *      in the VFS to make it easier to plug in network file
6429  *      system clients.  If inotify turns out to be permanently
6430  *      incompatible for network fs clients, we could instead simply
6431  *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
6432  */
6433 int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
6434                   const int notify_subdirs, const __u16 netfid,
6435                   __u32 filter, struct file *pfile, int multishot,
6436                   const struct nls_table *nls_codepage)
6437 {
6438         int rc = 0;
6439         struct smb_com_transaction_change_notify_req *pSMB = NULL;
6440         struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6441         struct dir_notify_req *dnotify_req;
6442         int bytes_returned;
6443
6444         cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6445         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6446                       (void **) &pSMBr);
6447         if (rc)
6448                 return rc;
6449
6450         pSMB->TotalParameterCount = 0 ;
6451         pSMB->TotalDataCount = 0;
6452         pSMB->MaxParameterCount = cpu_to_le32(2);
6453         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6454         pSMB->MaxSetupCount = 4;
6455         pSMB->Reserved = 0;
6456         pSMB->ParameterOffset = 0;
6457         pSMB->DataCount = 0;
6458         pSMB->DataOffset = 0;
6459         pSMB->SetupCount = 4; /* single byte does not need le conversion */
6460         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6461         pSMB->ParameterCount = pSMB->TotalParameterCount;
6462         if (notify_subdirs)
6463                 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6464         pSMB->Reserved2 = 0;
6465         pSMB->CompletionFilter = cpu_to_le32(filter);
6466         pSMB->Fid = netfid; /* file handle always le */
6467         pSMB->ByteCount = 0;
6468
6469         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6470                          (struct smb_hdr *)pSMBr, &bytes_returned,
6471                          CIFS_ASYNC_OP);
6472         if (rc) {
6473                 cFYI(1, "Error in Notify = %d", rc);
6474         } else {
6475                 /* Add file to outstanding requests */
6476                 /* BB change to kmem cache alloc */
6477                 dnotify_req = kmalloc(
6478                                                 sizeof(struct dir_notify_req),
6479                                                  GFP_KERNEL);
6480                 if (dnotify_req) {
6481                         dnotify_req->Pid = pSMB->hdr.Pid;
6482                         dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6483                         dnotify_req->Mid = pSMB->hdr.Mid;
6484                         dnotify_req->Tid = pSMB->hdr.Tid;
6485                         dnotify_req->Uid = pSMB->hdr.Uid;
6486                         dnotify_req->netfid = netfid;
6487                         dnotify_req->pfile = pfile;
6488                         dnotify_req->filter = filter;
6489                         dnotify_req->multishot = multishot;
6490                         spin_lock(&GlobalMid_Lock);
6491                         list_add_tail(&dnotify_req->lhead,
6492                                         &GlobalDnotifyReqList);
6493                         spin_unlock(&GlobalMid_Lock);
6494                 } else
6495                         rc = -ENOMEM;
6496         }
6497         cifs_buf_release(pSMB);
6498         return rc;
6499 }
6500 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */