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