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