CIFS: Rename *UCS* functions to *UTF16*
[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                     cifsConvertToUTF16((__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                     cifsConvertToUTF16((__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 = cifsConvertToUTF16((__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 = cifsConvertToUTF16((__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                     cifsConvertToUTF16((__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                    cifsConvertToUTF16((__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                     cifsConvertToUTF16((__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 int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
2324                const __u8 lock_type, const __u32 num_unlock,
2325                const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2326 {
2327         int rc = 0;
2328         LOCK_REQ *pSMB = NULL;
2329         struct kvec iov[2];
2330         int resp_buf_type;
2331         __u16 count;
2332
2333         cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2334
2335         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2336         if (rc)
2337                 return rc;
2338
2339         pSMB->Timeout = 0;
2340         pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2341         pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2342         pSMB->LockType = lock_type;
2343         pSMB->AndXCommand = 0xFF; /* none */
2344         pSMB->Fid = netfid; /* netfid stays le */
2345
2346         count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2347         inc_rfc1001_len(pSMB, count);
2348         pSMB->ByteCount = cpu_to_le16(count);
2349
2350         iov[0].iov_base = (char *)pSMB;
2351         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2352                          (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2353         iov[1].iov_base = (char *)buf;
2354         iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2355
2356         cifs_stats_inc(&tcon->num_locks);
2357         rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2358         if (rc)
2359                 cFYI(1, "Send error in cifs_lockv = %d", rc);
2360
2361         return rc;
2362 }
2363
2364 int
2365 CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
2366             const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2367             const __u64 offset, const __u32 numUnlock,
2368             const __u32 numLock, const __u8 lockType,
2369             const bool waitFlag, const __u8 oplock_level)
2370 {
2371         int rc = 0;
2372         LOCK_REQ *pSMB = NULL;
2373 /*      LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2374         int bytes_returned;
2375         int timeout = 0;
2376         __u16 count;
2377
2378         cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2379         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2380
2381         if (rc)
2382                 return rc;
2383
2384         if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2385                 timeout = CIFS_ASYNC_OP; /* no response expected */
2386                 pSMB->Timeout = 0;
2387         } else if (waitFlag) {
2388                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2389                 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2390         } else {
2391                 pSMB->Timeout = 0;
2392         }
2393
2394         pSMB->NumberOfLocks = cpu_to_le16(numLock);
2395         pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2396         pSMB->LockType = lockType;
2397         pSMB->OplockLevel = oplock_level;
2398         pSMB->AndXCommand = 0xFF;       /* none */
2399         pSMB->Fid = smb_file_id; /* netfid stays le */
2400
2401         if ((numLock != 0) || (numUnlock != 0)) {
2402                 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2403                 /* BB where to store pid high? */
2404                 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2405                 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2406                 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2407                 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2408                 count = sizeof(LOCKING_ANDX_RANGE);
2409         } else {
2410                 /* oplock break */
2411                 count = 0;
2412         }
2413         inc_rfc1001_len(pSMB, count);
2414         pSMB->ByteCount = cpu_to_le16(count);
2415
2416         if (waitFlag) {
2417                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2418                         (struct smb_hdr *) pSMB, &bytes_returned);
2419                 cifs_small_buf_release(pSMB);
2420         } else {
2421                 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
2422                                       timeout);
2423                 /* SMB buffer freed by function above */
2424         }
2425         cifs_stats_inc(&tcon->num_locks);
2426         if (rc)
2427                 cFYI(1, "Send error in Lock = %d", rc);
2428
2429         /* Note: On -EAGAIN error only caller can retry on handle based calls
2430         since file handle passed in no longer valid */
2431         return rc;
2432 }
2433
2434 int
2435 CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
2436                 const __u16 smb_file_id, const __u32 netpid, const int get_flag,
2437                 const __u64 len, struct file_lock *pLockData,
2438                 const __u16 lock_type, const bool waitFlag)
2439 {
2440         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2441         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2442         struct cifs_posix_lock *parm_data;
2443         int rc = 0;
2444         int timeout = 0;
2445         int bytes_returned = 0;
2446         int resp_buf_type = 0;
2447         __u16 params, param_offset, offset, byte_count, count;
2448         struct kvec iov[1];
2449
2450         cFYI(1, "Posix Lock");
2451
2452         if (pLockData == NULL)
2453                 return -EINVAL;
2454
2455         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2456
2457         if (rc)
2458                 return rc;
2459
2460         pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2461
2462         params = 6;
2463         pSMB->MaxSetupCount = 0;
2464         pSMB->Reserved = 0;
2465         pSMB->Flags = 0;
2466         pSMB->Reserved2 = 0;
2467         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2468         offset = param_offset + params;
2469
2470         count = sizeof(struct cifs_posix_lock);
2471         pSMB->MaxParameterCount = cpu_to_le16(2);
2472         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2473         pSMB->SetupCount = 1;
2474         pSMB->Reserved3 = 0;
2475         if (get_flag)
2476                 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2477         else
2478                 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2479         byte_count = 3 /* pad */  + params + count;
2480         pSMB->DataCount = cpu_to_le16(count);
2481         pSMB->ParameterCount = cpu_to_le16(params);
2482         pSMB->TotalDataCount = pSMB->DataCount;
2483         pSMB->TotalParameterCount = pSMB->ParameterCount;
2484         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2485         parm_data = (struct cifs_posix_lock *)
2486                         (((char *) &pSMB->hdr.Protocol) + offset);
2487
2488         parm_data->lock_type = cpu_to_le16(lock_type);
2489         if (waitFlag) {
2490                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2491                 parm_data->lock_flags = cpu_to_le16(1);
2492                 pSMB->Timeout = cpu_to_le32(-1);
2493         } else
2494                 pSMB->Timeout = 0;
2495
2496         parm_data->pid = cpu_to_le32(netpid);
2497         parm_data->start = cpu_to_le64(pLockData->fl_start);
2498         parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2499
2500         pSMB->DataOffset = cpu_to_le16(offset);
2501         pSMB->Fid = smb_file_id;
2502         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2503         pSMB->Reserved4 = 0;
2504         inc_rfc1001_len(pSMB, byte_count);
2505         pSMB->ByteCount = cpu_to_le16(byte_count);
2506         if (waitFlag) {
2507                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2508                         (struct smb_hdr *) pSMBr, &bytes_returned);
2509         } else {
2510                 iov[0].iov_base = (char *)pSMB;
2511                 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2512                 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2513                                 &resp_buf_type, timeout);
2514                 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2515                                 not try to free it twice below on exit */
2516                 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2517         }
2518
2519         if (rc) {
2520                 cFYI(1, "Send error in Posix Lock = %d", rc);
2521         } else if (get_flag) {
2522                 /* lock structure can be returned on get */
2523                 __u16 data_offset;
2524                 __u16 data_count;
2525                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2526
2527                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2528                         rc = -EIO;      /* bad smb */
2529                         goto plk_err_exit;
2530                 }
2531                 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2532                 data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2533                 if (data_count < sizeof(struct cifs_posix_lock)) {
2534                         rc = -EIO;
2535                         goto plk_err_exit;
2536                 }
2537                 parm_data = (struct cifs_posix_lock *)
2538                         ((char *)&pSMBr->hdr.Protocol + data_offset);
2539                 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2540                         pLockData->fl_type = F_UNLCK;
2541                 else {
2542                         if (parm_data->lock_type ==
2543                                         __constant_cpu_to_le16(CIFS_RDLCK))
2544                                 pLockData->fl_type = F_RDLCK;
2545                         else if (parm_data->lock_type ==
2546                                         __constant_cpu_to_le16(CIFS_WRLCK))
2547                                 pLockData->fl_type = F_WRLCK;
2548
2549                         pLockData->fl_start = le64_to_cpu(parm_data->start);
2550                         pLockData->fl_end = pLockData->fl_start +
2551                                         le64_to_cpu(parm_data->length) - 1;
2552                         pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2553                 }
2554         }
2555
2556 plk_err_exit:
2557         if (pSMB)
2558                 cifs_small_buf_release(pSMB);
2559
2560         if (resp_buf_type == CIFS_SMALL_BUFFER)
2561                 cifs_small_buf_release(iov[0].iov_base);
2562         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2563                 cifs_buf_release(iov[0].iov_base);
2564
2565         /* Note: On -EAGAIN error only caller can retry on handle based calls
2566            since file handle passed in no longer valid */
2567
2568         return rc;
2569 }
2570
2571
2572 int
2573 CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2574 {
2575         int rc = 0;
2576         CLOSE_REQ *pSMB = NULL;
2577         cFYI(1, "In CIFSSMBClose");
2578
2579 /* do not retry on dead session on close */
2580         rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2581         if (rc == -EAGAIN)
2582                 return 0;
2583         if (rc)
2584                 return rc;
2585
2586         pSMB->FileID = (__u16) smb_file_id;
2587         pSMB->LastWriteTime = 0xFFFFFFFF;
2588         pSMB->ByteCount = 0;
2589         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
2590         cifs_stats_inc(&tcon->num_closes);
2591         if (rc) {
2592                 if (rc != -EINTR) {
2593                         /* EINTR is expected when user ctl-c to kill app */
2594                         cERROR(1, "Send error in Close = %d", rc);
2595                 }
2596         }
2597
2598         /* Since session is dead, file will be closed on server already */
2599         if (rc == -EAGAIN)
2600                 rc = 0;
2601
2602         return rc;
2603 }
2604
2605 int
2606 CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2607 {
2608         int rc = 0;
2609         FLUSH_REQ *pSMB = NULL;
2610         cFYI(1, "In CIFSSMBFlush");
2611
2612         rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2613         if (rc)
2614                 return rc;
2615
2616         pSMB->FileID = (__u16) smb_file_id;
2617         pSMB->ByteCount = 0;
2618         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
2619         cifs_stats_inc(&tcon->num_flushes);
2620         if (rc)
2621                 cERROR(1, "Send error in Flush = %d", rc);
2622
2623         return rc;
2624 }
2625
2626 int
2627 CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
2628               const char *fromName, const char *toName,
2629               const struct nls_table *nls_codepage, int remap)
2630 {
2631         int rc = 0;
2632         RENAME_REQ *pSMB = NULL;
2633         RENAME_RSP *pSMBr = NULL;
2634         int bytes_returned;
2635         int name_len, name_len2;
2636         __u16 count;
2637
2638         cFYI(1, "In CIFSSMBRename");
2639 renameRetry:
2640         rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2641                       (void **) &pSMBr);
2642         if (rc)
2643                 return rc;
2644
2645         pSMB->BufferFormat = 0x04;
2646         pSMB->SearchAttributes =
2647             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2648                         ATTR_DIRECTORY);
2649
2650         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2651                 name_len =
2652                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
2653                                        PATH_MAX, nls_codepage, remap);
2654                 name_len++;     /* trailing null */
2655                 name_len *= 2;
2656                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2657         /* protocol requires ASCII signature byte on Unicode string */
2658                 pSMB->OldFileName[name_len + 1] = 0x00;
2659                 name_len2 =
2660                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2661                                        toName, PATH_MAX, nls_codepage, remap);
2662                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2663                 name_len2 *= 2; /* convert to bytes */
2664         } else {        /* BB improve the check for buffer overruns BB */
2665                 name_len = strnlen(fromName, PATH_MAX);
2666                 name_len++;     /* trailing null */
2667                 strncpy(pSMB->OldFileName, fromName, name_len);
2668                 name_len2 = strnlen(toName, PATH_MAX);
2669                 name_len2++;    /* trailing null */
2670                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2671                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2672                 name_len2++;    /* trailing null */
2673                 name_len2++;    /* signature byte */
2674         }
2675
2676         count = 1 /* 1st signature byte */  + name_len + name_len2;
2677         inc_rfc1001_len(pSMB, count);
2678         pSMB->ByteCount = cpu_to_le16(count);
2679
2680         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2681                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2682         cifs_stats_inc(&tcon->num_renames);
2683         if (rc)
2684                 cFYI(1, "Send error in rename = %d", rc);
2685
2686         cifs_buf_release(pSMB);
2687
2688         if (rc == -EAGAIN)
2689                 goto renameRetry;
2690
2691         return rc;
2692 }
2693
2694 int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
2695                 int netfid, const char *target_name,
2696                 const struct nls_table *nls_codepage, int remap)
2697 {
2698         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2699         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2700         struct set_file_rename *rename_info;
2701         char *data_offset;
2702         char dummy_string[30];
2703         int rc = 0;
2704         int bytes_returned = 0;
2705         int len_of_str;
2706         __u16 params, param_offset, offset, count, byte_count;
2707
2708         cFYI(1, "Rename to File by handle");
2709         rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2710                         (void **) &pSMBr);
2711         if (rc)
2712                 return rc;
2713
2714         params = 6;
2715         pSMB->MaxSetupCount = 0;
2716         pSMB->Reserved = 0;
2717         pSMB->Flags = 0;
2718         pSMB->Timeout = 0;
2719         pSMB->Reserved2 = 0;
2720         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2721         offset = param_offset + params;
2722
2723         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2724         rename_info = (struct set_file_rename *) data_offset;
2725         pSMB->MaxParameterCount = cpu_to_le16(2);
2726         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2727         pSMB->SetupCount = 1;
2728         pSMB->Reserved3 = 0;
2729         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2730         byte_count = 3 /* pad */  + params;
2731         pSMB->ParameterCount = cpu_to_le16(params);
2732         pSMB->TotalParameterCount = pSMB->ParameterCount;
2733         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2734         pSMB->DataOffset = cpu_to_le16(offset);
2735         /* construct random name ".cifs_tmp<inodenum><mid>" */
2736         rename_info->overwrite = cpu_to_le32(1);
2737         rename_info->root_fid  = 0;
2738         /* unicode only call */
2739         if (target_name == NULL) {
2740                 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2741                 len_of_str =
2742                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2743                                         dummy_string, 24, nls_codepage, remap);
2744         } else {
2745                 len_of_str =
2746                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2747                                         target_name, PATH_MAX, nls_codepage,
2748                                         remap);
2749         }
2750         rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2751         count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2752         byte_count += count;
2753         pSMB->DataCount = cpu_to_le16(count);
2754         pSMB->TotalDataCount = pSMB->DataCount;
2755         pSMB->Fid = netfid;
2756         pSMB->InformationLevel =
2757                 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2758         pSMB->Reserved4 = 0;
2759         inc_rfc1001_len(pSMB, byte_count);
2760         pSMB->ByteCount = cpu_to_le16(byte_count);
2761         rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2762                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2763         cifs_stats_inc(&pTcon->num_t2renames);
2764         if (rc)
2765                 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2766
2767         cifs_buf_release(pSMB);
2768
2769         /* Note: On -EAGAIN error only caller can retry on handle based calls
2770                 since file handle passed in no longer valid */
2771
2772         return rc;
2773 }
2774
2775 int
2776 CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
2777             const __u16 target_tid, const char *toName, const int flags,
2778             const struct nls_table *nls_codepage, int remap)
2779 {
2780         int rc = 0;
2781         COPY_REQ *pSMB = NULL;
2782         COPY_RSP *pSMBr = NULL;
2783         int bytes_returned;
2784         int name_len, name_len2;
2785         __u16 count;
2786
2787         cFYI(1, "In CIFSSMBCopy");
2788 copyRetry:
2789         rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2790                         (void **) &pSMBr);
2791         if (rc)
2792                 return rc;
2793
2794         pSMB->BufferFormat = 0x04;
2795         pSMB->Tid2 = target_tid;
2796
2797         pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2798
2799         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2800                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2801                                               fromName, PATH_MAX, nls_codepage,
2802                                               remap);
2803                 name_len++;     /* trailing null */
2804                 name_len *= 2;
2805                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2806                 /* protocol requires ASCII signature byte on Unicode string */
2807                 pSMB->OldFileName[name_len + 1] = 0x00;
2808                 name_len2 =
2809                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2810                                        toName, PATH_MAX, nls_codepage, remap);
2811                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2812                 name_len2 *= 2; /* convert to bytes */
2813         } else {        /* BB improve the check for buffer overruns BB */
2814                 name_len = strnlen(fromName, PATH_MAX);
2815                 name_len++;     /* trailing null */
2816                 strncpy(pSMB->OldFileName, fromName, name_len);
2817                 name_len2 = strnlen(toName, PATH_MAX);
2818                 name_len2++;    /* trailing null */
2819                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2820                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2821                 name_len2++;    /* trailing null */
2822                 name_len2++;    /* signature byte */
2823         }
2824
2825         count = 1 /* 1st signature byte */  + name_len + name_len2;
2826         inc_rfc1001_len(pSMB, count);
2827         pSMB->ByteCount = cpu_to_le16(count);
2828
2829         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2830                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2831         if (rc) {
2832                 cFYI(1, "Send error in copy = %d with %d files copied",
2833                         rc, le16_to_cpu(pSMBr->CopyCount));
2834         }
2835         cifs_buf_release(pSMB);
2836
2837         if (rc == -EAGAIN)
2838                 goto copyRetry;
2839
2840         return rc;
2841 }
2842
2843 int
2844 CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
2845                       const char *fromName, const char *toName,
2846                       const struct nls_table *nls_codepage)
2847 {
2848         TRANSACTION2_SPI_REQ *pSMB = NULL;
2849         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2850         char *data_offset;
2851         int name_len;
2852         int name_len_target;
2853         int rc = 0;
2854         int bytes_returned = 0;
2855         __u16 params, param_offset, offset, byte_count;
2856
2857         cFYI(1, "In Symlink Unix style");
2858 createSymLinkRetry:
2859         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2860                       (void **) &pSMBr);
2861         if (rc)
2862                 return rc;
2863
2864         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2865                 name_len =
2866                     cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2867                                     /* find define for this maxpathcomponent */
2868                                     PATH_MAX, nls_codepage);
2869                 name_len++;     /* trailing null */
2870                 name_len *= 2;
2871
2872         } else {        /* BB improve the check for buffer overruns BB */
2873                 name_len = strnlen(fromName, PATH_MAX);
2874                 name_len++;     /* trailing null */
2875                 strncpy(pSMB->FileName, fromName, name_len);
2876         }
2877         params = 6 + name_len;
2878         pSMB->MaxSetupCount = 0;
2879         pSMB->Reserved = 0;
2880         pSMB->Flags = 0;
2881         pSMB->Timeout = 0;
2882         pSMB->Reserved2 = 0;
2883         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2884                                 InformationLevel) - 4;
2885         offset = param_offset + params;
2886
2887         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2888         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2889                 name_len_target =
2890                     cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2891                                     /* find define for this maxpathcomponent */
2892                                     , nls_codepage);
2893                 name_len_target++;      /* trailing null */
2894                 name_len_target *= 2;
2895         } else {        /* BB improve the check for buffer overruns BB */
2896                 name_len_target = strnlen(toName, PATH_MAX);
2897                 name_len_target++;      /* trailing null */
2898                 strncpy(data_offset, toName, name_len_target);
2899         }
2900
2901         pSMB->MaxParameterCount = cpu_to_le16(2);
2902         /* BB find exact max on data count below from sess */
2903         pSMB->MaxDataCount = cpu_to_le16(1000);
2904         pSMB->SetupCount = 1;
2905         pSMB->Reserved3 = 0;
2906         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2907         byte_count = 3 /* pad */  + params + name_len_target;
2908         pSMB->DataCount = cpu_to_le16(name_len_target);
2909         pSMB->ParameterCount = cpu_to_le16(params);
2910         pSMB->TotalDataCount = pSMB->DataCount;
2911         pSMB->TotalParameterCount = pSMB->ParameterCount;
2912         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2913         pSMB->DataOffset = cpu_to_le16(offset);
2914         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2915         pSMB->Reserved4 = 0;
2916         inc_rfc1001_len(pSMB, byte_count);
2917         pSMB->ByteCount = cpu_to_le16(byte_count);
2918         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2919                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2920         cifs_stats_inc(&tcon->num_symlinks);
2921         if (rc)
2922                 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2923
2924         cifs_buf_release(pSMB);
2925
2926         if (rc == -EAGAIN)
2927                 goto createSymLinkRetry;
2928
2929         return rc;
2930 }
2931
2932 int
2933 CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
2934                        const char *fromName, const char *toName,
2935                        const struct nls_table *nls_codepage, int remap)
2936 {
2937         TRANSACTION2_SPI_REQ *pSMB = NULL;
2938         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2939         char *data_offset;
2940         int name_len;
2941         int name_len_target;
2942         int rc = 0;
2943         int bytes_returned = 0;
2944         __u16 params, param_offset, offset, byte_count;
2945
2946         cFYI(1, "In Create Hard link Unix style");
2947 createHardLinkRetry:
2948         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2949                       (void **) &pSMBr);
2950         if (rc)
2951                 return rc;
2952
2953         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2954                 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2955                                               PATH_MAX, nls_codepage, remap);
2956                 name_len++;     /* trailing null */
2957                 name_len *= 2;
2958
2959         } else {        /* BB improve the check for buffer overruns BB */
2960                 name_len = strnlen(toName, PATH_MAX);
2961                 name_len++;     /* trailing null */
2962                 strncpy(pSMB->FileName, toName, name_len);
2963         }
2964         params = 6 + name_len;
2965         pSMB->MaxSetupCount = 0;
2966         pSMB->Reserved = 0;
2967         pSMB->Flags = 0;
2968         pSMB->Timeout = 0;
2969         pSMB->Reserved2 = 0;
2970         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2971                                 InformationLevel) - 4;
2972         offset = param_offset + params;
2973
2974         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2975         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2976                 name_len_target =
2977                     cifsConvertToUTF16((__le16 *) data_offset, fromName,
2978                                        PATH_MAX, nls_codepage, remap);
2979                 name_len_target++;      /* trailing null */
2980                 name_len_target *= 2;
2981         } else {        /* BB improve the check for buffer overruns BB */
2982                 name_len_target = strnlen(fromName, PATH_MAX);
2983                 name_len_target++;      /* trailing null */
2984                 strncpy(data_offset, fromName, name_len_target);
2985         }
2986
2987         pSMB->MaxParameterCount = cpu_to_le16(2);
2988         /* BB find exact max on data count below from sess*/
2989         pSMB->MaxDataCount = cpu_to_le16(1000);
2990         pSMB->SetupCount = 1;
2991         pSMB->Reserved3 = 0;
2992         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2993         byte_count = 3 /* pad */  + params + name_len_target;
2994         pSMB->ParameterCount = cpu_to_le16(params);
2995         pSMB->TotalParameterCount = pSMB->ParameterCount;
2996         pSMB->DataCount = cpu_to_le16(name_len_target);
2997         pSMB->TotalDataCount = pSMB->DataCount;
2998         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2999         pSMB->DataOffset = cpu_to_le16(offset);
3000         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
3001         pSMB->Reserved4 = 0;
3002         inc_rfc1001_len(pSMB, byte_count);
3003         pSMB->ByteCount = cpu_to_le16(byte_count);
3004         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3005                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3006         cifs_stats_inc(&tcon->num_hardlinks);
3007         if (rc)
3008                 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
3009
3010         cifs_buf_release(pSMB);
3011         if (rc == -EAGAIN)
3012                 goto createHardLinkRetry;
3013
3014         return rc;
3015 }
3016
3017 int
3018 CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
3019                    const char *fromName, const char *toName,
3020                    const struct nls_table *nls_codepage, int remap)
3021 {
3022         int rc = 0;
3023         NT_RENAME_REQ *pSMB = NULL;
3024         RENAME_RSP *pSMBr = NULL;
3025         int bytes_returned;
3026         int name_len, name_len2;
3027         __u16 count;
3028
3029         cFYI(1, "In CIFSCreateHardLink");
3030 winCreateHardLinkRetry:
3031
3032         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3033                       (void **) &pSMBr);
3034         if (rc)
3035                 return rc;
3036
3037         pSMB->SearchAttributes =
3038             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3039                         ATTR_DIRECTORY);
3040         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3041         pSMB->ClusterCount = 0;
3042
3043         pSMB->BufferFormat = 0x04;
3044
3045         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3046                 name_len =
3047                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
3048                                        PATH_MAX, nls_codepage, remap);
3049                 name_len++;     /* trailing null */
3050                 name_len *= 2;
3051
3052                 /* protocol specifies ASCII buffer format (0x04) for unicode */
3053                 pSMB->OldFileName[name_len] = 0x04;
3054                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3055                 name_len2 =
3056                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3057                                        toName, PATH_MAX, nls_codepage, remap);
3058                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
3059                 name_len2 *= 2; /* convert to bytes */
3060         } else {        /* BB improve the check for buffer overruns BB */
3061                 name_len = strnlen(fromName, PATH_MAX);
3062                 name_len++;     /* trailing null */
3063                 strncpy(pSMB->OldFileName, fromName, name_len);
3064                 name_len2 = strnlen(toName, PATH_MAX);
3065                 name_len2++;    /* trailing null */
3066                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
3067                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
3068                 name_len2++;    /* trailing null */
3069                 name_len2++;    /* signature byte */
3070         }
3071
3072         count = 1 /* string type byte */  + name_len + name_len2;
3073         inc_rfc1001_len(pSMB, count);
3074         pSMB->ByteCount = cpu_to_le16(count);
3075
3076         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3077                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3078         cifs_stats_inc(&tcon->num_hardlinks);
3079         if (rc)
3080                 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
3081
3082         cifs_buf_release(pSMB);
3083         if (rc == -EAGAIN)
3084                 goto winCreateHardLinkRetry;
3085
3086         return rc;
3087 }
3088
3089 int
3090 CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
3091                         const unsigned char *searchName, char **symlinkinfo,
3092                         const struct nls_table *nls_codepage)
3093 {
3094 /* SMB_QUERY_FILE_UNIX_LINK */
3095         TRANSACTION2_QPI_REQ *pSMB = NULL;
3096         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3097         int rc = 0;
3098         int bytes_returned;
3099         int name_len;
3100         __u16 params, byte_count;
3101         char *data_start;
3102
3103         cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
3104
3105 querySymLinkRetry:
3106         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3107                       (void **) &pSMBr);
3108         if (rc)
3109                 return rc;
3110
3111         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3112                 name_len =
3113                         cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3114                                         PATH_MAX, nls_codepage);
3115                 name_len++;     /* trailing null */
3116                 name_len *= 2;
3117         } else {        /* BB improve the check for buffer overruns BB */
3118                 name_len = strnlen(searchName, PATH_MAX);
3119                 name_len++;     /* trailing null */
3120                 strncpy(pSMB->FileName, searchName, name_len);
3121         }
3122
3123         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3124         pSMB->TotalDataCount = 0;
3125         pSMB->MaxParameterCount = cpu_to_le16(2);
3126         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3127         pSMB->MaxSetupCount = 0;
3128         pSMB->Reserved = 0;
3129         pSMB->Flags = 0;
3130         pSMB->Timeout = 0;
3131         pSMB->Reserved2 = 0;
3132         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3133         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3134         pSMB->DataCount = 0;
3135         pSMB->DataOffset = 0;
3136         pSMB->SetupCount = 1;
3137         pSMB->Reserved3 = 0;
3138         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3139         byte_count = params + 1 /* pad */ ;
3140         pSMB->TotalParameterCount = cpu_to_le16(params);
3141         pSMB->ParameterCount = pSMB->TotalParameterCount;
3142         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3143         pSMB->Reserved4 = 0;
3144         inc_rfc1001_len(pSMB, byte_count);
3145         pSMB->ByteCount = cpu_to_le16(byte_count);
3146
3147         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3148                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3149         if (rc) {
3150                 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3151         } else {
3152                 /* decode response */
3153
3154                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3155                 /* BB also check enough total bytes returned */
3156                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3157                         rc = -EIO;
3158                 else {
3159                         bool is_unicode;
3160                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3161
3162                         data_start = ((char *) &pSMBr->hdr.Protocol) +
3163                                            le16_to_cpu(pSMBr->t2.DataOffset);
3164
3165                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3166                                 is_unicode = true;
3167                         else
3168                                 is_unicode = false;
3169
3170                         /* BB FIXME investigate remapping reserved chars here */
3171                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
3172                                         count, is_unicode, nls_codepage);
3173                         if (!*symlinkinfo)
3174                                 rc = -ENOMEM;
3175                 }
3176         }
3177         cifs_buf_release(pSMB);
3178         if (rc == -EAGAIN)
3179                 goto querySymLinkRetry;
3180         return rc;
3181 }
3182
3183 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3184 /*
3185  *      Recent Windows versions now create symlinks more frequently
3186  *      and they use the "reparse point" mechanism below.  We can of course
3187  *      do symlinks nicely to Samba and other servers which support the
3188  *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3189  *      "MF" symlinks optionally, but for recent Windows we really need to
3190  *      reenable the code below and fix the cifs_symlink callers to handle this.
3191  *      In the interim this code has been moved to its own config option so
3192  *      it is not compiled in by default until callers fixed up and more tested.
3193  */
3194 int
3195 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
3196                         const unsigned char *searchName,
3197                         char *symlinkinfo, const int buflen, __u16 fid,
3198                         const struct nls_table *nls_codepage)
3199 {
3200         int rc = 0;
3201         int bytes_returned;
3202         struct smb_com_transaction_ioctl_req *pSMB;
3203         struct smb_com_transaction_ioctl_rsp *pSMBr;
3204
3205         cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3206         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3207                       (void **) &pSMBr);
3208         if (rc)
3209                 return rc;
3210
3211         pSMB->TotalParameterCount = 0 ;
3212         pSMB->TotalDataCount = 0;
3213         pSMB->MaxParameterCount = cpu_to_le32(2);
3214         /* BB find exact data count max from sess structure BB */
3215         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3216         pSMB->MaxSetupCount = 4;
3217         pSMB->Reserved = 0;
3218         pSMB->ParameterOffset = 0;
3219         pSMB->DataCount = 0;
3220         pSMB->DataOffset = 0;
3221         pSMB->SetupCount = 4;
3222         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3223         pSMB->ParameterCount = pSMB->TotalParameterCount;
3224         pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3225         pSMB->IsFsctl = 1; /* FSCTL */
3226         pSMB->IsRootFlag = 0;
3227         pSMB->Fid = fid; /* file handle always le */
3228         pSMB->ByteCount = 0;
3229
3230         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3231                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3232         if (rc) {
3233                 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3234         } else {                /* decode response */
3235                 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3236                 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3237                 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3238                         /* BB also check enough total bytes returned */
3239                         rc = -EIO;      /* bad smb */
3240                         goto qreparse_out;
3241                 }
3242                 if (data_count && (data_count < 2048)) {
3243                         char *end_of_smb = 2 /* sizeof byte count */ +
3244                                get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3245
3246                         struct reparse_data *reparse_buf =
3247                                                 (struct reparse_data *)
3248                                                 ((char *)&pSMBr->hdr.Protocol
3249                                                                  + data_offset);
3250                         if ((char *)reparse_buf >= end_of_smb) {
3251                                 rc = -EIO;
3252                                 goto qreparse_out;
3253                         }
3254                         if ((reparse_buf->LinkNamesBuf +
3255                                 reparse_buf->TargetNameOffset +
3256                                 reparse_buf->TargetNameLen) > end_of_smb) {
3257                                 cFYI(1, "reparse buf beyond SMB");
3258                                 rc = -EIO;
3259                                 goto qreparse_out;
3260                         }
3261
3262                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3263                                 cifs_from_ucs2(symlinkinfo, (__le16 *)
3264                                                 (reparse_buf->LinkNamesBuf +
3265                                                 reparse_buf->TargetNameOffset),
3266                                                 buflen,
3267                                                 reparse_buf->TargetNameLen,
3268                                                 nls_codepage, 0);
3269                         } else { /* ASCII names */
3270                                 strncpy(symlinkinfo,
3271                                         reparse_buf->LinkNamesBuf +
3272                                         reparse_buf->TargetNameOffset,
3273                                         min_t(const int, buflen,
3274                                            reparse_buf->TargetNameLen));
3275                         }
3276                 } else {
3277                         rc = -EIO;
3278                         cFYI(1, "Invalid return data count on "
3279                                  "get reparse info ioctl");
3280                 }
3281                 symlinkinfo[buflen] = 0; /* just in case so the caller
3282                                         does not go off the end of the buffer */
3283                 cFYI(1, "readlink result - %s", symlinkinfo);
3284         }
3285
3286 qreparse_out:
3287         cifs_buf_release(pSMB);
3288
3289         /* Note: On -EAGAIN error only caller can retry on handle based calls
3290                 since file handle passed in no longer valid */
3291
3292         return rc;
3293 }
3294 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3295
3296 #ifdef CONFIG_CIFS_POSIX
3297
3298 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3299 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3300                              struct cifs_posix_ace *cifs_ace)
3301 {
3302         /* u8 cifs fields do not need le conversion */
3303         ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3304         ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3305         ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3306         /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3307
3308         return;
3309 }
3310
3311 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3312 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3313                                const int acl_type, const int size_of_data_area)
3314 {
3315         int size =  0;
3316         int i;
3317         __u16 count;
3318         struct cifs_posix_ace *pACE;
3319         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3320         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3321
3322         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3323                 return -EOPNOTSUPP;
3324
3325         if (acl_type & ACL_TYPE_ACCESS) {
3326                 count = le16_to_cpu(cifs_acl->access_entry_count);
3327                 pACE = &cifs_acl->ace_array[0];
3328                 size = sizeof(struct cifs_posix_acl);
3329                 size += sizeof(struct cifs_posix_ace) * count;
3330                 /* check if we would go beyond end of SMB */
3331                 if (size_of_data_area < size) {
3332                         cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3333                                 size_of_data_area, size);
3334                         return -EINVAL;
3335                 }
3336         } else if (acl_type & ACL_TYPE_DEFAULT) {
3337                 count = le16_to_cpu(cifs_acl->access_entry_count);
3338                 size = sizeof(struct cifs_posix_acl);
3339                 size += sizeof(struct cifs_posix_ace) * count;
3340 /* skip past access ACEs to get to default ACEs */
3341                 pACE = &cifs_acl->ace_array[count];
3342                 count = le16_to_cpu(cifs_acl->default_entry_count);
3343                 size += sizeof(struct cifs_posix_ace) * count;
3344                 /* check if we would go beyond end of SMB */
3345                 if (size_of_data_area < size)
3346                         return -EINVAL;
3347         } else {
3348                 /* illegal type */
3349                 return -EINVAL;
3350         }
3351
3352         size = posix_acl_xattr_size(count);
3353         if ((buflen == 0) || (local_acl == NULL)) {
3354                 /* used to query ACL EA size */
3355         } else if (size > buflen) {
3356                 return -ERANGE;
3357         } else /* buffer big enough */ {
3358                 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3359                 for (i = 0; i < count ; i++) {
3360                         cifs_convert_ace(&local_acl->a_entries[i], pACE);
3361                         pACE++;
3362                 }
3363         }
3364         return size;
3365 }
3366
3367 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3368                                      const posix_acl_xattr_entry *local_ace)
3369 {
3370         __u16 rc = 0; /* 0 = ACL converted ok */
3371
3372         cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3373         cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
3374         /* BB is there a better way to handle the large uid? */
3375         if (local_ace->e_id == cpu_to_le32(-1)) {
3376         /* Probably no need to le convert -1 on any arch but can not hurt */
3377                 cifs_ace->cifs_uid = cpu_to_le64(-1);
3378         } else
3379                 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3380         /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3381         return rc;
3382 }
3383
3384 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3385 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3386                                const int buflen, const int acl_type)
3387 {
3388         __u16 rc = 0;
3389         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3390         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3391         int count;
3392         int i;
3393
3394         if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3395                 return 0;
3396
3397         count = posix_acl_xattr_count((size_t)buflen);
3398         cFYI(1, "setting acl with %d entries from buf of length %d and "
3399                 "version of %d",
3400                 count, buflen, le32_to_cpu(local_acl->a_version));
3401         if (le32_to_cpu(local_acl->a_version) != 2) {
3402                 cFYI(1, "unknown POSIX ACL version %d",
3403                      le32_to_cpu(local_acl->a_version));
3404                 return 0;
3405         }
3406         cifs_acl->version = cpu_to_le16(1);
3407         if (acl_type == ACL_TYPE_ACCESS)
3408                 cifs_acl->access_entry_count = cpu_to_le16(count);
3409         else if (acl_type == ACL_TYPE_DEFAULT)
3410                 cifs_acl->default_entry_count = cpu_to_le16(count);
3411         else {
3412                 cFYI(1, "unknown ACL type %d", acl_type);
3413                 return 0;
3414         }
3415         for (i = 0; i < count; i++) {
3416                 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3417                                         &local_acl->a_entries[i]);
3418                 if (rc != 0) {
3419                         /* ACE not converted */
3420                         break;
3421                 }
3422         }
3423         if (rc == 0) {
3424                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3425                 rc += sizeof(struct cifs_posix_acl);
3426                 /* BB add check to make sure ACL does not overflow SMB */
3427         }
3428         return rc;
3429 }
3430
3431 int
3432 CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
3433                    const unsigned char *searchName,
3434                    char *acl_inf, const int buflen, const int acl_type,
3435                    const struct nls_table *nls_codepage, int remap)
3436 {
3437 /* SMB_QUERY_POSIX_ACL */
3438         TRANSACTION2_QPI_REQ *pSMB = NULL;
3439         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3440         int rc = 0;
3441         int bytes_returned;
3442         int name_len;
3443         __u16 params, byte_count;
3444
3445         cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3446
3447 queryAclRetry:
3448         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3449                 (void **) &pSMBr);
3450         if (rc)
3451                 return rc;
3452
3453         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3454                 name_len =
3455                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3456                                            searchName, PATH_MAX, nls_codepage,
3457                                            remap);
3458                 name_len++;     /* trailing null */
3459                 name_len *= 2;
3460                 pSMB->FileName[name_len] = 0;
3461                 pSMB->FileName[name_len+1] = 0;
3462         } else {        /* BB improve the check for buffer overruns BB */
3463                 name_len = strnlen(searchName, PATH_MAX);
3464                 name_len++;     /* trailing null */
3465                 strncpy(pSMB->FileName, searchName, name_len);
3466         }
3467
3468         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3469         pSMB->TotalDataCount = 0;
3470         pSMB->MaxParameterCount = cpu_to_le16(2);
3471         /* BB find exact max data count below from sess structure BB */
3472         pSMB->MaxDataCount = cpu_to_le16(4000);
3473         pSMB->MaxSetupCount = 0;
3474         pSMB->Reserved = 0;
3475         pSMB->Flags = 0;
3476         pSMB->Timeout = 0;
3477         pSMB->Reserved2 = 0;
3478         pSMB->ParameterOffset = cpu_to_le16(
3479                 offsetof(struct smb_com_transaction2_qpi_req,
3480                          InformationLevel) - 4);
3481         pSMB->DataCount = 0;
3482         pSMB->DataOffset = 0;
3483         pSMB->SetupCount = 1;
3484         pSMB->Reserved3 = 0;
3485         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3486         byte_count = params + 1 /* pad */ ;
3487         pSMB->TotalParameterCount = cpu_to_le16(params);
3488         pSMB->ParameterCount = pSMB->TotalParameterCount;
3489         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3490         pSMB->Reserved4 = 0;
3491         inc_rfc1001_len(pSMB, byte_count);
3492         pSMB->ByteCount = cpu_to_le16(byte_count);
3493
3494         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3495                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3496         cifs_stats_inc(&tcon->num_acl_get);
3497         if (rc) {
3498                 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3499         } else {
3500                 /* decode response */
3501
3502                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3503                 /* BB also check enough total bytes returned */
3504                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3505                         rc = -EIO;      /* bad smb */
3506                 else {
3507                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3508                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3509                         rc = cifs_copy_posix_acl(acl_inf,
3510                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3511                                 buflen, acl_type, count);
3512                 }
3513         }
3514         cifs_buf_release(pSMB);
3515         if (rc == -EAGAIN)
3516                 goto queryAclRetry;
3517         return rc;
3518 }
3519
3520 int
3521 CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
3522                    const unsigned char *fileName,
3523                    const char *local_acl, const int buflen,
3524                    const int acl_type,
3525                    const struct nls_table *nls_codepage, int remap)
3526 {
3527         struct smb_com_transaction2_spi_req *pSMB = NULL;
3528         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3529         char *parm_data;
3530         int name_len;
3531         int rc = 0;
3532         int bytes_returned = 0;
3533         __u16 params, byte_count, data_count, param_offset, offset;
3534
3535         cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3536 setAclRetry:
3537         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3538                       (void **) &pSMBr);
3539         if (rc)
3540                 return rc;
3541         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3542                 name_len =
3543                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3544                                            PATH_MAX, nls_codepage, remap);
3545                 name_len++;     /* trailing null */
3546                 name_len *= 2;
3547         } else {        /* BB improve the check for buffer overruns BB */
3548                 name_len = strnlen(fileName, PATH_MAX);
3549                 name_len++;     /* trailing null */
3550                 strncpy(pSMB->FileName, fileName, name_len);
3551         }
3552         params = 6 + name_len;
3553         pSMB->MaxParameterCount = cpu_to_le16(2);
3554         /* BB find max SMB size from sess */
3555         pSMB->MaxDataCount = cpu_to_le16(1000);
3556         pSMB->MaxSetupCount = 0;
3557         pSMB->Reserved = 0;
3558         pSMB->Flags = 0;
3559         pSMB->Timeout = 0;
3560         pSMB->Reserved2 = 0;
3561         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3562                                 InformationLevel) - 4;
3563         offset = param_offset + params;
3564         parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3565         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3566
3567         /* convert to on the wire format for POSIX ACL */
3568         data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3569
3570         if (data_count == 0) {
3571                 rc = -EOPNOTSUPP;
3572                 goto setACLerrorExit;
3573         }
3574         pSMB->DataOffset = cpu_to_le16(offset);
3575         pSMB->SetupCount = 1;
3576         pSMB->Reserved3 = 0;
3577         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3578         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3579         byte_count = 3 /* pad */  + params + data_count;
3580         pSMB->DataCount = cpu_to_le16(data_count);
3581         pSMB->TotalDataCount = pSMB->DataCount;
3582         pSMB->ParameterCount = cpu_to_le16(params);
3583         pSMB->TotalParameterCount = pSMB->ParameterCount;
3584         pSMB->Reserved4 = 0;
3585         inc_rfc1001_len(pSMB, byte_count);
3586         pSMB->ByteCount = cpu_to_le16(byte_count);
3587         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3588                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3589         if (rc)
3590                 cFYI(1, "Set POSIX ACL returned %d", rc);
3591
3592 setACLerrorExit:
3593         cifs_buf_release(pSMB);
3594         if (rc == -EAGAIN)
3595                 goto setAclRetry;
3596         return rc;
3597 }
3598
3599 /* BB fix tabs in this function FIXME BB */
3600 int
3601 CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
3602                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3603 {
3604         int rc = 0;
3605         struct smb_t2_qfi_req *pSMB = NULL;
3606         struct smb_t2_qfi_rsp *pSMBr = NULL;
3607         int bytes_returned;
3608         __u16 params, byte_count;
3609
3610         cFYI(1, "In GetExtAttr");
3611         if (tcon == NULL)
3612                 return -ENODEV;
3613
3614 GetExtAttrRetry:
3615         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3616                         (void **) &pSMBr);
3617         if (rc)
3618                 return rc;
3619
3620         params = 2 /* level */ + 2 /* fid */;
3621         pSMB->t2.TotalDataCount = 0;
3622         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3623         /* BB find exact max data count below from sess structure BB */
3624         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3625         pSMB->t2.MaxSetupCount = 0;
3626         pSMB->t2.Reserved = 0;
3627         pSMB->t2.Flags = 0;
3628         pSMB->t2.Timeout = 0;
3629         pSMB->t2.Reserved2 = 0;
3630         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3631                                                Fid) - 4);
3632         pSMB->t2.DataCount = 0;
3633         pSMB->t2.DataOffset = 0;
3634         pSMB->t2.SetupCount = 1;
3635         pSMB->t2.Reserved3 = 0;
3636         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3637         byte_count = params + 1 /* pad */ ;
3638         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3639         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3640         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3641         pSMB->Pad = 0;
3642         pSMB->Fid = netfid;
3643         inc_rfc1001_len(pSMB, byte_count);
3644         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3645
3646         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3647                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3648         if (rc) {
3649                 cFYI(1, "error %d in GetExtAttr", rc);
3650         } else {
3651                 /* decode response */
3652                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3653                 /* BB also check enough total bytes returned */
3654                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3655                         /* If rc should we check for EOPNOSUPP and
3656                            disable the srvino flag? or in caller? */
3657                         rc = -EIO;      /* bad smb */
3658                 else {
3659                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3660                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3661                         struct file_chattr_info *pfinfo;
3662                         /* BB Do we need a cast or hash here ? */
3663                         if (count != 16) {
3664                                 cFYI(1, "Illegal size ret in GetExtAttr");
3665                                 rc = -EIO;
3666                                 goto GetExtAttrOut;
3667                         }
3668                         pfinfo = (struct file_chattr_info *)
3669                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3670                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3671                         *pMask = le64_to_cpu(pfinfo->mask);
3672                 }
3673         }
3674 GetExtAttrOut:
3675         cifs_buf_release(pSMB);
3676         if (rc == -EAGAIN)
3677                 goto GetExtAttrRetry;
3678         return rc;
3679 }
3680
3681 #endif /* CONFIG_POSIX */
3682
3683 #ifdef CONFIG_CIFS_ACL
3684 /*
3685  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3686  * all NT TRANSACTS that we init here have total parm and data under about 400
3687  * bytes (to fit in small cifs buffer size), which is the case so far, it
3688  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3689  * returned setup area) and MaxParameterCount (returned parms size) must be set
3690  * by caller
3691  */
3692 static int
3693 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3694                    const int parm_len, struct cifs_tcon *tcon,
3695                    void **ret_buf)
3696 {
3697         int rc;
3698         __u32 temp_offset;
3699         struct smb_com_ntransact_req *pSMB;
3700
3701         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3702                                 (void **)&pSMB);
3703         if (rc)
3704                 return rc;
3705         *ret_buf = (void *)pSMB;
3706         pSMB->Reserved = 0;
3707         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3708         pSMB->TotalDataCount  = 0;
3709         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3710         pSMB->ParameterCount = pSMB->TotalParameterCount;
3711         pSMB->DataCount  = pSMB->TotalDataCount;
3712         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3713                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3714         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3715         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3716         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3717         pSMB->SubCommand = cpu_to_le16(sub_command);
3718         return 0;
3719 }
3720
3721 static int
3722 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3723                    __u32 *pparmlen, __u32 *pdatalen)
3724 {
3725         char *end_of_smb;
3726         __u32 data_count, data_offset, parm_count, parm_offset;
3727         struct smb_com_ntransact_rsp *pSMBr;
3728         u16 bcc;
3729
3730         *pdatalen = 0;
3731         *pparmlen = 0;
3732
3733         if (buf == NULL)
3734                 return -EINVAL;
3735
3736         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3737
3738         bcc = get_bcc(&pSMBr->hdr);
3739         end_of_smb = 2 /* sizeof byte count */ + bcc +
3740                         (char *)&pSMBr->ByteCount;
3741
3742         data_offset = le32_to_cpu(pSMBr->DataOffset);
3743         data_count = le32_to_cpu(pSMBr->DataCount);
3744         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3745         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3746
3747         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3748         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3749
3750         /* should we also check that parm and data areas do not overlap? */
3751         if (*ppparm > end_of_smb) {
3752                 cFYI(1, "parms start after end of smb");
3753                 return -EINVAL;
3754         } else if (parm_count + *ppparm > end_of_smb) {
3755                 cFYI(1, "parm end after end of smb");
3756                 return -EINVAL;
3757         } else if (*ppdata > end_of_smb) {
3758                 cFYI(1, "data starts after end of smb");
3759                 return -EINVAL;
3760         } else if (data_count + *ppdata > end_of_smb) {
3761                 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3762                         *ppdata, data_count, (data_count + *ppdata),
3763                         end_of_smb, pSMBr);
3764                 return -EINVAL;
3765         } else if (parm_count + data_count > bcc) {
3766                 cFYI(1, "parm count and data count larger than SMB");
3767                 return -EINVAL;
3768         }
3769         *pdatalen = data_count;
3770         *pparmlen = parm_count;
3771         return 0;
3772 }
3773
3774 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3775 int
3776 CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3777                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3778 {
3779         int rc = 0;
3780         int buf_type = 0;
3781         QUERY_SEC_DESC_REQ *pSMB;
3782         struct kvec iov[1];
3783
3784         cFYI(1, "GetCifsACL");
3785
3786         *pbuflen = 0;
3787         *acl_inf = NULL;
3788
3789         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3790                         8 /* parm len */, tcon, (void **) &pSMB);
3791         if (rc)
3792                 return rc;
3793
3794         pSMB->MaxParameterCount = cpu_to_le32(4);
3795         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3796         pSMB->MaxSetupCount = 0;
3797         pSMB->Fid = fid; /* file handle always le */
3798         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3799                                      CIFS_ACL_DACL);
3800         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3801         inc_rfc1001_len(pSMB, 11);
3802         iov[0].iov_base = (char *)pSMB;
3803         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3804
3805         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3806                          0);
3807         cifs_stats_inc(&tcon->num_acl_get);
3808         if (rc) {
3809                 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3810         } else {                /* decode response */
3811                 __le32 *parm;
3812                 __u32 parm_len;
3813                 __u32 acl_len;
3814                 struct smb_com_ntransact_rsp *pSMBr;
3815                 char *pdata;
3816
3817 /* validate_nttransact */
3818                 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3819                                         &pdata, &parm_len, pbuflen);
3820                 if (rc)
3821                         goto qsec_out;
3822                 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3823
3824                 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3825
3826                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3827                         rc = -EIO;      /* bad smb */
3828                         *pbuflen = 0;
3829                         goto qsec_out;
3830                 }
3831
3832 /* BB check that data area is minimum length and as big as acl_len */
3833
3834                 acl_len = le32_to_cpu(*parm);
3835                 if (acl_len != *pbuflen) {
3836                         cERROR(1, "acl length %d does not match %d",
3837                                    acl_len, *pbuflen);
3838                         if (*pbuflen > acl_len)
3839                                 *pbuflen = acl_len;
3840                 }
3841
3842                 /* check if buffer is big enough for the acl
3843                    header followed by the smallest SID */
3844                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3845                     (*pbuflen >= 64 * 1024)) {
3846                         cERROR(1, "bad acl length %d", *pbuflen);
3847                         rc = -EINVAL;
3848                         *pbuflen = 0;
3849                 } else {
3850                         *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3851                         if (*acl_inf == NULL) {
3852                                 *pbuflen = 0;
3853                                 rc = -ENOMEM;
3854                         }
3855                         memcpy(*acl_inf, pdata, *pbuflen);
3856                 }
3857         }
3858 qsec_out:
3859         if (buf_type == CIFS_SMALL_BUFFER)
3860                 cifs_small_buf_release(iov[0].iov_base);
3861         else if (buf_type == CIFS_LARGE_BUFFER)
3862                 cifs_buf_release(iov[0].iov_base);
3863 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3864         return rc;
3865 }
3866
3867 int
3868 CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3869                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3870 {
3871         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3872         int rc = 0;
3873         int bytes_returned = 0;
3874         SET_SEC_DESC_REQ *pSMB = NULL;
3875         NTRANSACT_RSP *pSMBr = NULL;
3876
3877 setCifsAclRetry:
3878         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
3879                         (void **) &pSMBr);
3880         if (rc)
3881                         return (rc);
3882
3883         pSMB->MaxSetupCount = 0;
3884         pSMB->Reserved = 0;
3885
3886         param_count = 8;
3887         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3888         data_count = acllen;
3889         data_offset = param_offset + param_count;
3890         byte_count = 3 /* pad */  + param_count;
3891
3892         pSMB->DataCount = cpu_to_le32(data_count);
3893         pSMB->TotalDataCount = pSMB->DataCount;
3894         pSMB->MaxParameterCount = cpu_to_le32(4);
3895         pSMB->MaxDataCount = cpu_to_le32(16384);
3896         pSMB->ParameterCount = cpu_to_le32(param_count);
3897         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3898         pSMB->TotalParameterCount = pSMB->ParameterCount;
3899         pSMB->DataOffset = cpu_to_le32(data_offset);
3900         pSMB->SetupCount = 0;
3901         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3902         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3903
3904         pSMB->Fid = fid; /* file handle always le */
3905         pSMB->Reserved2 = 0;
3906         pSMB->AclFlags = cpu_to_le32(aclflag);
3907
3908         if (pntsd && acllen) {
3909                 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3910                         (char *) pntsd,
3911                         acllen);
3912                 inc_rfc1001_len(pSMB, byte_count + data_count);
3913         } else
3914                 inc_rfc1001_len(pSMB, byte_count);
3915
3916         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3917                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3918
3919         cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3920         if (rc)
3921                 cFYI(1, "Set CIFS ACL returned %d", rc);
3922         cifs_buf_release(pSMB);
3923
3924         if (rc == -EAGAIN)
3925                 goto setCifsAclRetry;
3926
3927         return (rc);
3928 }
3929
3930 #endif /* CONFIG_CIFS_ACL */
3931
3932 /* Legacy Query Path Information call for lookup to old servers such
3933    as Win9x/WinME */
3934 int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3935                         const unsigned char *searchName,
3936                         FILE_ALL_INFO *pFinfo,
3937                         const struct nls_table *nls_codepage, int remap)
3938 {
3939         QUERY_INFORMATION_REQ *pSMB;
3940         QUERY_INFORMATION_RSP *pSMBr;
3941         int rc = 0;
3942         int bytes_returned;
3943         int name_len;
3944
3945         cFYI(1, "In SMBQPath path %s", searchName);
3946 QInfRetry:
3947         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3948                       (void **) &pSMBr);
3949         if (rc)
3950                 return rc;
3951
3952         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3953                 name_len =
3954                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3955                                            searchName, PATH_MAX, nls_codepage,
3956                                            remap);
3957                 name_len++;     /* trailing null */
3958                 name_len *= 2;
3959         } else {
3960                 name_len = strnlen(searchName, PATH_MAX);
3961                 name_len++;     /* trailing null */
3962                 strncpy(pSMB->FileName, searchName, name_len);
3963         }
3964         pSMB->BufferFormat = 0x04;
3965         name_len++; /* account for buffer type byte */
3966         inc_rfc1001_len(pSMB, (__u16)name_len);
3967         pSMB->ByteCount = cpu_to_le16(name_len);
3968
3969         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3970                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3971         if (rc) {
3972                 cFYI(1, "Send error in QueryInfo = %d", rc);
3973         } else if (pFinfo) {
3974                 struct timespec ts;
3975                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3976
3977                 /* decode response */
3978                 /* BB FIXME - add time zone adjustment BB */
3979                 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
3980                 ts.tv_nsec = 0;
3981                 ts.tv_sec = time;
3982                 /* decode time fields */
3983                 pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3984                 pFinfo->LastWriteTime = pFinfo->ChangeTime;
3985                 pFinfo->LastAccessTime = 0;
3986                 pFinfo->AllocationSize =
3987                         cpu_to_le64(le32_to_cpu(pSMBr->size));
3988                 pFinfo->EndOfFile = pFinfo->AllocationSize;
3989                 pFinfo->Attributes =
3990                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
3991         } else
3992                 rc = -EIO; /* bad buffer passed in */
3993
3994         cifs_buf_release(pSMB);
3995
3996         if (rc == -EAGAIN)
3997                 goto QInfRetry;
3998
3999         return rc;
4000 }
4001
4002 int
4003 CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
4004                  u16 netfid, FILE_ALL_INFO *pFindData)
4005 {
4006         struct smb_t2_qfi_req *pSMB = NULL;
4007         struct smb_t2_qfi_rsp *pSMBr = NULL;
4008         int rc = 0;
4009         int bytes_returned;
4010         __u16 params, byte_count;
4011
4012 QFileInfoRetry:
4013         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4014                       (void **) &pSMBr);
4015         if (rc)
4016                 return rc;
4017
4018         params = 2 /* level */ + 2 /* fid */;
4019         pSMB->t2.TotalDataCount = 0;
4020         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4021         /* BB find exact max data count below from sess structure BB */
4022         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4023         pSMB->t2.MaxSetupCount = 0;
4024         pSMB->t2.Reserved = 0;
4025         pSMB->t2.Flags = 0;
4026         pSMB->t2.Timeout = 0;
4027         pSMB->t2.Reserved2 = 0;
4028         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4029                                                Fid) - 4);
4030         pSMB->t2.DataCount = 0;
4031         pSMB->t2.DataOffset = 0;
4032         pSMB->t2.SetupCount = 1;
4033         pSMB->t2.Reserved3 = 0;
4034         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4035         byte_count = params + 1 /* pad */ ;
4036         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4037         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4038         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4039         pSMB->Pad = 0;
4040         pSMB->Fid = netfid;
4041         inc_rfc1001_len(pSMB, byte_count);
4042
4043         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4044                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4045         if (rc) {
4046                 cFYI(1, "Send error in QPathInfo = %d", rc);
4047         } else {                /* decode response */
4048                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4049
4050                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4051                         rc = -EIO;
4052                 else if (get_bcc(&pSMBr->hdr) < 40)
4053                         rc = -EIO;      /* bad smb */
4054                 else if (pFindData) {
4055                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4056                         memcpy((char *) pFindData,
4057                                (char *) &pSMBr->hdr.Protocol +
4058                                data_offset, sizeof(FILE_ALL_INFO));
4059                 } else
4060                     rc = -ENOMEM;
4061         }
4062         cifs_buf_release(pSMB);
4063         if (rc == -EAGAIN)
4064                 goto QFileInfoRetry;
4065
4066         return rc;
4067 }
4068
4069 int
4070 CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
4071                  const unsigned char *searchName,
4072                  FILE_ALL_INFO *pFindData,
4073                  int legacy /* old style infolevel */,
4074                  const struct nls_table *nls_codepage, int remap)
4075 {
4076 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4077         TRANSACTION2_QPI_REQ *pSMB = NULL;
4078         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4079         int rc = 0;
4080         int bytes_returned;
4081         int name_len;
4082         __u16 params, byte_count;
4083
4084 /* cFYI(1, "In QPathInfo path %s", searchName); */
4085 QPathInfoRetry:
4086         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4087                       (void **) &pSMBr);
4088         if (rc)
4089                 return rc;
4090
4091         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4092                 name_len =
4093                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4094                                        PATH_MAX, nls_codepage, remap);
4095                 name_len++;     /* trailing null */
4096                 name_len *= 2;
4097         } else {        /* BB improve the check for buffer overruns BB */
4098                 name_len = strnlen(searchName, PATH_MAX);
4099                 name_len++;     /* trailing null */
4100                 strncpy(pSMB->FileName, searchName, name_len);
4101         }
4102
4103         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4104         pSMB->TotalDataCount = 0;
4105         pSMB->MaxParameterCount = cpu_to_le16(2);
4106         /* BB find exact max SMB PDU from sess structure BB */
4107         pSMB->MaxDataCount = cpu_to_le16(4000);
4108         pSMB->MaxSetupCount = 0;
4109         pSMB->Reserved = 0;
4110         pSMB->Flags = 0;
4111         pSMB->Timeout = 0;
4112         pSMB->Reserved2 = 0;
4113         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4114         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4115         pSMB->DataCount = 0;
4116         pSMB->DataOffset = 0;
4117         pSMB->SetupCount = 1;
4118         pSMB->Reserved3 = 0;
4119         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4120         byte_count = params + 1 /* pad */ ;
4121         pSMB->TotalParameterCount = cpu_to_le16(params);
4122         pSMB->ParameterCount = pSMB->TotalParameterCount;
4123         if (legacy)
4124                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4125         else
4126                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4127         pSMB->Reserved4 = 0;
4128         inc_rfc1001_len(pSMB, byte_count);
4129         pSMB->ByteCount = cpu_to_le16(byte_count);
4130
4131         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4132                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4133         if (rc) {
4134                 cFYI(1, "Send error in QPathInfo = %d", rc);
4135         } else {                /* decode response */
4136                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4137
4138                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4139                         rc = -EIO;
4140                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4141                         rc = -EIO;      /* bad smb */
4142                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4143                         rc = -EIO;  /* 24 or 26 expected but we do not read
4144                                         last field */
4145                 else if (pFindData) {
4146                         int size;
4147                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4148
4149                         /* On legacy responses we do not read the last field,
4150                         EAsize, fortunately since it varies by subdialect and
4151                         also note it differs on Set vs. Get, ie two bytes or 4
4152                         bytes depending but we don't care here */
4153                         if (legacy)
4154                                 size = sizeof(FILE_INFO_STANDARD);
4155                         else
4156                                 size = sizeof(FILE_ALL_INFO);
4157                         memcpy((char *) pFindData,
4158                                (char *) &pSMBr->hdr.Protocol +
4159                                data_offset, size);
4160                 } else
4161                     rc = -ENOMEM;
4162         }
4163         cifs_buf_release(pSMB);
4164         if (rc == -EAGAIN)
4165                 goto QPathInfoRetry;
4166
4167         return rc;
4168 }
4169
4170 int
4171 CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
4172                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4173 {
4174         struct smb_t2_qfi_req *pSMB = NULL;
4175         struct smb_t2_qfi_rsp *pSMBr = NULL;
4176         int rc = 0;
4177         int bytes_returned;
4178         __u16 params, byte_count;
4179
4180 UnixQFileInfoRetry:
4181         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4182                       (void **) &pSMBr);
4183         if (rc)
4184                 return rc;
4185
4186         params = 2 /* level */ + 2 /* fid */;
4187         pSMB->t2.TotalDataCount = 0;
4188         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4189         /* BB find exact max data count below from sess structure BB */
4190         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4191         pSMB->t2.MaxSetupCount = 0;
4192         pSMB->t2.Reserved = 0;
4193         pSMB->t2.Flags = 0;
4194         pSMB->t2.Timeout = 0;
4195         pSMB->t2.Reserved2 = 0;
4196         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4197                                                Fid) - 4);
4198         pSMB->t2.DataCount = 0;
4199         pSMB->t2.DataOffset = 0;
4200         pSMB->t2.SetupCount = 1;
4201         pSMB->t2.Reserved3 = 0;
4202         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4203         byte_count = params + 1 /* pad */ ;
4204         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4205         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4206         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4207         pSMB->Pad = 0;
4208         pSMB->Fid = netfid;
4209         inc_rfc1001_len(pSMB, byte_count);
4210
4211         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4212                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4213         if (rc) {
4214                 cFYI(1, "Send error in QPathInfo = %d", rc);
4215         } else {                /* decode response */
4216                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4217
4218                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4219                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4220                                    "Unix Extensions can be disabled on mount "
4221                                    "by specifying the nosfu mount option.");
4222                         rc = -EIO;      /* bad smb */
4223                 } else {
4224                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4225                         memcpy((char *) pFindData,
4226                                (char *) &pSMBr->hdr.Protocol +
4227                                data_offset,
4228                                sizeof(FILE_UNIX_BASIC_INFO));
4229                 }
4230         }
4231
4232         cifs_buf_release(pSMB);
4233         if (rc == -EAGAIN)
4234                 goto UnixQFileInfoRetry;
4235
4236         return rc;
4237 }
4238
4239 int
4240 CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
4241                      const unsigned char *searchName,
4242                      FILE_UNIX_BASIC_INFO *pFindData,
4243                      const struct nls_table *nls_codepage, int remap)
4244 {
4245 /* SMB_QUERY_FILE_UNIX_BASIC */
4246         TRANSACTION2_QPI_REQ *pSMB = NULL;
4247         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4248         int rc = 0;
4249         int bytes_returned = 0;
4250         int name_len;
4251         __u16 params, byte_count;
4252
4253         cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4254 UnixQPathInfoRetry:
4255         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4256                       (void **) &pSMBr);
4257         if (rc)
4258                 return rc;
4259
4260         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4261                 name_len =
4262                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4263                                        PATH_MAX, nls_codepage, remap);
4264                 name_len++;     /* trailing null */
4265                 name_len *= 2;
4266         } else {        /* BB improve the check for buffer overruns BB */
4267                 name_len = strnlen(searchName, PATH_MAX);
4268                 name_len++;     /* trailing null */
4269                 strncpy(pSMB->FileName, searchName, name_len);
4270         }
4271
4272         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4273         pSMB->TotalDataCount = 0;
4274         pSMB->MaxParameterCount = cpu_to_le16(2);
4275         /* BB find exact max SMB PDU from sess structure BB */
4276         pSMB->MaxDataCount = cpu_to_le16(4000);
4277         pSMB->MaxSetupCount = 0;
4278         pSMB->Reserved = 0;
4279         pSMB->Flags = 0;
4280         pSMB->Timeout = 0;
4281         pSMB->Reserved2 = 0;
4282         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4283         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4284         pSMB->DataCount = 0;
4285         pSMB->DataOffset = 0;
4286         pSMB->SetupCount = 1;
4287         pSMB->Reserved3 = 0;
4288         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4289         byte_count = params + 1 /* pad */ ;
4290         pSMB->TotalParameterCount = cpu_to_le16(params);
4291         pSMB->ParameterCount = pSMB->TotalParameterCount;
4292         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4293         pSMB->Reserved4 = 0;
4294         inc_rfc1001_len(pSMB, byte_count);
4295         pSMB->ByteCount = cpu_to_le16(byte_count);
4296
4297         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4298                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4299         if (rc) {
4300                 cFYI(1, "Send error in QPathInfo = %d", rc);
4301         } else {                /* decode response */
4302                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4303
4304                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4305                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4306                                    "Unix Extensions can be disabled on mount "
4307                                    "by specifying the nosfu mount option.");
4308                         rc = -EIO;      /* bad smb */
4309                 } else {
4310                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4311                         memcpy((char *) pFindData,
4312                                (char *) &pSMBr->hdr.Protocol +
4313                                data_offset,
4314                                sizeof(FILE_UNIX_BASIC_INFO));
4315                 }
4316         }
4317         cifs_buf_release(pSMB);
4318         if (rc == -EAGAIN)
4319                 goto UnixQPathInfoRetry;
4320
4321         return rc;
4322 }
4323
4324 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4325 int
4326 CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
4327               const char *searchName,
4328               const struct nls_table *nls_codepage,
4329               __u16 *pnetfid,
4330               struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4331 {
4332 /* level 257 SMB_ */
4333         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4334         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4335         T2_FFIRST_RSP_PARMS *parms;
4336         int rc = 0;
4337         int bytes_returned = 0;
4338         int name_len;
4339         __u16 params, byte_count;
4340
4341         cFYI(1, "In FindFirst for %s", searchName);
4342
4343 findFirstRetry:
4344         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4345                       (void **) &pSMBr);
4346         if (rc)
4347                 return rc;
4348
4349         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4350                 name_len =
4351                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4352                                        PATH_MAX, nls_codepage, remap);
4353                 /* We can not add the asterik earlier in case
4354                 it got remapped to 0xF03A as if it were part of the
4355                 directory name instead of a wildcard */
4356                 name_len *= 2;
4357                 pSMB->FileName[name_len] = dirsep;
4358                 pSMB->FileName[name_len+1] = 0;
4359                 pSMB->FileName[name_len+2] = '*';
4360                 pSMB->FileName[name_len+3] = 0;
4361                 name_len += 4; /* now the trailing null */
4362                 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4363                 pSMB->FileName[name_len+1] = 0;
4364                 name_len += 2;
4365         } else {        /* BB add check for overrun of SMB buf BB */
4366                 name_len = strnlen(searchName, PATH_MAX);
4367 /* BB fix here and in unicode clause above ie
4368                 if (name_len > buffersize-header)
4369                         free buffer exit; BB */
4370                 strncpy(pSMB->FileName, searchName, name_len);
4371                 pSMB->FileName[name_len] = dirsep;
4372                 pSMB->FileName[name_len+1] = '*';
4373                 pSMB->FileName[name_len+2] = 0;
4374                 name_len += 3;
4375         }
4376
4377         params = 12 + name_len /* includes null */ ;
4378         pSMB->TotalDataCount = 0;       /* no EAs */
4379         pSMB->MaxParameterCount = cpu_to_le16(10);
4380         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4381         pSMB->MaxSetupCount = 0;
4382         pSMB->Reserved = 0;
4383         pSMB->Flags = 0;
4384         pSMB->Timeout = 0;
4385         pSMB->Reserved2 = 0;
4386         byte_count = params + 1 /* pad */ ;
4387         pSMB->TotalParameterCount = cpu_to_le16(params);
4388         pSMB->ParameterCount = pSMB->TotalParameterCount;
4389         pSMB->ParameterOffset = cpu_to_le16(
4390               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4391                 - 4);
4392         pSMB->DataCount = 0;
4393         pSMB->DataOffset = 0;
4394         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4395         pSMB->Reserved3 = 0;
4396         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4397         pSMB->SearchAttributes =
4398             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4399                         ATTR_DIRECTORY);
4400         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4401         pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END |
4402                 CIFS_SEARCH_RETURN_RESUME);
4403         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4404
4405         /* BB what should we set StorageType to? Does it matter? BB */
4406         pSMB->SearchStorageType = 0;
4407         inc_rfc1001_len(pSMB, byte_count);
4408         pSMB->ByteCount = cpu_to_le16(byte_count);
4409
4410         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4411                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4412         cifs_stats_inc(&tcon->num_ffirst);
4413
4414         if (rc) {/* BB add logic to retry regular search if Unix search
4415                         rejected unexpectedly by server */
4416                 /* BB Add code to handle unsupported level rc */
4417                 cFYI(1, "Error in FindFirst = %d", rc);
4418
4419                 cifs_buf_release(pSMB);
4420
4421                 /* BB eventually could optimize out free and realloc of buf */
4422                 /*    for this case */
4423                 if (rc == -EAGAIN)
4424                         goto findFirstRetry;
4425         } else { /* decode response */
4426                 /* BB remember to free buffer if error BB */
4427                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4428                 if (rc == 0) {
4429                         unsigned int lnoff;
4430
4431                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4432                                 psrch_inf->unicode = true;
4433                         else
4434                                 psrch_inf->unicode = false;
4435
4436                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4437                         psrch_inf->smallBuf = 0;
4438                         psrch_inf->srch_entries_start =
4439                                 (char *) &pSMBr->hdr.Protocol +
4440                                         le16_to_cpu(pSMBr->t2.DataOffset);
4441                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4442                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4443
4444                         if (parms->EndofSearch)
4445                                 psrch_inf->endOfSearch = true;
4446                         else
4447                                 psrch_inf->endOfSearch = false;
4448
4449                         psrch_inf->entries_in_buffer =
4450                                         le16_to_cpu(parms->SearchCount);
4451                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4452                                 psrch_inf->entries_in_buffer;
4453                         lnoff = le16_to_cpu(parms->LastNameOffset);
4454                         if (CIFSMaxBufSize < lnoff) {
4455                                 cERROR(1, "ignoring corrupt resume name");
4456                                 psrch_inf->last_entry = NULL;
4457                                 return rc;
4458                         }
4459
4460                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4461                                                         lnoff;
4462
4463                         *pnetfid = parms->SearchHandle;
4464                 } else {
4465                         cifs_buf_release(pSMB);
4466                 }
4467         }
4468
4469         return rc;
4470 }
4471
4472 int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
4473                  __u16 searchHandle, struct cifs_search_info *psrch_inf)
4474 {
4475         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4476         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4477         T2_FNEXT_RSP_PARMS *parms;
4478         char *response_data;
4479         int rc = 0;
4480         int bytes_returned;
4481         unsigned int name_len;
4482         __u16 params, byte_count;
4483
4484         cFYI(1, "In FindNext");
4485
4486         if (psrch_inf->endOfSearch)
4487                 return -ENOENT;
4488
4489         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4490                 (void **) &pSMBr);
4491         if (rc)
4492                 return rc;
4493
4494         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4495         byte_count = 0;
4496         pSMB->TotalDataCount = 0;       /* no EAs */
4497         pSMB->MaxParameterCount = cpu_to_le16(8);
4498         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4499         pSMB->MaxSetupCount = 0;
4500         pSMB->Reserved = 0;
4501         pSMB->Flags = 0;
4502         pSMB->Timeout = 0;
4503         pSMB->Reserved2 = 0;
4504         pSMB->ParameterOffset =  cpu_to_le16(
4505               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4506         pSMB->DataCount = 0;
4507         pSMB->DataOffset = 0;
4508         pSMB->SetupCount = 1;
4509         pSMB->Reserved3 = 0;
4510         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4511         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4512         pSMB->SearchCount =
4513                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4514         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4515         pSMB->ResumeKey = psrch_inf->resume_key;
4516         pSMB->SearchFlags =
4517               cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
4518
4519         name_len = psrch_inf->resume_name_len;
4520         params += name_len;
4521         if (name_len < PATH_MAX) {
4522                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4523                 byte_count += name_len;
4524                 /* 14 byte parm len above enough for 2 byte null terminator */
4525                 pSMB->ResumeFileName[name_len] = 0;
4526                 pSMB->ResumeFileName[name_len+1] = 0;
4527         } else {
4528                 rc = -EINVAL;
4529                 goto FNext2_err_exit;
4530         }
4531         byte_count = params + 1 /* pad */ ;
4532         pSMB->TotalParameterCount = cpu_to_le16(params);
4533         pSMB->ParameterCount = pSMB->TotalParameterCount;
4534         inc_rfc1001_len(pSMB, byte_count);
4535         pSMB->ByteCount = cpu_to_le16(byte_count);
4536
4537         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4538                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4539         cifs_stats_inc(&tcon->num_fnext);
4540         if (rc) {
4541                 if (rc == -EBADF) {
4542                         psrch_inf->endOfSearch = true;
4543                         cifs_buf_release(pSMB);
4544                         rc = 0; /* search probably was closed at end of search*/
4545                 } else
4546                         cFYI(1, "FindNext returned = %d", rc);
4547         } else {                /* decode response */
4548                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4549
4550                 if (rc == 0) {
4551                         unsigned int lnoff;
4552
4553                         /* BB fixme add lock for file (srch_info) struct here */
4554                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4555                                 psrch_inf->unicode = true;
4556                         else
4557                                 psrch_inf->unicode = false;
4558                         response_data = (char *) &pSMBr->hdr.Protocol +
4559                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4560                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4561                         response_data = (char *)&pSMBr->hdr.Protocol +
4562                                 le16_to_cpu(pSMBr->t2.DataOffset);
4563                         if (psrch_inf->smallBuf)
4564                                 cifs_small_buf_release(
4565                                         psrch_inf->ntwrk_buf_start);
4566                         else
4567                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4568                         psrch_inf->srch_entries_start = response_data;
4569                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4570                         psrch_inf->smallBuf = 0;
4571                         if (parms->EndofSearch)
4572                                 psrch_inf->endOfSearch = true;
4573                         else
4574                                 psrch_inf->endOfSearch = false;
4575                         psrch_inf->entries_in_buffer =
4576                                                 le16_to_cpu(parms->SearchCount);
4577                         psrch_inf->index_of_last_entry +=
4578                                 psrch_inf->entries_in_buffer;
4579                         lnoff = le16_to_cpu(parms->LastNameOffset);
4580                         if (CIFSMaxBufSize < lnoff) {
4581                                 cERROR(1, "ignoring corrupt resume name");
4582                                 psrch_inf->last_entry = NULL;
4583                                 return rc;
4584                         } else
4585                                 psrch_inf->last_entry =
4586                                         psrch_inf->srch_entries_start + lnoff;
4587
4588 /*  cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4589             psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4590
4591                         /* BB fixme add unlock here */
4592                 }
4593
4594         }
4595
4596         /* BB On error, should we leave previous search buf (and count and
4597         last entry fields) intact or free the previous one? */
4598
4599         /* Note: On -EAGAIN error only caller can retry on handle based calls
4600         since file handle passed in no longer valid */
4601 FNext2_err_exit:
4602         if (rc != 0)
4603                 cifs_buf_release(pSMB);
4604         return rc;
4605 }
4606
4607 int
4608 CIFSFindClose(const int xid, struct cifs_tcon *tcon,
4609               const __u16 searchHandle)
4610 {
4611         int rc = 0;
4612         FINDCLOSE_REQ *pSMB = NULL;
4613
4614         cFYI(1, "In CIFSSMBFindClose");
4615         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4616
4617         /* no sense returning error if session restarted
4618                 as file handle has been closed */
4619         if (rc == -EAGAIN)
4620                 return 0;
4621         if (rc)
4622                 return rc;
4623
4624         pSMB->FileID = searchHandle;
4625         pSMB->ByteCount = 0;
4626         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4627         if (rc)
4628                 cERROR(1, "Send error in FindClose = %d", rc);
4629
4630         cifs_stats_inc(&tcon->num_fclose);
4631
4632         /* Since session is dead, search handle closed on server already */
4633         if (rc == -EAGAIN)
4634                 rc = 0;
4635
4636         return rc;
4637 }
4638
4639 int
4640 CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
4641                       const unsigned char *searchName,
4642                       __u64 *inode_number,
4643                       const struct nls_table *nls_codepage, int remap)
4644 {
4645         int rc = 0;
4646         TRANSACTION2_QPI_REQ *pSMB = NULL;
4647         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4648         int name_len, bytes_returned;
4649         __u16 params, byte_count;
4650
4651         cFYI(1, "In GetSrvInodeNum for %s", searchName);
4652         if (tcon == NULL)
4653                 return -ENODEV;
4654
4655 GetInodeNumberRetry:
4656         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4657                       (void **) &pSMBr);
4658         if (rc)
4659                 return rc;
4660
4661         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4662                 name_len =
4663                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4664                                            searchName, PATH_MAX, nls_codepage,
4665                                            remap);
4666                 name_len++;     /* trailing null */
4667                 name_len *= 2;
4668         } else {        /* BB improve the check for buffer overruns BB */
4669                 name_len = strnlen(searchName, PATH_MAX);
4670                 name_len++;     /* trailing null */
4671                 strncpy(pSMB->FileName, searchName, name_len);
4672         }
4673
4674         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4675         pSMB->TotalDataCount = 0;
4676         pSMB->MaxParameterCount = cpu_to_le16(2);
4677         /* BB find exact max data count below from sess structure BB */
4678         pSMB->MaxDataCount = cpu_to_le16(4000);
4679         pSMB->MaxSetupCount = 0;
4680         pSMB->Reserved = 0;
4681         pSMB->Flags = 0;
4682         pSMB->Timeout = 0;
4683         pSMB->Reserved2 = 0;
4684         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4685                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4686         pSMB->DataCount = 0;
4687         pSMB->DataOffset = 0;
4688         pSMB->SetupCount = 1;
4689         pSMB->Reserved3 = 0;
4690         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4691         byte_count = params + 1 /* pad */ ;
4692         pSMB->TotalParameterCount = cpu_to_le16(params);
4693         pSMB->ParameterCount = pSMB->TotalParameterCount;
4694         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4695         pSMB->Reserved4 = 0;
4696         inc_rfc1001_len(pSMB, byte_count);
4697         pSMB->ByteCount = cpu_to_le16(byte_count);
4698
4699         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4700                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4701         if (rc) {
4702                 cFYI(1, "error %d in QueryInternalInfo", rc);
4703         } else {
4704                 /* decode response */
4705                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4706                 /* BB also check enough total bytes returned */
4707                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4708                         /* If rc should we check for EOPNOSUPP and
4709                         disable the srvino flag? or in caller? */
4710                         rc = -EIO;      /* bad smb */
4711                 else {
4712                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4713                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4714                         struct file_internal_info *pfinfo;
4715                         /* BB Do we need a cast or hash here ? */
4716                         if (count < 8) {
4717                                 cFYI(1, "Illegal size ret in QryIntrnlInf");
4718                                 rc = -EIO;
4719                                 goto GetInodeNumOut;
4720                         }
4721                         pfinfo = (struct file_internal_info *)
4722                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4723                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4724                 }
4725         }
4726 GetInodeNumOut:
4727         cifs_buf_release(pSMB);
4728         if (rc == -EAGAIN)
4729                 goto GetInodeNumberRetry;
4730         return rc;
4731 }
4732
4733 /* parses DFS refferal V3 structure
4734  * caller is responsible for freeing target_nodes
4735  * returns:
4736  *      on success - 0
4737  *      on failure - errno
4738  */
4739 static int
4740 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4741                 unsigned int *num_of_nodes,
4742                 struct dfs_info3_param **target_nodes,
4743                 const struct nls_table *nls_codepage, int remap,
4744                 const char *searchName)
4745 {
4746         int i, rc = 0;
4747         char *data_end;
4748         bool is_unicode;
4749         struct dfs_referral_level_3 *ref;
4750
4751         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4752                 is_unicode = true;
4753         else
4754                 is_unicode = false;
4755         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4756
4757         if (*num_of_nodes < 1) {
4758                 cERROR(1, "num_referrals: must be at least > 0,"
4759                         "but we get num_referrals = %d\n", *num_of_nodes);
4760                 rc = -EINVAL;
4761                 goto parse_DFS_referrals_exit;
4762         }
4763
4764         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4765         if (ref->VersionNumber != cpu_to_le16(3)) {
4766                 cERROR(1, "Referrals of V%d version are not supported,"
4767                         "should be V3", le16_to_cpu(ref->VersionNumber));
4768                 rc = -EINVAL;
4769                 goto parse_DFS_referrals_exit;
4770         }
4771
4772         /* get the upper boundary of the resp buffer */
4773         data_end = (char *)(&(pSMBr->PathConsumed)) +
4774                                 le16_to_cpu(pSMBr->t2.DataCount);
4775
4776         cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
4777                         *num_of_nodes,
4778                         le32_to_cpu(pSMBr->DFSFlags));
4779
4780         *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4781                         *num_of_nodes, GFP_KERNEL);
4782         if (*target_nodes == NULL) {
4783                 cERROR(1, "Failed to allocate buffer for target_nodes\n");
4784                 rc = -ENOMEM;
4785                 goto parse_DFS_referrals_exit;
4786         }
4787
4788         /* collect necessary data from referrals */
4789         for (i = 0; i < *num_of_nodes; i++) {
4790                 char *temp;
4791                 int max_len;
4792                 struct dfs_info3_param *node = (*target_nodes)+i;
4793
4794                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4795                 if (is_unicode) {
4796                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4797                                                 GFP_KERNEL);
4798                         if (tmp == NULL) {
4799                                 rc = -ENOMEM;
4800                                 goto parse_DFS_referrals_exit;
4801                         }
4802                         cifsConvertToUTF16((__le16 *) tmp, searchName,
4803                                            PATH_MAX, nls_codepage, remap);
4804                         node->path_consumed = cifs_utf16_bytes(tmp,
4805                                         le16_to_cpu(pSMBr->PathConsumed),
4806                                         nls_codepage);
4807                         kfree(tmp);
4808                 } else
4809                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4810
4811                 node->server_type = le16_to_cpu(ref->ServerType);
4812                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4813
4814                 /* copy DfsPath */
4815                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4816                 max_len = data_end - temp;
4817                 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4818                                                 is_unicode, nls_codepage);
4819                 if (!node->path_name) {
4820                         rc = -ENOMEM;
4821                         goto parse_DFS_referrals_exit;
4822                 }
4823
4824                 /* copy link target UNC */
4825                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4826                 max_len = data_end - temp;
4827                 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4828                                                 is_unicode, nls_codepage);
4829                 if (!node->node_name)
4830                         rc = -ENOMEM;
4831         }
4832
4833 parse_DFS_referrals_exit:
4834         if (rc) {
4835                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4836                 *target_nodes = NULL;
4837                 *num_of_nodes = 0;
4838         }
4839         return rc;
4840 }
4841
4842 int
4843 CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4844                 const unsigned char *searchName,
4845                 struct dfs_info3_param **target_nodes,
4846                 unsigned int *num_of_nodes,
4847                 const struct nls_table *nls_codepage, int remap)
4848 {
4849 /* TRANS2_GET_DFS_REFERRAL */
4850         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4851         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4852         int rc = 0;
4853         int bytes_returned;
4854         int name_len;
4855         __u16 params, byte_count;
4856         *num_of_nodes = 0;
4857         *target_nodes = NULL;
4858
4859         cFYI(1, "In GetDFSRefer the path %s", searchName);
4860         if (ses == NULL)
4861                 return -ENODEV;
4862 getDFSRetry:
4863         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4864                       (void **) &pSMBr);
4865         if (rc)
4866                 return rc;
4867
4868         /* server pointer checked in called function,
4869         but should never be null here anyway */
4870         pSMB->hdr.Mid = GetNextMid(ses->server);
4871         pSMB->hdr.Tid = ses->ipc_tid;
4872         pSMB->hdr.Uid = ses->Suid;
4873         if (ses->capabilities & CAP_STATUS32)
4874                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4875         if (ses->capabilities & CAP_DFS)
4876                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4877
4878         if (ses->capabilities & CAP_UNICODE) {
4879                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4880                 name_len =
4881                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4882                                        searchName, PATH_MAX, nls_codepage,
4883                                        remap);
4884                 name_len++;     /* trailing null */
4885                 name_len *= 2;
4886         } else {        /* BB improve the check for buffer overruns BB */
4887                 name_len = strnlen(searchName, PATH_MAX);
4888                 name_len++;     /* trailing null */
4889                 strncpy(pSMB->RequestFileName, searchName, name_len);
4890         }
4891
4892         if (ses->server) {
4893                 if (ses->server->sec_mode &
4894                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4895                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4896         }
4897
4898         pSMB->hdr.Uid = ses->Suid;
4899
4900         params = 2 /* level */  + name_len /*includes null */ ;
4901         pSMB->TotalDataCount = 0;
4902         pSMB->DataCount = 0;
4903         pSMB->DataOffset = 0;
4904         pSMB->MaxParameterCount = 0;
4905         /* BB find exact max SMB PDU from sess structure BB */
4906         pSMB->MaxDataCount = cpu_to_le16(4000);
4907         pSMB->MaxSetupCount = 0;
4908         pSMB->Reserved = 0;
4909         pSMB->Flags = 0;
4910         pSMB->Timeout = 0;
4911         pSMB->Reserved2 = 0;
4912         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4913           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4914         pSMB->SetupCount = 1;
4915         pSMB->Reserved3 = 0;
4916         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4917         byte_count = params + 3 /* pad */ ;
4918         pSMB->ParameterCount = cpu_to_le16(params);
4919         pSMB->TotalParameterCount = pSMB->ParameterCount;
4920         pSMB->MaxReferralLevel = cpu_to_le16(3);
4921         inc_rfc1001_len(pSMB, byte_count);
4922         pSMB->ByteCount = cpu_to_le16(byte_count);
4923
4924         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4925                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4926         if (rc) {
4927                 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4928                 goto GetDFSRefExit;
4929         }
4930         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4931
4932         /* BB Also check if enough total bytes returned? */
4933         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4934                 rc = -EIO;      /* bad smb */
4935                 goto GetDFSRefExit;
4936         }
4937
4938         cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
4939                                 get_bcc(&pSMBr->hdr),
4940                                 le16_to_cpu(pSMBr->t2.DataOffset));
4941
4942         /* parse returned result into more usable form */
4943         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4944                                  target_nodes, nls_codepage, remap,
4945                                  searchName);
4946
4947 GetDFSRefExit:
4948         cifs_buf_release(pSMB);
4949
4950         if (rc == -EAGAIN)
4951                 goto getDFSRetry;
4952
4953         return rc;
4954 }
4955
4956 /* Query File System Info such as free space to old servers such as Win 9x */
4957 int
4958 SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4959 {
4960 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4961         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4962         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4963         FILE_SYSTEM_ALLOC_INFO *response_data;
4964         int rc = 0;
4965         int bytes_returned = 0;
4966         __u16 params, byte_count;
4967
4968         cFYI(1, "OldQFSInfo");
4969 oldQFSInfoRetry:
4970         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4971                 (void **) &pSMBr);
4972         if (rc)
4973                 return rc;
4974
4975         params = 2;     /* level */
4976         pSMB->TotalDataCount = 0;
4977         pSMB->MaxParameterCount = cpu_to_le16(2);
4978         pSMB->MaxDataCount = cpu_to_le16(1000);
4979         pSMB->MaxSetupCount = 0;
4980         pSMB->Reserved = 0;
4981         pSMB->Flags = 0;
4982         pSMB->Timeout = 0;
4983         pSMB->Reserved2 = 0;
4984         byte_count = params + 1 /* pad */ ;
4985         pSMB->TotalParameterCount = cpu_to_le16(params);
4986         pSMB->ParameterCount = pSMB->TotalParameterCount;
4987         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4988         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4989         pSMB->DataCount = 0;
4990         pSMB->DataOffset = 0;
4991         pSMB->SetupCount = 1;
4992         pSMB->Reserved3 = 0;
4993         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4994         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4995         inc_rfc1001_len(pSMB, byte_count);
4996         pSMB->ByteCount = cpu_to_le16(byte_count);
4997
4998         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4999                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5000         if (rc) {
5001                 cFYI(1, "Send error in QFSInfo = %d", rc);
5002         } else {                /* decode response */
5003                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5004
5005                 if (rc || get_bcc(&pSMBr->hdr) < 18)
5006                         rc = -EIO;      /* bad smb */
5007                 else {
5008                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5009                         cFYI(1, "qfsinf resp BCC: %d  Offset %d",
5010                                  get_bcc(&pSMBr->hdr), data_offset);
5011
5012                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
5013                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5014                         FSData->f_bsize =
5015                                 le16_to_cpu(response_data->BytesPerSector) *
5016                                 le32_to_cpu(response_data->
5017                                         SectorsPerAllocationUnit);
5018                         FSData->f_blocks =
5019                                le32_to_cpu(response_data->TotalAllocationUnits);
5020                         FSData->f_bfree = FSData->f_bavail =
5021                                 le32_to_cpu(response_data->FreeAllocationUnits);
5022                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5023                              (unsigned long long)FSData->f_blocks,
5024                              (unsigned long long)FSData->f_bfree,
5025                              FSData->f_bsize);
5026                 }
5027         }
5028         cifs_buf_release(pSMB);
5029
5030         if (rc == -EAGAIN)
5031                 goto oldQFSInfoRetry;
5032
5033         return rc;
5034 }
5035
5036 int
5037 CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
5038 {
5039 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5040         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5041         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5042         FILE_SYSTEM_INFO *response_data;
5043         int rc = 0;
5044         int bytes_returned = 0;
5045         __u16 params, byte_count;
5046
5047         cFYI(1, "In QFSInfo");
5048 QFSInfoRetry:
5049         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5050                       (void **) &pSMBr);
5051         if (rc)
5052                 return rc;
5053
5054         params = 2;     /* level */
5055         pSMB->TotalDataCount = 0;
5056         pSMB->MaxParameterCount = cpu_to_le16(2);
5057         pSMB->MaxDataCount = cpu_to_le16(1000);
5058         pSMB->MaxSetupCount = 0;
5059         pSMB->Reserved = 0;
5060         pSMB->Flags = 0;
5061         pSMB->Timeout = 0;
5062         pSMB->Reserved2 = 0;
5063         byte_count = params + 1 /* pad */ ;
5064         pSMB->TotalParameterCount = cpu_to_le16(params);
5065         pSMB->ParameterCount = pSMB->TotalParameterCount;
5066         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5067                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5068         pSMB->DataCount = 0;
5069         pSMB->DataOffset = 0;
5070         pSMB->SetupCount = 1;
5071         pSMB->Reserved3 = 0;
5072         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5073         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5074         inc_rfc1001_len(pSMB, byte_count);
5075         pSMB->ByteCount = cpu_to_le16(byte_count);
5076
5077         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5078                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5079         if (rc) {
5080                 cFYI(1, "Send error in QFSInfo = %d", rc);
5081         } else {                /* decode response */
5082                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5083
5084                 if (rc || get_bcc(&pSMBr->hdr) < 24)
5085                         rc = -EIO;      /* bad smb */
5086                 else {
5087                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5088
5089                         response_data =
5090                             (FILE_SYSTEM_INFO
5091                              *) (((char *) &pSMBr->hdr.Protocol) +
5092                                  data_offset);
5093                         FSData->f_bsize =
5094                             le32_to_cpu(response_data->BytesPerSector) *
5095                             le32_to_cpu(response_data->
5096                                         SectorsPerAllocationUnit);
5097                         FSData->f_blocks =
5098                             le64_to_cpu(response_data->TotalAllocationUnits);
5099                         FSData->f_bfree = FSData->f_bavail =
5100                             le64_to_cpu(response_data->FreeAllocationUnits);
5101                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5102                              (unsigned long long)FSData->f_blocks,
5103                              (unsigned long long)FSData->f_bfree,
5104                              FSData->f_bsize);
5105                 }
5106         }
5107         cifs_buf_release(pSMB);
5108
5109         if (rc == -EAGAIN)
5110                 goto QFSInfoRetry;
5111
5112         return rc;
5113 }
5114
5115 int
5116 CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
5117 {
5118 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5119         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5120         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5121         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5122         int rc = 0;
5123         int bytes_returned = 0;
5124         __u16 params, byte_count;
5125
5126         cFYI(1, "In QFSAttributeInfo");
5127 QFSAttributeRetry:
5128         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5129                       (void **) &pSMBr);
5130         if (rc)
5131                 return rc;
5132
5133         params = 2;     /* level */
5134         pSMB->TotalDataCount = 0;
5135         pSMB->MaxParameterCount = cpu_to_le16(2);
5136         /* BB find exact max SMB PDU from sess structure BB */
5137         pSMB->MaxDataCount = cpu_to_le16(1000);
5138         pSMB->MaxSetupCount = 0;
5139         pSMB->Reserved = 0;
5140         pSMB->Flags = 0;
5141         pSMB->Timeout = 0;
5142         pSMB->Reserved2 = 0;
5143         byte_count = params + 1 /* pad */ ;
5144         pSMB->TotalParameterCount = cpu_to_le16(params);
5145         pSMB->ParameterCount = pSMB->TotalParameterCount;
5146         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5147                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5148         pSMB->DataCount = 0;
5149         pSMB->DataOffset = 0;
5150         pSMB->SetupCount = 1;
5151         pSMB->Reserved3 = 0;
5152         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5153         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5154         inc_rfc1001_len(pSMB, byte_count);
5155         pSMB->ByteCount = cpu_to_le16(byte_count);
5156
5157         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5158                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5159         if (rc) {
5160                 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5161         } else {                /* decode response */
5162                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5163
5164                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5165                         /* BB also check if enough bytes returned */
5166                         rc = -EIO;      /* bad smb */
5167                 } else {
5168                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5169                         response_data =
5170                             (FILE_SYSTEM_ATTRIBUTE_INFO
5171                              *) (((char *) &pSMBr->hdr.Protocol) +
5172                                  data_offset);
5173                         memcpy(&tcon->fsAttrInfo, response_data,
5174                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5175                 }
5176         }
5177         cifs_buf_release(pSMB);
5178
5179         if (rc == -EAGAIN)
5180                 goto QFSAttributeRetry;
5181
5182         return rc;
5183 }
5184
5185 int
5186 CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
5187 {
5188 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5189         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5190         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5191         FILE_SYSTEM_DEVICE_INFO *response_data;
5192         int rc = 0;
5193         int bytes_returned = 0;
5194         __u16 params, byte_count;
5195
5196         cFYI(1, "In QFSDeviceInfo");
5197 QFSDeviceRetry:
5198         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5199                       (void **) &pSMBr);
5200         if (rc)
5201                 return rc;
5202
5203         params = 2;     /* level */
5204         pSMB->TotalDataCount = 0;
5205         pSMB->MaxParameterCount = cpu_to_le16(2);
5206         /* BB find exact max SMB PDU from sess structure BB */
5207         pSMB->MaxDataCount = cpu_to_le16(1000);
5208         pSMB->MaxSetupCount = 0;
5209         pSMB->Reserved = 0;
5210         pSMB->Flags = 0;
5211         pSMB->Timeout = 0;
5212         pSMB->Reserved2 = 0;
5213         byte_count = params + 1 /* pad */ ;
5214         pSMB->TotalParameterCount = cpu_to_le16(params);
5215         pSMB->ParameterCount = pSMB->TotalParameterCount;
5216         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5217                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5218
5219         pSMB->DataCount = 0;
5220         pSMB->DataOffset = 0;
5221         pSMB->SetupCount = 1;
5222         pSMB->Reserved3 = 0;
5223         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5224         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5225         inc_rfc1001_len(pSMB, byte_count);
5226         pSMB->ByteCount = cpu_to_le16(byte_count);
5227
5228         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5229                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5230         if (rc) {
5231                 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5232         } else {                /* decode response */
5233                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5234
5235                 if (rc || get_bcc(&pSMBr->hdr) <
5236                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5237                         rc = -EIO;      /* bad smb */
5238                 else {
5239                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5240                         response_data =
5241                             (FILE_SYSTEM_DEVICE_INFO *)
5242                                 (((char *) &pSMBr->hdr.Protocol) +
5243                                  data_offset);
5244                         memcpy(&tcon->fsDevInfo, response_data,
5245                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5246                 }
5247         }
5248         cifs_buf_release(pSMB);
5249
5250         if (rc == -EAGAIN)
5251                 goto QFSDeviceRetry;
5252
5253         return rc;
5254 }
5255
5256 int
5257 CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
5258 {
5259 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5260         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5261         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5262         FILE_SYSTEM_UNIX_INFO *response_data;
5263         int rc = 0;
5264         int bytes_returned = 0;
5265         __u16 params, byte_count;
5266
5267         cFYI(1, "In QFSUnixInfo");
5268 QFSUnixRetry:
5269         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5270                                    (void **) &pSMB, (void **) &pSMBr);
5271         if (rc)
5272                 return rc;
5273
5274         params = 2;     /* level */
5275         pSMB->TotalDataCount = 0;
5276         pSMB->DataCount = 0;
5277         pSMB->DataOffset = 0;
5278         pSMB->MaxParameterCount = cpu_to_le16(2);
5279         /* BB find exact max SMB PDU from sess structure BB */
5280         pSMB->MaxDataCount = cpu_to_le16(100);
5281         pSMB->MaxSetupCount = 0;
5282         pSMB->Reserved = 0;
5283         pSMB->Flags = 0;
5284         pSMB->Timeout = 0;
5285         pSMB->Reserved2 = 0;
5286         byte_count = params + 1 /* pad */ ;
5287         pSMB->ParameterCount = cpu_to_le16(params);
5288         pSMB->TotalParameterCount = pSMB->ParameterCount;
5289         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5290                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5291         pSMB->SetupCount = 1;
5292         pSMB->Reserved3 = 0;
5293         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5294         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5295         inc_rfc1001_len(pSMB, byte_count);
5296         pSMB->ByteCount = cpu_to_le16(byte_count);
5297
5298         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5299                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5300         if (rc) {
5301                 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5302         } else {                /* decode response */
5303                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5304
5305                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5306                         rc = -EIO;      /* bad smb */
5307                 } else {
5308                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5309                         response_data =
5310                             (FILE_SYSTEM_UNIX_INFO
5311                              *) (((char *) &pSMBr->hdr.Protocol) +
5312                                  data_offset);
5313                         memcpy(&tcon->fsUnixInfo, response_data,
5314                                sizeof(FILE_SYSTEM_UNIX_INFO));
5315                 }
5316         }
5317         cifs_buf_release(pSMB);
5318
5319         if (rc == -EAGAIN)
5320                 goto QFSUnixRetry;
5321
5322
5323         return rc;
5324 }
5325
5326 int
5327 CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
5328 {
5329 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5330         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5331         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5332         int rc = 0;
5333         int bytes_returned = 0;
5334         __u16 params, param_offset, offset, byte_count;
5335
5336         cFYI(1, "In SETFSUnixInfo");
5337 SETFSUnixRetry:
5338         /* BB switch to small buf init to save memory */
5339         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5340                                         (void **) &pSMB, (void **) &pSMBr);
5341         if (rc)
5342                 return rc;
5343
5344         params = 4;     /* 2 bytes zero followed by info level. */
5345         pSMB->MaxSetupCount = 0;
5346         pSMB->Reserved = 0;
5347         pSMB->Flags = 0;
5348         pSMB->Timeout = 0;
5349         pSMB->Reserved2 = 0;
5350         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5351                                 - 4;
5352         offset = param_offset + params;
5353
5354         pSMB->MaxParameterCount = cpu_to_le16(4);
5355         /* BB find exact max SMB PDU from sess structure BB */
5356         pSMB->MaxDataCount = cpu_to_le16(100);
5357         pSMB->SetupCount = 1;
5358         pSMB->Reserved3 = 0;
5359         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5360         byte_count = 1 /* pad */ + params + 12;
5361
5362         pSMB->DataCount = cpu_to_le16(12);
5363         pSMB->ParameterCount = cpu_to_le16(params);
5364         pSMB->TotalDataCount = pSMB->DataCount;
5365         pSMB->TotalParameterCount = pSMB->ParameterCount;
5366         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5367         pSMB->DataOffset = cpu_to_le16(offset);
5368
5369         /* Params. */
5370         pSMB->FileNum = 0;
5371         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5372
5373         /* Data. */
5374         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5375         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5376         pSMB->ClientUnixCap = cpu_to_le64(cap);
5377
5378         inc_rfc1001_len(pSMB, byte_count);
5379         pSMB->ByteCount = cpu_to_le16(byte_count);
5380
5381         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5382                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5383         if (rc) {
5384                 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5385         } else {                /* decode response */
5386                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5387                 if (rc)
5388                         rc = -EIO;      /* bad smb */
5389         }
5390         cifs_buf_release(pSMB);
5391
5392         if (rc == -EAGAIN)
5393                 goto SETFSUnixRetry;
5394
5395         return rc;
5396 }
5397
5398
5399
5400 int
5401 CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
5402                    struct kstatfs *FSData)
5403 {
5404 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5405         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5406         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5407         FILE_SYSTEM_POSIX_INFO *response_data;
5408         int rc = 0;
5409         int bytes_returned = 0;
5410         __u16 params, byte_count;
5411
5412         cFYI(1, "In QFSPosixInfo");
5413 QFSPosixRetry:
5414         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5415                       (void **) &pSMBr);
5416         if (rc)
5417                 return rc;
5418
5419         params = 2;     /* level */
5420         pSMB->TotalDataCount = 0;
5421         pSMB->DataCount = 0;
5422         pSMB->DataOffset = 0;
5423         pSMB->MaxParameterCount = cpu_to_le16(2);
5424         /* BB find exact max SMB PDU from sess structure BB */
5425         pSMB->MaxDataCount = cpu_to_le16(100);
5426         pSMB->MaxSetupCount = 0;
5427         pSMB->Reserved = 0;
5428         pSMB->Flags = 0;
5429         pSMB->Timeout = 0;
5430         pSMB->Reserved2 = 0;
5431         byte_count = params + 1 /* pad */ ;
5432         pSMB->ParameterCount = cpu_to_le16(params);
5433         pSMB->TotalParameterCount = pSMB->ParameterCount;
5434         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5435                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5436         pSMB->SetupCount = 1;
5437         pSMB->Reserved3 = 0;
5438         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5439         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5440         inc_rfc1001_len(pSMB, byte_count);
5441         pSMB->ByteCount = cpu_to_le16(byte_count);
5442
5443         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5444                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5445         if (rc) {
5446                 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5447         } else {                /* decode response */
5448                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5449
5450                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5451                         rc = -EIO;      /* bad smb */
5452                 } else {
5453                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5454                         response_data =
5455                             (FILE_SYSTEM_POSIX_INFO
5456                              *) (((char *) &pSMBr->hdr.Protocol) +
5457                                  data_offset);
5458                         FSData->f_bsize =
5459                                         le32_to_cpu(response_data->BlockSize);
5460                         FSData->f_blocks =
5461                                         le64_to_cpu(response_data->TotalBlocks);
5462                         FSData->f_bfree =
5463                             le64_to_cpu(response_data->BlocksAvail);
5464                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5465                                 FSData->f_bavail = FSData->f_bfree;
5466                         } else {
5467                                 FSData->f_bavail =
5468                                     le64_to_cpu(response_data->UserBlocksAvail);
5469                         }
5470                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5471                                 FSData->f_files =
5472                                      le64_to_cpu(response_data->TotalFileNodes);
5473                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5474                                 FSData->f_ffree =
5475                                       le64_to_cpu(response_data->FreeFileNodes);
5476                 }
5477         }
5478         cifs_buf_release(pSMB);
5479
5480         if (rc == -EAGAIN)
5481                 goto QFSPosixRetry;
5482
5483         return rc;
5484 }
5485
5486
5487 /* We can not use write of zero bytes trick to
5488    set file size due to need for large file support.  Also note that
5489    this SetPathInfo is preferred to SetFileInfo based method in next
5490    routine which is only needed to work around a sharing violation bug
5491    in Samba which this routine can run into */
5492
5493 int
5494 CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
5495               __u64 size, bool SetAllocation,
5496               const struct nls_table *nls_codepage, int remap)
5497 {
5498         struct smb_com_transaction2_spi_req *pSMB = NULL;
5499         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5500         struct file_end_of_file_info *parm_data;
5501         int name_len;
5502         int rc = 0;
5503         int bytes_returned = 0;
5504         __u16 params, byte_count, data_count, param_offset, offset;
5505
5506         cFYI(1, "In SetEOF");
5507 SetEOFRetry:
5508         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5509                       (void **) &pSMBr);
5510         if (rc)
5511                 return rc;
5512
5513         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5514                 name_len =
5515                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5516                                        PATH_MAX, nls_codepage, remap);
5517                 name_len++;     /* trailing null */
5518                 name_len *= 2;
5519         } else {        /* BB improve the check for buffer overruns BB */
5520                 name_len = strnlen(fileName, PATH_MAX);
5521                 name_len++;     /* trailing null */
5522                 strncpy(pSMB->FileName, fileName, name_len);
5523         }
5524         params = 6 + name_len;
5525         data_count = sizeof(struct file_end_of_file_info);
5526         pSMB->MaxParameterCount = cpu_to_le16(2);
5527         pSMB->MaxDataCount = cpu_to_le16(4100);
5528         pSMB->MaxSetupCount = 0;
5529         pSMB->Reserved = 0;
5530         pSMB->Flags = 0;
5531         pSMB->Timeout = 0;
5532         pSMB->Reserved2 = 0;
5533         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5534                                 InformationLevel) - 4;
5535         offset = param_offset + params;
5536         if (SetAllocation) {
5537                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5538                         pSMB->InformationLevel =
5539                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5540                 else
5541                         pSMB->InformationLevel =
5542                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5543         } else /* Set File Size */  {
5544             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5545                     pSMB->InformationLevel =
5546                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5547             else
5548                     pSMB->InformationLevel =
5549                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5550         }
5551
5552         parm_data =
5553             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5554                                        offset);
5555         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5556         pSMB->DataOffset = cpu_to_le16(offset);
5557         pSMB->SetupCount = 1;
5558         pSMB->Reserved3 = 0;
5559         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5560         byte_count = 3 /* pad */  + params + data_count;
5561         pSMB->DataCount = cpu_to_le16(data_count);
5562         pSMB->TotalDataCount = pSMB->DataCount;
5563         pSMB->ParameterCount = cpu_to_le16(params);
5564         pSMB->TotalParameterCount = pSMB->ParameterCount;
5565         pSMB->Reserved4 = 0;
5566         inc_rfc1001_len(pSMB, byte_count);
5567         parm_data->FileSize = cpu_to_le64(size);
5568         pSMB->ByteCount = cpu_to_le16(byte_count);
5569         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5570                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5571         if (rc)
5572                 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5573
5574         cifs_buf_release(pSMB);
5575
5576         if (rc == -EAGAIN)
5577                 goto SetEOFRetry;
5578
5579         return rc;
5580 }
5581
5582 int
5583 CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5584                    __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5585 {
5586         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5587         struct file_end_of_file_info *parm_data;
5588         int rc = 0;
5589         __u16 params, param_offset, offset, byte_count, count;
5590
5591         cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5592                         (long long)size);
5593         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5594
5595         if (rc)
5596                 return rc;
5597
5598         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5599         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5600
5601         params = 6;
5602         pSMB->MaxSetupCount = 0;
5603         pSMB->Reserved = 0;
5604         pSMB->Flags = 0;
5605         pSMB->Timeout = 0;
5606         pSMB->Reserved2 = 0;
5607         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5608         offset = param_offset + params;
5609
5610         count = sizeof(struct file_end_of_file_info);
5611         pSMB->MaxParameterCount = cpu_to_le16(2);
5612         /* BB find exact max SMB PDU from sess structure BB */
5613         pSMB->MaxDataCount = cpu_to_le16(1000);
5614         pSMB->SetupCount = 1;
5615         pSMB->Reserved3 = 0;
5616         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5617         byte_count = 3 /* pad */  + params + count;
5618         pSMB->DataCount = cpu_to_le16(count);
5619         pSMB->ParameterCount = cpu_to_le16(params);
5620         pSMB->TotalDataCount = pSMB->DataCount;
5621         pSMB->TotalParameterCount = pSMB->ParameterCount;
5622         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5623         parm_data =
5624                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5625                                 + offset);
5626         pSMB->DataOffset = cpu_to_le16(offset);
5627         parm_data->FileSize = cpu_to_le64(size);
5628         pSMB->Fid = fid;
5629         if (SetAllocation) {
5630                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5631                         pSMB->InformationLevel =
5632                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5633                 else
5634                         pSMB->InformationLevel =
5635                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5636         } else /* Set File Size */  {
5637             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5638                     pSMB->InformationLevel =
5639                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5640             else
5641                     pSMB->InformationLevel =
5642                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5643         }
5644         pSMB->Reserved4 = 0;
5645         inc_rfc1001_len(pSMB, byte_count);
5646         pSMB->ByteCount = cpu_to_le16(byte_count);
5647         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5648         if (rc) {
5649                 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5650         }
5651
5652         /* Note: On -EAGAIN error only caller can retry on handle based calls
5653                 since file handle passed in no longer valid */
5654
5655         return rc;
5656 }
5657
5658 /* Some legacy servers such as NT4 require that the file times be set on
5659    an open handle, rather than by pathname - this is awkward due to
5660    potential access conflicts on the open, but it is unavoidable for these
5661    old servers since the only other choice is to go from 100 nanosecond DCE
5662    time and resort to the original setpathinfo l