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