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