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