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