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