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