]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/cifs/cifssmb.c
cifs: convert async write code to pass in data via rq_pages array
[karo-tx-linux.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         struct smb_rqst rqst = { .rq_iov = &iov,
729                                  .rq_nvec = 1 };
730
731         cFYI(1, "In echo request");
732
733         rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
734         if (rc)
735                 return rc;
736
737         /* set up echo request */
738         smb->hdr.Tid = 0xffff;
739         smb->hdr.WordCount = 1;
740         put_unaligned_le16(1, &smb->EchoCount);
741         put_bcc(1, &smb->hdr);
742         smb->Data[0] = 'a';
743         inc_rfc1001_len(smb, 3);
744         iov.iov_base = smb;
745         iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
746
747         rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback,
748                              server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
749         if (rc)
750                 cFYI(1, "Echo request failed: %d", rc);
751
752         cifs_small_buf_release(smb);
753
754         return rc;
755 }
756
757 int
758 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
759 {
760         LOGOFF_ANDX_REQ *pSMB;
761         int rc = 0;
762
763         cFYI(1, "In SMBLogoff for session disconnect");
764
765         /*
766          * BB: do we need to check validity of ses and server? They should
767          * always be valid since we have an active reference. If not, that
768          * should probably be a BUG()
769          */
770         if (!ses || !ses->server)
771                 return -EIO;
772
773         mutex_lock(&ses->session_mutex);
774         if (ses->need_reconnect)
775                 goto session_already_dead; /* no need to send SMBlogoff if uid
776                                               already closed due to reconnect */
777         rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
778         if (rc) {
779                 mutex_unlock(&ses->session_mutex);
780                 return rc;
781         }
782
783         pSMB->hdr.Mid = get_next_mid(ses->server);
784
785         if (ses->server->sec_mode &
786                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
787                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
788
789         pSMB->hdr.Uid = ses->Suid;
790
791         pSMB->AndXCommand = 0xFF;
792         rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
793 session_already_dead:
794         mutex_unlock(&ses->session_mutex);
795
796         /* if session dead then we do not need to do ulogoff,
797                 since server closed smb session, no sense reporting
798                 error */
799         if (rc == -EAGAIN)
800                 rc = 0;
801         return rc;
802 }
803
804 int
805 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
806                  const char *fileName, __u16 type,
807                  const struct nls_table *nls_codepage, int remap)
808 {
809         TRANSACTION2_SPI_REQ *pSMB = NULL;
810         TRANSACTION2_SPI_RSP *pSMBr = NULL;
811         struct unlink_psx_rq *pRqD;
812         int name_len;
813         int rc = 0;
814         int bytes_returned = 0;
815         __u16 params, param_offset, offset, byte_count;
816
817         cFYI(1, "In POSIX delete");
818 PsxDelete:
819         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
820                       (void **) &pSMBr);
821         if (rc)
822                 return rc;
823
824         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
825                 name_len =
826                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
827                                        PATH_MAX, nls_codepage, remap);
828                 name_len++;     /* trailing null */
829                 name_len *= 2;
830         } else { /* BB add path length overrun check */
831                 name_len = strnlen(fileName, PATH_MAX);
832                 name_len++;     /* trailing null */
833                 strncpy(pSMB->FileName, fileName, name_len);
834         }
835
836         params = 6 + name_len;
837         pSMB->MaxParameterCount = cpu_to_le16(2);
838         pSMB->MaxDataCount = 0; /* BB double check this with jra */
839         pSMB->MaxSetupCount = 0;
840         pSMB->Reserved = 0;
841         pSMB->Flags = 0;
842         pSMB->Timeout = 0;
843         pSMB->Reserved2 = 0;
844         param_offset = offsetof(struct smb_com_transaction2_spi_req,
845                                 InformationLevel) - 4;
846         offset = param_offset + params;
847
848         /* Setup pointer to Request Data (inode type) */
849         pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
850         pRqD->type = cpu_to_le16(type);
851         pSMB->ParameterOffset = cpu_to_le16(param_offset);
852         pSMB->DataOffset = cpu_to_le16(offset);
853         pSMB->SetupCount = 1;
854         pSMB->Reserved3 = 0;
855         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
856         byte_count = 3 /* pad */  + params + sizeof(struct unlink_psx_rq);
857
858         pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
859         pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
860         pSMB->ParameterCount = cpu_to_le16(params);
861         pSMB->TotalParameterCount = pSMB->ParameterCount;
862         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
863         pSMB->Reserved4 = 0;
864         inc_rfc1001_len(pSMB, byte_count);
865         pSMB->ByteCount = cpu_to_le16(byte_count);
866         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
867                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
868         if (rc)
869                 cFYI(1, "Posix delete returned %d", rc);
870         cifs_buf_release(pSMB);
871
872         cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
873
874         if (rc == -EAGAIN)
875                 goto PsxDelete;
876
877         return rc;
878 }
879
880 int
881 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
882                struct cifs_sb_info *cifs_sb)
883 {
884         DELETE_FILE_REQ *pSMB = NULL;
885         DELETE_FILE_RSP *pSMBr = NULL;
886         int rc = 0;
887         int bytes_returned;
888         int name_len;
889         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
890
891 DelFileRetry:
892         rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
893                       (void **) &pSMBr);
894         if (rc)
895                 return rc;
896
897         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
898                 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
899                                               PATH_MAX, cifs_sb->local_nls,
900                                               remap);
901                 name_len++;     /* trailing null */
902                 name_len *= 2;
903         } else {                /* BB improve check for buffer overruns BB */
904                 name_len = strnlen(name, PATH_MAX);
905                 name_len++;     /* trailing null */
906                 strncpy(pSMB->fileName, name, name_len);
907         }
908         pSMB->SearchAttributes =
909             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
910         pSMB->BufferFormat = 0x04;
911         inc_rfc1001_len(pSMB, name_len + 1);
912         pSMB->ByteCount = cpu_to_le16(name_len + 1);
913         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
914                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
915         cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
916         if (rc)
917                 cFYI(1, "Error in RMFile = %d", rc);
918
919         cifs_buf_release(pSMB);
920         if (rc == -EAGAIN)
921                 goto DelFileRetry;
922
923         return rc;
924 }
925
926 int
927 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
928              struct cifs_sb_info *cifs_sb)
929 {
930         DELETE_DIRECTORY_REQ *pSMB = NULL;
931         DELETE_DIRECTORY_RSP *pSMBr = NULL;
932         int rc = 0;
933         int bytes_returned;
934         int name_len;
935         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
936
937         cFYI(1, "In CIFSSMBRmDir");
938 RmDirRetry:
939         rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
940                       (void **) &pSMBr);
941         if (rc)
942                 return rc;
943
944         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
945                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
946                                               PATH_MAX, cifs_sb->local_nls,
947                                               remap);
948                 name_len++;     /* trailing null */
949                 name_len *= 2;
950         } else {                /* BB improve check for buffer overruns BB */
951                 name_len = strnlen(name, PATH_MAX);
952                 name_len++;     /* trailing null */
953                 strncpy(pSMB->DirName, name, name_len);
954         }
955
956         pSMB->BufferFormat = 0x04;
957         inc_rfc1001_len(pSMB, name_len + 1);
958         pSMB->ByteCount = cpu_to_le16(name_len + 1);
959         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
960                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
961         cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
962         if (rc)
963                 cFYI(1, "Error in RMDir = %d", rc);
964
965         cifs_buf_release(pSMB);
966         if (rc == -EAGAIN)
967                 goto RmDirRetry;
968         return rc;
969 }
970
971 int
972 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
973              struct cifs_sb_info *cifs_sb)
974 {
975         int rc = 0;
976         CREATE_DIRECTORY_REQ *pSMB = NULL;
977         CREATE_DIRECTORY_RSP *pSMBr = NULL;
978         int bytes_returned;
979         int name_len;
980         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
981
982         cFYI(1, "In CIFSSMBMkDir");
983 MkDirRetry:
984         rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
985                       (void **) &pSMBr);
986         if (rc)
987                 return rc;
988
989         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
990                 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
991                                               PATH_MAX, cifs_sb->local_nls,
992                                               remap);
993                 name_len++;     /* trailing null */
994                 name_len *= 2;
995         } else {                /* BB improve check for buffer overruns BB */
996                 name_len = strnlen(name, PATH_MAX);
997                 name_len++;     /* trailing null */
998                 strncpy(pSMB->DirName, name, name_len);
999         }
1000
1001         pSMB->BufferFormat = 0x04;
1002         inc_rfc1001_len(pSMB, name_len + 1);
1003         pSMB->ByteCount = cpu_to_le16(name_len + 1);
1004         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1005                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1006         cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
1007         if (rc)
1008                 cFYI(1, "Error in Mkdir = %d", rc);
1009
1010         cifs_buf_release(pSMB);
1011         if (rc == -EAGAIN)
1012                 goto MkDirRetry;
1013         return rc;
1014 }
1015
1016 int
1017 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
1018                 __u32 posix_flags, __u64 mode, __u16 *netfid,
1019                 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
1020                 const char *name, const struct nls_table *nls_codepage,
1021                 int remap)
1022 {
1023         TRANSACTION2_SPI_REQ *pSMB = NULL;
1024         TRANSACTION2_SPI_RSP *pSMBr = NULL;
1025         int name_len;
1026         int rc = 0;
1027         int bytes_returned = 0;
1028         __u16 params, param_offset, offset, byte_count, count;
1029         OPEN_PSX_REQ *pdata;
1030         OPEN_PSX_RSP *psx_rsp;
1031
1032         cFYI(1, "In POSIX Create");
1033 PsxCreat:
1034         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1035                       (void **) &pSMBr);
1036         if (rc)
1037                 return rc;
1038
1039         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1040                 name_len =
1041                     cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1042                                        PATH_MAX, nls_codepage, remap);
1043                 name_len++;     /* trailing null */
1044                 name_len *= 2;
1045         } else {        /* BB improve the check for buffer overruns BB */
1046                 name_len = strnlen(name, PATH_MAX);
1047                 name_len++;     /* trailing null */
1048                 strncpy(pSMB->FileName, name, name_len);
1049         }
1050
1051         params = 6 + name_len;
1052         count = sizeof(OPEN_PSX_REQ);
1053         pSMB->MaxParameterCount = cpu_to_le16(2);
1054         pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1055         pSMB->MaxSetupCount = 0;
1056         pSMB->Reserved = 0;
1057         pSMB->Flags = 0;
1058         pSMB->Timeout = 0;
1059         pSMB->Reserved2 = 0;
1060         param_offset = offsetof(struct smb_com_transaction2_spi_req,
1061                                 InformationLevel) - 4;
1062         offset = param_offset + params;
1063         pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
1064         pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1065         pdata->Permissions = cpu_to_le64(mode);
1066         pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1067         pdata->OpenFlags =  cpu_to_le32(*pOplock);
1068         pSMB->ParameterOffset = cpu_to_le16(param_offset);
1069         pSMB->DataOffset = cpu_to_le16(offset);
1070         pSMB->SetupCount = 1;
1071         pSMB->Reserved3 = 0;
1072         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1073         byte_count = 3 /* pad */  + params + count;
1074
1075         pSMB->DataCount = cpu_to_le16(count);
1076         pSMB->ParameterCount = cpu_to_le16(params);
1077         pSMB->TotalDataCount = pSMB->DataCount;
1078         pSMB->TotalParameterCount = pSMB->ParameterCount;
1079         pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1080         pSMB->Reserved4 = 0;
1081         inc_rfc1001_len(pSMB, byte_count);
1082         pSMB->ByteCount = cpu_to_le16(byte_count);
1083         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1084                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1085         if (rc) {
1086                 cFYI(1, "Posix create returned %d", rc);
1087                 goto psx_create_err;
1088         }
1089
1090         cFYI(1, "copying inode info");
1091         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1092
1093         if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1094                 rc = -EIO;      /* bad smb */
1095                 goto psx_create_err;
1096         }
1097
1098         /* copy return information to pRetData */
1099         psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1100                         + le16_to_cpu(pSMBr->t2.DataOffset));
1101
1102         *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1103         if (netfid)
1104                 *netfid = psx_rsp->Fid;   /* cifs fid stays in le */
1105         /* Let caller know file was created so we can set the mode. */
1106         /* Do we care about the CreateAction in any other cases? */
1107         if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1108                 *pOplock |= CIFS_CREATE_ACTION;
1109         /* check to make sure response data is there */
1110         if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1111                 pRetData->Type = cpu_to_le32(-1); /* unknown */
1112                 cFYI(DBG2, "unknown type");
1113         } else {
1114                 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1115                                         + sizeof(FILE_UNIX_BASIC_INFO)) {
1116                         cERROR(1, "Open response data too small");
1117                         pRetData->Type = cpu_to_le32(-1);
1118                         goto psx_create_err;
1119                 }
1120                 memcpy((char *) pRetData,
1121                         (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1122                         sizeof(FILE_UNIX_BASIC_INFO));
1123         }
1124
1125 psx_create_err:
1126         cifs_buf_release(pSMB);
1127
1128         if (posix_flags & SMB_O_DIRECTORY)
1129                 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1130         else
1131                 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1132
1133         if (rc == -EAGAIN)
1134                 goto PsxCreat;
1135
1136         return rc;
1137 }
1138
1139 static __u16 convert_disposition(int disposition)
1140 {
1141         __u16 ofun = 0;
1142
1143         switch (disposition) {
1144                 case FILE_SUPERSEDE:
1145                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1146                         break;
1147                 case FILE_OPEN:
1148                         ofun = SMBOPEN_OAPPEND;
1149                         break;
1150                 case FILE_CREATE:
1151                         ofun = SMBOPEN_OCREATE;
1152                         break;
1153                 case FILE_OPEN_IF:
1154                         ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1155                         break;
1156                 case FILE_OVERWRITE:
1157                         ofun = SMBOPEN_OTRUNC;
1158                         break;
1159                 case FILE_OVERWRITE_IF:
1160                         ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1161                         break;
1162                 default:
1163                         cFYI(1, "unknown disposition %d", disposition);
1164                         ofun =  SMBOPEN_OAPPEND; /* regular open */
1165         }
1166         return ofun;
1167 }
1168
1169 static int
1170 access_flags_to_smbopen_mode(const int access_flags)
1171 {
1172         int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1173
1174         if (masked_flags == GENERIC_READ)
1175                 return SMBOPEN_READ;
1176         else if (masked_flags == GENERIC_WRITE)
1177                 return SMBOPEN_WRITE;
1178
1179         /* just go for read/write */
1180         return SMBOPEN_READWRITE;
1181 }
1182
1183 int
1184 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1185             const char *fileName, const int openDisposition,
1186             const int access_flags, const int create_options, __u16 *netfid,
1187             int *pOplock, FILE_ALL_INFO *pfile_info,
1188             const struct nls_table *nls_codepage, int remap)
1189 {
1190         int rc = -EACCES;
1191         OPENX_REQ *pSMB = NULL;
1192         OPENX_RSP *pSMBr = NULL;
1193         int bytes_returned;
1194         int name_len;
1195         __u16 count;
1196
1197 OldOpenRetry:
1198         rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1199                       (void **) &pSMBr);
1200         if (rc)
1201                 return rc;
1202
1203         pSMB->AndXCommand = 0xFF;       /* none */
1204
1205         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1206                 count = 1;      /* account for one byte pad to word boundary */
1207                 name_len =
1208                    cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1209                                       fileName, PATH_MAX, nls_codepage, remap);
1210                 name_len++;     /* trailing null */
1211                 name_len *= 2;
1212         } else {                /* BB improve check for buffer overruns BB */
1213                 count = 0;      /* no pad */
1214                 name_len = strnlen(fileName, PATH_MAX);
1215                 name_len++;     /* trailing null */
1216                 strncpy(pSMB->fileName, fileName, name_len);
1217         }
1218         if (*pOplock & REQ_OPLOCK)
1219                 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1220         else if (*pOplock & REQ_BATCHOPLOCK)
1221                 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1222
1223         pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1224         pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1225         pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1226         /* set file as system file if special file such
1227            as fifo and server expecting SFU style and
1228            no Unix extensions */
1229
1230         if (create_options & CREATE_OPTION_SPECIAL)
1231                 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1232         else /* BB FIXME BB */
1233                 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1234
1235         if (create_options & CREATE_OPTION_READONLY)
1236                 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1237
1238         /* BB FIXME BB */
1239 /*      pSMB->CreateOptions = cpu_to_le32(create_options &
1240                                                  CREATE_OPTIONS_MASK); */
1241         /* BB FIXME END BB */
1242
1243         pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1244         pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1245         count += name_len;
1246         inc_rfc1001_len(pSMB, count);
1247
1248         pSMB->ByteCount = cpu_to_le16(count);
1249         /* long_op set to 1 to allow for oplock break timeouts */
1250         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1251                         (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1252         cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1253         if (rc) {
1254                 cFYI(1, "Error in Open = %d", rc);
1255         } else {
1256         /* BB verify if wct == 15 */
1257
1258 /*              *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1259
1260                 *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1261                 /* Let caller know file was created so we can set the mode. */
1262                 /* Do we care about the CreateAction in any other cases? */
1263         /* BB FIXME BB */
1264 /*              if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1265                         *pOplock |= CIFS_CREATE_ACTION; */
1266         /* BB FIXME END */
1267
1268                 if (pfile_info) {
1269                         pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1270                         pfile_info->LastAccessTime = 0; /* BB fixme */
1271                         pfile_info->LastWriteTime = 0; /* BB fixme */
1272                         pfile_info->ChangeTime = 0;  /* BB fixme */
1273                         pfile_info->Attributes =
1274                                 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1275                         /* the file_info buf is endian converted by caller */
1276                         pfile_info->AllocationSize =
1277                                 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1278                         pfile_info->EndOfFile = pfile_info->AllocationSize;
1279                         pfile_info->NumberOfLinks = cpu_to_le32(1);
1280                         pfile_info->DeletePending = 0;
1281                 }
1282         }
1283
1284         cifs_buf_release(pSMB);
1285         if (rc == -EAGAIN)
1286                 goto OldOpenRetry;
1287         return rc;
1288 }
1289
1290 int
1291 CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
1292             const char *fileName, const int openDisposition,
1293             const int access_flags, const int create_options, __u16 *netfid,
1294             int *pOplock, FILE_ALL_INFO *pfile_info,
1295             const struct nls_table *nls_codepage, int remap)
1296 {
1297         int rc = -EACCES;
1298         OPEN_REQ *pSMB = NULL;
1299         OPEN_RSP *pSMBr = NULL;
1300         int bytes_returned;
1301         int name_len;
1302         __u16 count;
1303
1304 openRetry:
1305         rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1306                       (void **) &pSMBr);
1307         if (rc)
1308                 return rc;
1309
1310         pSMB->AndXCommand = 0xFF;       /* none */
1311
1312         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1313                 count = 1;      /* account for one byte pad to word boundary */
1314                 name_len =
1315                     cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1316                                        fileName, PATH_MAX, nls_codepage, remap);
1317                 name_len++;     /* trailing null */
1318                 name_len *= 2;
1319                 pSMB->NameLength = cpu_to_le16(name_len);
1320         } else {                /* BB improve check for buffer overruns BB */
1321                 count = 0;      /* no pad */
1322                 name_len = strnlen(fileName, PATH_MAX);
1323                 name_len++;     /* trailing null */
1324                 pSMB->NameLength = cpu_to_le16(name_len);
1325                 strncpy(pSMB->fileName, fileName, name_len);
1326         }
1327         if (*pOplock & REQ_OPLOCK)
1328                 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1329         else if (*pOplock & REQ_BATCHOPLOCK)
1330                 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1331         pSMB->DesiredAccess = cpu_to_le32(access_flags);
1332         pSMB->AllocationSize = 0;
1333         /* set file as system file if special file such
1334            as fifo and server expecting SFU style and
1335            no Unix extensions */
1336         if (create_options & CREATE_OPTION_SPECIAL)
1337                 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1338         else
1339                 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1340
1341         /* XP does not handle ATTR_POSIX_SEMANTICS */
1342         /* but it helps speed up case sensitive checks for other
1343         servers such as Samba */
1344         if (tcon->ses->capabilities & CAP_UNIX)
1345                 pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1346
1347         if (create_options & CREATE_OPTION_READONLY)
1348                 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1349
1350         pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1351         pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1352         pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1353         /* BB Expirement with various impersonation levels and verify */
1354         pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1355         pSMB->SecurityFlags =
1356             SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1357
1358         count += name_len;
1359         inc_rfc1001_len(pSMB, count);
1360
1361         pSMB->ByteCount = cpu_to_le16(count);
1362         /* long_op set to 1 to allow for oplock break timeouts */
1363         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1364                         (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1365         cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1366         if (rc) {
1367                 cFYI(1, "Error in Open = %d", rc);
1368         } else {
1369                 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1370                 *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1371                 /* Let caller know file was created so we can set the mode. */
1372                 /* Do we care about the CreateAction in any other cases? */
1373                 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1374                         *pOplock |= CIFS_CREATE_ACTION;
1375                 if (pfile_info) {
1376                         memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1377                                 36 /* CreationTime to Attributes */);
1378                         /* the file_info buf is endian converted by caller */
1379                         pfile_info->AllocationSize = pSMBr->AllocationSize;
1380                         pfile_info->EndOfFile = pSMBr->EndOfFile;
1381                         pfile_info->NumberOfLinks = cpu_to_le32(1);
1382                         pfile_info->DeletePending = 0;
1383                 }
1384         }
1385
1386         cifs_buf_release(pSMB);
1387         if (rc == -EAGAIN)
1388                 goto openRetry;
1389         return rc;
1390 }
1391
1392 /*
1393  * Discard any remaining data in the current SMB. To do this, we borrow the
1394  * current bigbuf.
1395  */
1396 static int
1397 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1398 {
1399         unsigned int rfclen = get_rfc1002_length(server->smallbuf);
1400         int remaining = rfclen + 4 - server->total_read;
1401         struct cifs_readdata *rdata = mid->callback_data;
1402
1403         while (remaining > 0) {
1404                 int length;
1405
1406                 length = cifs_read_from_socket(server, server->bigbuf,
1407                                 min_t(unsigned int, remaining,
1408                                     CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1409                 if (length < 0)
1410                         return length;
1411                 server->total_read += length;
1412                 remaining -= length;
1413         }
1414
1415         dequeue_mid(mid, rdata->result);
1416         return 0;
1417 }
1418
1419 int
1420 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1421 {
1422         int length, len;
1423         unsigned int data_offset, data_len;
1424         struct cifs_readdata *rdata = mid->callback_data;
1425         char *buf = server->smallbuf;
1426         unsigned int buflen = get_rfc1002_length(buf) + 4;
1427
1428         cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__,
1429                 mid->mid, rdata->offset, rdata->bytes);
1430
1431         /*
1432          * read the rest of READ_RSP header (sans Data array), or whatever we
1433          * can if there's not enough data. At this point, we've read down to
1434          * the Mid.
1435          */
1436         len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1437                                                         HEADER_SIZE(server) + 1;
1438
1439         rdata->iov[0].iov_base = buf + HEADER_SIZE(server) - 1;
1440         rdata->iov[0].iov_len = len;
1441
1442         length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1443         if (length < 0)
1444                 return length;
1445         server->total_read += length;
1446
1447         /* Was the SMB read successful? */
1448         rdata->result = server->ops->map_error(buf, false);
1449         if (rdata->result != 0) {
1450                 cFYI(1, "%s: server returned error %d", __func__,
1451                         rdata->result);
1452                 return cifs_readv_discard(server, mid);
1453         }
1454
1455         /* Is there enough to get to the rest of the READ_RSP header? */
1456         if (server->total_read < server->vals->read_rsp_size) {
1457                 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1458                         __func__, server->total_read,
1459                         server->vals->read_rsp_size);
1460                 rdata->result = -EIO;
1461                 return cifs_readv_discard(server, mid);
1462         }
1463
1464         data_offset = server->ops->read_data_offset(buf) + 4;
1465         if (data_offset < server->total_read) {
1466                 /*
1467                  * win2k8 sometimes sends an offset of 0 when the read
1468                  * is beyond the EOF. Treat it as if the data starts just after
1469                  * the header.
1470                  */
1471                 cFYI(1, "%s: data offset (%u) inside read response header",
1472                         __func__, data_offset);
1473                 data_offset = server->total_read;
1474         } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1475                 /* data_offset is beyond the end of smallbuf */
1476                 cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
1477                         __func__, data_offset);
1478                 rdata->result = -EIO;
1479                 return cifs_readv_discard(server, mid);
1480         }
1481
1482         cFYI(1, "%s: total_read=%u data_offset=%u", __func__,
1483                 server->total_read, data_offset);
1484
1485         len = data_offset - server->total_read;
1486         if (len > 0) {
1487                 /* read any junk before data into the rest of smallbuf */
1488                 rdata->iov[0].iov_base = buf + server->total_read;
1489                 rdata->iov[0].iov_len = len;
1490                 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
1491                 if (length < 0)
1492                         return length;
1493                 server->total_read += length;
1494         }
1495
1496         /* set up first iov for signature check */
1497         rdata->iov[0].iov_base = buf;
1498         rdata->iov[0].iov_len = server->total_read;
1499         cFYI(1, "0: iov_base=%p iov_len=%zu",
1500                 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1501
1502         /* how much data is in the response? */
1503         data_len = server->ops->read_data_length(buf);
1504         if (data_offset + data_len > buflen) {
1505                 /* data_len is corrupt -- discard frame */
1506                 rdata->result = -EIO;
1507                 return cifs_readv_discard(server, mid);
1508         }
1509
1510         /* marshal up the page array */
1511         cifs_kmap_lock();
1512         len = rdata->marshal_iov(rdata, data_len);
1513         cifs_kmap_unlock();
1514         data_len -= len;
1515
1516         /* issue the read if we have any iovecs left to fill */
1517         if (rdata->nr_iov > 1) {
1518                 length = cifs_readv_from_socket(server, &rdata->iov[1],
1519                                                 rdata->nr_iov - 1, len);
1520                 if (length < 0)
1521                         return length;
1522                 server->total_read += length;
1523         } else {
1524                 length = 0;
1525         }
1526
1527         rdata->bytes = length;
1528
1529         cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read,
1530                 buflen, data_len);
1531
1532         /* discard anything left over */
1533         if (server->total_read < buflen)
1534                 return cifs_readv_discard(server, mid);
1535
1536         dequeue_mid(mid, false);
1537         return length;
1538 }
1539
1540 static void
1541 cifs_readv_callback(struct mid_q_entry *mid)
1542 {
1543         struct cifs_readdata *rdata = mid->callback_data;
1544         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1545         struct TCP_Server_Info *server = tcon->ses->server;
1546         struct smb_rqst rqst = { .rq_iov = rdata->iov,
1547                                  .rq_nvec = rdata->nr_iov };
1548
1549         cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__,
1550                 mid->mid, mid->mid_state, rdata->result, rdata->bytes);
1551
1552         switch (mid->mid_state) {
1553         case MID_RESPONSE_RECEIVED:
1554                 /* result already set, check signature */
1555                 if (server->sec_mode &
1556                     (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1557                         int rc = 0;
1558
1559                         rc = cifs_verify_signature(&rqst, server,
1560                                                   mid->sequence_number + 1);
1561                         if (rc)
1562                                 cERROR(1, "SMB signature verification returned "
1563                                        "error = %d", rc);
1564                 }
1565                 /* FIXME: should this be counted toward the initiating task? */
1566                 task_io_account_read(rdata->bytes);
1567                 cifs_stats_bytes_read(tcon, rdata->bytes);
1568                 break;
1569         case MID_REQUEST_SUBMITTED:
1570         case MID_RETRY_NEEDED:
1571                 rdata->result = -EAGAIN;
1572                 break;
1573         default:
1574                 rdata->result = -EIO;
1575         }
1576
1577         queue_work(cifsiod_wq, &rdata->work);
1578         DeleteMidQEntry(mid);
1579         add_credits(server, 1, 0);
1580 }
1581
1582 /* cifs_async_readv - send an async write, and set up mid to handle result */
1583 int
1584 cifs_async_readv(struct cifs_readdata *rdata)
1585 {
1586         int rc;
1587         READ_REQ *smb = NULL;
1588         int wct;
1589         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1590         struct smb_rqst rqst = { .rq_iov = rdata->iov,
1591                                  .rq_nvec = 1 };
1592
1593         cFYI(1, "%s: offset=%llu bytes=%u", __func__,
1594                 rdata->offset, rdata->bytes);
1595
1596         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1597                 wct = 12;
1598         else {
1599                 wct = 10; /* old style read */
1600                 if ((rdata->offset >> 32) > 0)  {
1601                         /* can not handle this big offset for old */
1602                         return -EIO;
1603                 }
1604         }
1605
1606         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1607         if (rc)
1608                 return rc;
1609
1610         smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1611         smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1612
1613         smb->AndXCommand = 0xFF;        /* none */
1614         smb->Fid = rdata->cfile->fid.netfid;
1615         smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1616         if (wct == 12)
1617                 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1618         smb->Remaining = 0;
1619         smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1620         smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1621         if (wct == 12)
1622                 smb->ByteCount = 0;
1623         else {
1624                 /* old style read */
1625                 struct smb_com_readx_req *smbr =
1626                         (struct smb_com_readx_req *)smb;
1627                 smbr->ByteCount = 0;
1628         }
1629
1630         /* 4 for RFC1001 length + 1 for BCC */
1631         rdata->iov[0].iov_base = smb;
1632         rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1633
1634         kref_get(&rdata->refcount);
1635         rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1636                              cifs_readv_callback, rdata, 0);
1637
1638         if (rc == 0)
1639                 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1640         else
1641                 kref_put(&rdata->refcount, cifs_readdata_release);
1642
1643         cifs_small_buf_release(smb);
1644         return rc;
1645 }
1646
1647 int
1648 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1649             unsigned int *nbytes, char **buf, int *pbuf_type)
1650 {
1651         int rc = -EACCES;
1652         READ_REQ *pSMB = NULL;
1653         READ_RSP *pSMBr = NULL;
1654         char *pReadData = NULL;
1655         int wct;
1656         int resp_buf_type = 0;
1657         struct kvec iov[1];
1658         __u32 pid = io_parms->pid;
1659         __u16 netfid = io_parms->netfid;
1660         __u64 offset = io_parms->offset;
1661         struct cifs_tcon *tcon = io_parms->tcon;
1662         unsigned int count = io_parms->length;
1663
1664         cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1665         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1666                 wct = 12;
1667         else {
1668                 wct = 10; /* old style read */
1669                 if ((offset >> 32) > 0)  {
1670                         /* can not handle this big offset for old */
1671                         return -EIO;
1672                 }
1673         }
1674
1675         *nbytes = 0;
1676         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1677         if (rc)
1678                 return rc;
1679
1680         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1681         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1682
1683         /* tcon and ses pointer are checked in smb_init */
1684         if (tcon->ses->server == NULL)
1685                 return -ECONNABORTED;
1686
1687         pSMB->AndXCommand = 0xFF;       /* none */
1688         pSMB->Fid = netfid;
1689         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1690         if (wct == 12)
1691                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1692
1693         pSMB->Remaining = 0;
1694         pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1695         pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1696         if (wct == 12)
1697                 pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1698         else {
1699                 /* old style read */
1700                 struct smb_com_readx_req *pSMBW =
1701                         (struct smb_com_readx_req *)pSMB;
1702                 pSMBW->ByteCount = 0;
1703         }
1704
1705         iov[0].iov_base = (char *)pSMB;
1706         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1707         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1708                          &resp_buf_type, CIFS_LOG_ERROR);
1709         cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1710         pSMBr = (READ_RSP *)iov[0].iov_base;
1711         if (rc) {
1712                 cERROR(1, "Send error in read = %d", rc);
1713         } else {
1714                 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1715                 data_length = data_length << 16;
1716                 data_length += le16_to_cpu(pSMBr->DataLength);
1717                 *nbytes = data_length;
1718
1719                 /*check that DataLength would not go beyond end of SMB */
1720                 if ((data_length > CIFSMaxBufSize)
1721                                 || (data_length > count)) {
1722                         cFYI(1, "bad length %d for count %d",
1723                                  data_length, count);
1724                         rc = -EIO;
1725                         *nbytes = 0;
1726                 } else {
1727                         pReadData = (char *) (&pSMBr->hdr.Protocol) +
1728                                         le16_to_cpu(pSMBr->DataOffset);
1729 /*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
1730                                 cERROR(1, "Faulting on read rc = %d",rc);
1731                                 rc = -EFAULT;
1732                         }*/ /* can not use copy_to_user when using page cache*/
1733                         if (*buf)
1734                                 memcpy(*buf, pReadData, data_length);
1735                 }
1736         }
1737
1738 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1739         if (*buf) {
1740                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1741                         cifs_small_buf_release(iov[0].iov_base);
1742                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1743                         cifs_buf_release(iov[0].iov_base);
1744         } else if (resp_buf_type != CIFS_NO_BUFFER) {
1745                 /* return buffer to caller to free */
1746                 *buf = iov[0].iov_base;
1747                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1748                         *pbuf_type = CIFS_SMALL_BUFFER;
1749                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1750                         *pbuf_type = CIFS_LARGE_BUFFER;
1751         } /* else no valid buffer on return - leave as null */
1752
1753         /* Note: On -EAGAIN error only caller can retry on handle based calls
1754                 since file handle passed in no longer valid */
1755         return rc;
1756 }
1757
1758
1759 int
1760 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1761              unsigned int *nbytes, const char *buf,
1762              const char __user *ubuf, const int long_op)
1763 {
1764         int rc = -EACCES;
1765         WRITE_REQ *pSMB = NULL;
1766         WRITE_RSP *pSMBr = NULL;
1767         int bytes_returned, wct;
1768         __u32 bytes_sent;
1769         __u16 byte_count;
1770         __u32 pid = io_parms->pid;
1771         __u16 netfid = io_parms->netfid;
1772         __u64 offset = io_parms->offset;
1773         struct cifs_tcon *tcon = io_parms->tcon;
1774         unsigned int count = io_parms->length;
1775
1776         *nbytes = 0;
1777
1778         /* cFYI(1, "write at %lld %d bytes", offset, count);*/
1779         if (tcon->ses == NULL)
1780                 return -ECONNABORTED;
1781
1782         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1783                 wct = 14;
1784         else {
1785                 wct = 12;
1786                 if ((offset >> 32) > 0) {
1787                         /* can not handle big offset for old srv */
1788                         return -EIO;
1789                 }
1790         }
1791
1792         rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1793                       (void **) &pSMBr);
1794         if (rc)
1795                 return rc;
1796
1797         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1798         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1799
1800         /* tcon and ses pointer are checked in smb_init */
1801         if (tcon->ses->server == NULL)
1802                 return -ECONNABORTED;
1803
1804         pSMB->AndXCommand = 0xFF;       /* none */
1805         pSMB->Fid = netfid;
1806         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1807         if (wct == 14)
1808                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1809
1810         pSMB->Reserved = 0xFFFFFFFF;
1811         pSMB->WriteMode = 0;
1812         pSMB->Remaining = 0;
1813
1814         /* Can increase buffer size if buffer is big enough in some cases ie we
1815         can send more if LARGE_WRITE_X capability returned by the server and if
1816         our buffer is big enough or if we convert to iovecs on socket writes
1817         and eliminate the copy to the CIFS buffer */
1818         if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1819                 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1820         } else {
1821                 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1822                          & ~0xFF;
1823         }
1824
1825         if (bytes_sent > count)
1826                 bytes_sent = count;
1827         pSMB->DataOffset =
1828                 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1829         if (buf)
1830                 memcpy(pSMB->Data, buf, bytes_sent);
1831         else if (ubuf) {
1832                 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1833                         cifs_buf_release(pSMB);
1834                         return -EFAULT;
1835                 }
1836         } else if (count != 0) {
1837                 /* No buffer */
1838                 cifs_buf_release(pSMB);
1839                 return -EINVAL;
1840         } /* else setting file size with write of zero bytes */
1841         if (wct == 14)
1842                 byte_count = bytes_sent + 1; /* pad */
1843         else /* wct == 12 */
1844                 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1845
1846         pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1847         pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1848         inc_rfc1001_len(pSMB, byte_count);
1849
1850         if (wct == 14)
1851                 pSMB->ByteCount = cpu_to_le16(byte_count);
1852         else { /* old style write has byte count 4 bytes earlier
1853                   so 4 bytes pad  */
1854                 struct smb_com_writex_req *pSMBW =
1855                         (struct smb_com_writex_req *)pSMB;
1856                 pSMBW->ByteCount = cpu_to_le16(byte_count);
1857         }
1858
1859         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1860                          (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1861         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1862         if (rc) {
1863                 cFYI(1, "Send error in write = %d", rc);
1864         } else {
1865                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1866                 *nbytes = (*nbytes) << 16;
1867                 *nbytes += le16_to_cpu(pSMBr->Count);
1868
1869                 /*
1870                  * Mask off high 16 bits when bytes written as returned by the
1871                  * server is greater than bytes requested by the client. Some
1872                  * OS/2 servers are known to set incorrect CountHigh values.
1873                  */
1874                 if (*nbytes > count)
1875                         *nbytes &= 0xFFFF;
1876         }
1877
1878         cifs_buf_release(pSMB);
1879
1880         /* Note: On -EAGAIN error only caller can retry on handle based calls
1881                 since file handle passed in no longer valid */
1882
1883         return rc;
1884 }
1885
1886 void
1887 cifs_writedata_release(struct kref *refcount)
1888 {
1889         struct cifs_writedata *wdata = container_of(refcount,
1890                                         struct cifs_writedata, refcount);
1891
1892         if (wdata->cfile)
1893                 cifsFileInfo_put(wdata->cfile);
1894
1895         kfree(wdata);
1896 }
1897
1898 /*
1899  * Write failed with a retryable error. Resend the write request. It's also
1900  * possible that the page was redirtied so re-clean the page.
1901  */
1902 static void
1903 cifs_writev_requeue(struct cifs_writedata *wdata)
1904 {
1905         int i, rc;
1906         struct inode *inode = wdata->cfile->dentry->d_inode;
1907         struct TCP_Server_Info *server;
1908
1909         for (i = 0; i < wdata->nr_pages; i++) {
1910                 lock_page(wdata->pages[i]);
1911                 clear_page_dirty_for_io(wdata->pages[i]);
1912         }
1913
1914         do {
1915                 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1916                 rc = server->ops->async_writev(wdata);
1917         } while (rc == -EAGAIN);
1918
1919         for (i = 0; i < wdata->nr_pages; i++) {
1920                 if (rc != 0)
1921                         SetPageError(wdata->pages[i]);
1922                 unlock_page(wdata->pages[i]);
1923         }
1924
1925         mapping_set_error(inode->i_mapping, rc);
1926         kref_put(&wdata->refcount, cifs_writedata_release);
1927 }
1928
1929 void
1930 cifs_writev_complete(struct work_struct *work)
1931 {
1932         struct cifs_writedata *wdata = container_of(work,
1933                                                 struct cifs_writedata, work);
1934         struct inode *inode = wdata->cfile->dentry->d_inode;
1935         int i = 0;
1936
1937         if (wdata->result == 0) {
1938                 spin_lock(&inode->i_lock);
1939                 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
1940                 spin_unlock(&inode->i_lock);
1941                 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
1942                                          wdata->bytes);
1943         } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
1944                 return cifs_writev_requeue(wdata);
1945
1946         for (i = 0; i < wdata->nr_pages; i++) {
1947                 struct page *page = wdata->pages[i];
1948                 if (wdata->result == -EAGAIN)
1949                         __set_page_dirty_nobuffers(page);
1950                 else if (wdata->result < 0)
1951                         SetPageError(page);
1952                 end_page_writeback(page);
1953                 page_cache_release(page);
1954         }
1955         if (wdata->result != -EAGAIN)
1956                 mapping_set_error(inode->i_mapping, wdata->result);
1957         kref_put(&wdata->refcount, cifs_writedata_release);
1958 }
1959
1960 struct cifs_writedata *
1961 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
1962 {
1963         struct cifs_writedata *wdata;
1964
1965         /* this would overflow */
1966         if (nr_pages == 0) {
1967                 cERROR(1, "%s: called with nr_pages == 0!", __func__);
1968                 return NULL;
1969         }
1970
1971         /* writedata + number of page pointers */
1972         wdata = kzalloc(sizeof(*wdata) +
1973                         sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
1974         if (wdata != NULL) {
1975                 kref_init(&wdata->refcount);
1976                 INIT_LIST_HEAD(&wdata->list);
1977                 init_completion(&wdata->done);
1978                 INIT_WORK(&wdata->work, complete);
1979         }
1980         return wdata;
1981 }
1982
1983 /*
1984  * Check the mid_state and signature on received buffer (if any), and queue the
1985  * workqueue completion task.
1986  */
1987 static void
1988 cifs_writev_callback(struct mid_q_entry *mid)
1989 {
1990         struct cifs_writedata *wdata = mid->callback_data;
1991         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1992         unsigned int written;
1993         WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1994
1995         switch (mid->mid_state) {
1996         case MID_RESPONSE_RECEIVED:
1997                 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1998                 if (wdata->result != 0)
1999                         break;
2000
2001                 written = le16_to_cpu(smb->CountHigh);
2002                 written <<= 16;
2003                 written += le16_to_cpu(smb->Count);
2004                 /*
2005                  * Mask off high 16 bits when bytes written as returned
2006                  * by the server is greater than bytes requested by the
2007                  * client. OS/2 servers are known to set incorrect
2008                  * CountHigh values.
2009                  */
2010                 if (written > wdata->bytes)
2011                         written &= 0xFFFF;
2012
2013                 if (written < wdata->bytes)
2014                         wdata->result = -ENOSPC;
2015                 else
2016                         wdata->bytes = written;
2017                 break;
2018         case MID_REQUEST_SUBMITTED:
2019         case MID_RETRY_NEEDED:
2020                 wdata->result = -EAGAIN;
2021                 break;
2022         default:
2023                 wdata->result = -EIO;
2024                 break;
2025         }
2026
2027         queue_work(cifsiod_wq, &wdata->work);
2028         DeleteMidQEntry(mid);
2029         add_credits(tcon->ses->server, 1, 0);
2030 }
2031
2032 /* cifs_async_writev - send an async write, and set up mid to handle result */
2033 int
2034 cifs_async_writev(struct cifs_writedata *wdata)
2035 {
2036         int rc = -EACCES;
2037         WRITE_REQ *smb = NULL;
2038         int wct;
2039         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2040         struct kvec iov;
2041         struct smb_rqst rqst = { };
2042
2043         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2044                 wct = 14;
2045         } else {
2046                 wct = 12;
2047                 if (wdata->offset >> 32 > 0) {
2048                         /* can not handle big offset for old srv */
2049                         return -EIO;
2050                 }
2051         }
2052
2053         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2054         if (rc)
2055                 goto async_writev_out;
2056
2057         smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2058         smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2059
2060         smb->AndXCommand = 0xFF;        /* none */
2061         smb->Fid = wdata->cfile->fid.netfid;
2062         smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2063         if (wct == 14)
2064                 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2065         smb->Reserved = 0xFFFFFFFF;
2066         smb->WriteMode = 0;
2067         smb->Remaining = 0;
2068
2069         smb->DataOffset =
2070             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2071
2072         /* 4 for RFC1001 length + 1 for BCC */
2073         iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
2074         iov.iov_base = smb;
2075
2076         rqst.rq_iov = &iov;
2077         rqst.rq_nvec = 1;
2078         rqst.rq_pages = wdata->pages;
2079         rqst.rq_npages = wdata->nr_pages;
2080         rqst.rq_pagesz = wdata->pagesz;
2081         rqst.rq_tailsz = wdata->tailsz;
2082
2083         cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
2084
2085         smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2086         smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2087
2088         if (wct == 14) {
2089                 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2090                 put_bcc(wdata->bytes + 1, &smb->hdr);
2091         } else {
2092                 /* wct == 12 */
2093                 struct smb_com_writex_req *smbw =
2094                                 (struct smb_com_writex_req *)smb;
2095                 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2096                 put_bcc(wdata->bytes + 5, &smbw->hdr);
2097                 iov.iov_len += 4; /* pad bigger by four bytes */
2098         }
2099
2100         kref_get(&wdata->refcount);
2101         rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2102                                 cifs_writev_callback, wdata, 0);
2103
2104         if (rc == 0)
2105                 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2106         else
2107                 kref_put(&wdata->refcount, cifs_writedata_release);
2108
2109 async_writev_out:
2110         cifs_small_buf_release(smb);
2111         return rc;
2112 }
2113
2114 int
2115 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2116               unsigned int *nbytes, struct kvec *iov, int n_vec)
2117 {
2118         int rc = -EACCES;
2119         WRITE_REQ *pSMB = NULL;
2120         int wct;
2121         int smb_hdr_len;
2122         int resp_buf_type = 0;
2123         __u32 pid = io_parms->pid;
2124         __u16 netfid = io_parms->netfid;
2125         __u64 offset = io_parms->offset;
2126         struct cifs_tcon *tcon = io_parms->tcon;
2127         unsigned int count = io_parms->length;
2128
2129         *nbytes = 0;
2130
2131         cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
2132
2133         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2134                 wct = 14;
2135         } else {
2136                 wct = 12;
2137                 if ((offset >> 32) > 0) {
2138                         /* can not handle big offset for old srv */
2139                         return -EIO;
2140                 }
2141         }
2142         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2143         if (rc)
2144                 return rc;
2145
2146         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2147         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2148
2149         /* tcon and ses pointer are checked in smb_init */
2150         if (tcon->ses->server == NULL)
2151                 return -ECONNABORTED;
2152
2153         pSMB->AndXCommand = 0xFF;       /* none */
2154         pSMB->Fid = netfid;
2155         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2156         if (wct == 14)
2157                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2158         pSMB->Reserved = 0xFFFFFFFF;
2159         pSMB->WriteMode = 0;
2160         pSMB->Remaining = 0;
2161
2162         pSMB->DataOffset =
2163             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2164
2165         pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2166         pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2167         /* header + 1 byte pad */
2168         smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2169         if (wct == 14)
2170                 inc_rfc1001_len(pSMB, count + 1);
2171         else /* wct == 12 */
2172                 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2173         if (wct == 14)
2174                 pSMB->ByteCount = cpu_to_le16(count + 1);
2175         else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2176                 struct smb_com_writex_req *pSMBW =
2177                                 (struct smb_com_writex_req *)pSMB;
2178                 pSMBW->ByteCount = cpu_to_le16(count + 5);
2179         }
2180         iov[0].iov_base = pSMB;
2181         if (wct == 14)
2182                 iov[0].iov_len = smb_hdr_len + 4;
2183         else /* wct == 12 pad bigger by four bytes */
2184                 iov[0].iov_len = smb_hdr_len + 8;
2185
2186
2187         rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0);
2188         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2189         if (rc) {
2190                 cFYI(1, "Send error Write2 = %d", rc);
2191         } else if (resp_buf_type == 0) {
2192                 /* presumably this can not happen, but best to be safe */
2193                 rc = -EIO;
2194         } else {
2195                 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
2196                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
2197                 *nbytes = (*nbytes) << 16;
2198                 *nbytes += le16_to_cpu(pSMBr->Count);
2199
2200                 /*
2201                  * Mask off high 16 bits when bytes written as returned by the
2202                  * server is greater than bytes requested by the client. OS/2
2203                  * servers are known to set incorrect CountHigh values.
2204                  */
2205                 if (*nbytes > count)
2206                         *nbytes &= 0xFFFF;
2207         }
2208
2209 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2210         if (resp_buf_type == CIFS_SMALL_BUFFER)
2211                 cifs_small_buf_release(iov[0].iov_base);
2212         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2213                 cifs_buf_release(iov[0].iov_base);
2214
2215         /* Note: On -EAGAIN error only caller can retry on handle based calls
2216                 since file handle passed in no longer valid */
2217
2218         return rc;
2219 }
2220
2221 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2222                const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2223                const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2224 {
2225         int rc = 0;
2226         LOCK_REQ *pSMB = NULL;
2227         struct kvec iov[2];
2228         int resp_buf_type;
2229         __u16 count;
2230
2231         cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
2232
2233         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2234         if (rc)
2235                 return rc;
2236
2237         pSMB->Timeout = 0;
2238         pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2239         pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2240         pSMB->LockType = lock_type;
2241         pSMB->AndXCommand = 0xFF; /* none */
2242         pSMB->Fid = netfid; /* netfid stays le */
2243
2244         count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2245         inc_rfc1001_len(pSMB, count);
2246         pSMB->ByteCount = cpu_to_le16(count);
2247
2248         iov[0].iov_base = (char *)pSMB;
2249         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2250                          (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2251         iov[1].iov_base = (char *)buf;
2252         iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2253
2254         cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2255         rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2256         if (rc)
2257                 cFYI(1, "Send error in cifs_lockv = %d", rc);
2258
2259         return rc;
2260 }
2261
2262 int
2263 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2264             const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2265             const __u64 offset, const __u32 numUnlock,
2266             const __u32 numLock, const __u8 lockType,
2267             const bool waitFlag, const __u8 oplock_level)
2268 {
2269         int rc = 0;
2270         LOCK_REQ *pSMB = NULL;
2271 /*      LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2272         int bytes_returned;
2273         int flags = 0;
2274         __u16 count;
2275
2276         cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
2277         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2278
2279         if (rc)
2280                 return rc;
2281
2282         if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2283                 /* no response expected */
2284                 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
2285                 pSMB->Timeout = 0;
2286         } else if (waitFlag) {
2287                 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2288                 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2289         } else {
2290                 pSMB->Timeout = 0;
2291         }
2292
2293         pSMB->NumberOfLocks = cpu_to_le16(numLock);
2294         pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2295         pSMB->LockType = lockType;
2296         pSMB->OplockLevel = oplock_level;
2297         pSMB->AndXCommand = 0xFF;       /* none */
2298         pSMB->Fid = smb_file_id; /* netfid stays le */
2299
2300         if ((numLock != 0) || (numUnlock != 0)) {
2301                 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2302                 /* BB where to store pid high? */
2303                 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2304                 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2305                 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2306                 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2307                 count = sizeof(LOCKING_ANDX_RANGE);
2308         } else {
2309                 /* oplock break */
2310                 count = 0;
2311         }
2312         inc_rfc1001_len(pSMB, count);
2313         pSMB->ByteCount = cpu_to_le16(count);
2314
2315         if (waitFlag) {
2316                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2317                         (struct smb_hdr *) pSMB, &bytes_returned);
2318                 cifs_small_buf_release(pSMB);
2319         } else {
2320                 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2321                 /* SMB buffer freed by function above */
2322         }
2323         cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2324         if (rc)
2325                 cFYI(1, "Send error in Lock = %d", rc);
2326
2327         /* Note: On -EAGAIN error only caller can retry on handle based calls
2328         since file handle passed in no longer valid */
2329         return rc;
2330 }
2331
2332 int
2333 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2334                 const __u16 smb_file_id, const __u32 netpid,
2335                 const loff_t start_offset, const __u64 len,
2336                 struct file_lock *pLockData, const __u16 lock_type,
2337                 const bool waitFlag)
2338 {
2339         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2340         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2341         struct cifs_posix_lock *parm_data;
2342         int rc = 0;
2343         int timeout = 0;
2344         int bytes_returned = 0;
2345         int resp_buf_type = 0;
2346         __u16 params, param_offset, offset, byte_count, count;
2347         struct kvec iov[1];
2348
2349         cFYI(1, "Posix Lock");
2350
2351         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2352
2353         if (rc)
2354                 return rc;
2355
2356         pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2357
2358         params = 6;
2359         pSMB->MaxSetupCount = 0;
2360         pSMB->Reserved = 0;
2361         pSMB->Flags = 0;
2362         pSMB->Reserved2 = 0;
2363         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2364         offset = param_offset + params;
2365
2366         count = sizeof(struct cifs_posix_lock);
2367         pSMB->MaxParameterCount = cpu_to_le16(2);
2368         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2369         pSMB->SetupCount = 1;
2370         pSMB->Reserved3 = 0;
2371         if (pLockData)
2372                 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2373         else
2374                 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2375         byte_count = 3 /* pad */  + params + count;
2376         pSMB->DataCount = cpu_to_le16(count);
2377         pSMB->ParameterCount = cpu_to_le16(params);
2378         pSMB->TotalDataCount = pSMB->DataCount;
2379         pSMB->TotalParameterCount = pSMB->ParameterCount;
2380         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2381         parm_data = (struct cifs_posix_lock *)
2382                         (((char *) &pSMB->hdr.Protocol) + offset);
2383
2384         parm_data->lock_type = cpu_to_le16(lock_type);
2385         if (waitFlag) {
2386                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2387                 parm_data->lock_flags = cpu_to_le16(1);
2388                 pSMB->Timeout = cpu_to_le32(-1);
2389         } else
2390                 pSMB->Timeout = 0;
2391
2392         parm_data->pid = cpu_to_le32(netpid);
2393         parm_data->start = cpu_to_le64(start_offset);
2394         parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2395
2396         pSMB->DataOffset = cpu_to_le16(offset);
2397         pSMB->Fid = smb_file_id;
2398         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2399         pSMB->Reserved4 = 0;
2400         inc_rfc1001_len(pSMB, byte_count);
2401         pSMB->ByteCount = cpu_to_le16(byte_count);
2402         if (waitFlag) {
2403                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2404                         (struct smb_hdr *) pSMBr, &bytes_returned);
2405         } else {
2406                 iov[0].iov_base = (char *)pSMB;
2407                 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2408                 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2409                                 &resp_buf_type, timeout);
2410                 pSMB = NULL; /* request buf already freed by SendReceive2. Do
2411                                 not try to free it twice below on exit */
2412                 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
2413         }
2414
2415         if (rc) {
2416                 cFYI(1, "Send error in Posix Lock = %d", rc);
2417         } else if (pLockData) {
2418                 /* lock structure can be returned on get */
2419                 __u16 data_offset;
2420                 __u16 data_count;
2421                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2422
2423                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2424                         rc = -EIO;      /* bad smb */
2425                         goto plk_err_exit;
2426                 }
2427                 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2428                 data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2429                 if (data_count < sizeof(struct cifs_posix_lock)) {
2430                         rc = -EIO;
2431                         goto plk_err_exit;
2432                 }
2433                 parm_data = (struct cifs_posix_lock *)
2434                         ((char *)&pSMBr->hdr.Protocol + data_offset);
2435                 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
2436                         pLockData->fl_type = F_UNLCK;
2437                 else {
2438                         if (parm_data->lock_type ==
2439                                         __constant_cpu_to_le16(CIFS_RDLCK))
2440                                 pLockData->fl_type = F_RDLCK;
2441                         else if (parm_data->lock_type ==
2442                                         __constant_cpu_to_le16(CIFS_WRLCK))
2443                                 pLockData->fl_type = F_WRLCK;
2444
2445                         pLockData->fl_start = le64_to_cpu(parm_data->start);
2446                         pLockData->fl_end = pLockData->fl_start +
2447                                         le64_to_cpu(parm_data->length) - 1;
2448                         pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2449                 }
2450         }
2451
2452 plk_err_exit:
2453         if (pSMB)
2454                 cifs_small_buf_release(pSMB);
2455
2456         if (resp_buf_type == CIFS_SMALL_BUFFER)
2457                 cifs_small_buf_release(iov[0].iov_base);
2458         else if (resp_buf_type == CIFS_LARGE_BUFFER)
2459                 cifs_buf_release(iov[0].iov_base);
2460
2461         /* Note: On -EAGAIN error only caller can retry on handle based calls
2462            since file handle passed in no longer valid */
2463
2464         return rc;
2465 }
2466
2467
2468 int
2469 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2470 {
2471         int rc = 0;
2472         CLOSE_REQ *pSMB = NULL;
2473         cFYI(1, "In CIFSSMBClose");
2474
2475 /* do not retry on dead session on close */
2476         rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2477         if (rc == -EAGAIN)
2478                 return 0;
2479         if (rc)
2480                 return rc;
2481
2482         pSMB->FileID = (__u16) smb_file_id;
2483         pSMB->LastWriteTime = 0xFFFFFFFF;
2484         pSMB->ByteCount = 0;
2485         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2486         cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2487         if (rc) {
2488                 if (rc != -EINTR) {
2489                         /* EINTR is expected when user ctl-c to kill app */
2490                         cERROR(1, "Send error in Close = %d", rc);
2491                 }
2492         }
2493
2494         /* Since session is dead, file will be closed on server already */
2495         if (rc == -EAGAIN)
2496                 rc = 0;
2497
2498         return rc;
2499 }
2500
2501 int
2502 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2503 {
2504         int rc = 0;
2505         FLUSH_REQ *pSMB = NULL;
2506         cFYI(1, "In CIFSSMBFlush");
2507
2508         rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2509         if (rc)
2510                 return rc;
2511
2512         pSMB->FileID = (__u16) smb_file_id;
2513         pSMB->ByteCount = 0;
2514         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2515         cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2516         if (rc)
2517                 cERROR(1, "Send error in Flush = %d", rc);
2518
2519         return rc;
2520 }
2521
2522 int
2523 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2524               const char *from_name, const char *to_name,
2525               struct cifs_sb_info *cifs_sb)
2526 {
2527         int rc = 0;
2528         RENAME_REQ *pSMB = NULL;
2529         RENAME_RSP *pSMBr = NULL;
2530         int bytes_returned;
2531         int name_len, name_len2;
2532         __u16 count;
2533         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
2534
2535         cFYI(1, "In CIFSSMBRename");
2536 renameRetry:
2537         rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2538                       (void **) &pSMBr);
2539         if (rc)
2540                 return rc;
2541
2542         pSMB->BufferFormat = 0x04;
2543         pSMB->SearchAttributes =
2544             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2545                         ATTR_DIRECTORY);
2546
2547         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2548                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2549                                               from_name, PATH_MAX,
2550                                               cifs_sb->local_nls, remap);
2551                 name_len++;     /* trailing null */
2552                 name_len *= 2;
2553                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2554         /* protocol requires ASCII signature byte on Unicode string */
2555                 pSMB->OldFileName[name_len + 1] = 0x00;
2556                 name_len2 =
2557                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2558                                        to_name, PATH_MAX, cifs_sb->local_nls,
2559                                        remap);
2560                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2561                 name_len2 *= 2; /* convert to bytes */
2562         } else {        /* BB improve the check for buffer overruns BB */
2563                 name_len = strnlen(from_name, PATH_MAX);
2564                 name_len++;     /* trailing null */
2565                 strncpy(pSMB->OldFileName, from_name, name_len);
2566                 name_len2 = strnlen(to_name, PATH_MAX);
2567                 name_len2++;    /* trailing null */
2568                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2569                 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2570                 name_len2++;    /* trailing null */
2571                 name_len2++;    /* signature byte */
2572         }
2573
2574         count = 1 /* 1st signature byte */  + name_len + name_len2;
2575         inc_rfc1001_len(pSMB, count);
2576         pSMB->ByteCount = cpu_to_le16(count);
2577
2578         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2579                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2580         cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2581         if (rc)
2582                 cFYI(1, "Send error in rename = %d", rc);
2583
2584         cifs_buf_release(pSMB);
2585
2586         if (rc == -EAGAIN)
2587                 goto renameRetry;
2588
2589         return rc;
2590 }
2591
2592 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2593                 int netfid, const char *target_name,
2594                 const struct nls_table *nls_codepage, int remap)
2595 {
2596         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2597         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2598         struct set_file_rename *rename_info;
2599         char *data_offset;
2600         char dummy_string[30];
2601         int rc = 0;
2602         int bytes_returned = 0;
2603         int len_of_str;
2604         __u16 params, param_offset, offset, count, byte_count;
2605
2606         cFYI(1, "Rename to File by handle");
2607         rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2608                         (void **) &pSMBr);
2609         if (rc)
2610                 return rc;
2611
2612         params = 6;
2613         pSMB->MaxSetupCount = 0;
2614         pSMB->Reserved = 0;
2615         pSMB->Flags = 0;
2616         pSMB->Timeout = 0;
2617         pSMB->Reserved2 = 0;
2618         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2619         offset = param_offset + params;
2620
2621         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2622         rename_info = (struct set_file_rename *) data_offset;
2623         pSMB->MaxParameterCount = cpu_to_le16(2);
2624         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2625         pSMB->SetupCount = 1;
2626         pSMB->Reserved3 = 0;
2627         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2628         byte_count = 3 /* pad */  + params;
2629         pSMB->ParameterCount = cpu_to_le16(params);
2630         pSMB->TotalParameterCount = pSMB->ParameterCount;
2631         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2632         pSMB->DataOffset = cpu_to_le16(offset);
2633         /* construct random name ".cifs_tmp<inodenum><mid>" */
2634         rename_info->overwrite = cpu_to_le32(1);
2635         rename_info->root_fid  = 0;
2636         /* unicode only call */
2637         if (target_name == NULL) {
2638                 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2639                 len_of_str =
2640                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2641                                         dummy_string, 24, nls_codepage, remap);
2642         } else {
2643                 len_of_str =
2644                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2645                                         target_name, PATH_MAX, nls_codepage,
2646                                         remap);
2647         }
2648         rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2649         count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2650         byte_count += count;
2651         pSMB->DataCount = cpu_to_le16(count);
2652         pSMB->TotalDataCount = pSMB->DataCount;
2653         pSMB->Fid = netfid;
2654         pSMB->InformationLevel =
2655                 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2656         pSMB->Reserved4 = 0;
2657         inc_rfc1001_len(pSMB, byte_count);
2658         pSMB->ByteCount = cpu_to_le16(byte_count);
2659         rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2660                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2661         cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2662         if (rc)
2663                 cFYI(1, "Send error in Rename (by file handle) = %d", rc);
2664
2665         cifs_buf_release(pSMB);
2666
2667         /* Note: On -EAGAIN error only caller can retry on handle based calls
2668                 since file handle passed in no longer valid */
2669
2670         return rc;
2671 }
2672
2673 int
2674 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2675             const char *fromName, const __u16 target_tid, const char *toName,
2676             const int flags, const struct nls_table *nls_codepage, int remap)
2677 {
2678         int rc = 0;
2679         COPY_REQ *pSMB = NULL;
2680         COPY_RSP *pSMBr = NULL;
2681         int bytes_returned;
2682         int name_len, name_len2;
2683         __u16 count;
2684
2685         cFYI(1, "In CIFSSMBCopy");
2686 copyRetry:
2687         rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2688                         (void **) &pSMBr);
2689         if (rc)
2690                 return rc;
2691
2692         pSMB->BufferFormat = 0x04;
2693         pSMB->Tid2 = target_tid;
2694
2695         pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2696
2697         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2698                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2699                                               fromName, PATH_MAX, nls_codepage,
2700                                               remap);
2701                 name_len++;     /* trailing null */
2702                 name_len *= 2;
2703                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2704                 /* protocol requires ASCII signature byte on Unicode string */
2705                 pSMB->OldFileName[name_len + 1] = 0x00;
2706                 name_len2 =
2707                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2708                                        toName, PATH_MAX, nls_codepage, remap);
2709                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2710                 name_len2 *= 2; /* convert to bytes */
2711         } else {        /* BB improve the check for buffer overruns BB */
2712                 name_len = strnlen(fromName, PATH_MAX);
2713                 name_len++;     /* trailing null */
2714                 strncpy(pSMB->OldFileName, fromName, name_len);
2715                 name_len2 = strnlen(toName, PATH_MAX);
2716                 name_len2++;    /* trailing null */
2717                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2718                 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
2719                 name_len2++;    /* trailing null */
2720                 name_len2++;    /* signature byte */
2721         }
2722
2723         count = 1 /* 1st signature byte */  + name_len + name_len2;
2724         inc_rfc1001_len(pSMB, count);
2725         pSMB->ByteCount = cpu_to_le16(count);
2726
2727         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2728                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2729         if (rc) {
2730                 cFYI(1, "Send error in copy = %d with %d files copied",
2731                         rc, le16_to_cpu(pSMBr->CopyCount));
2732         }
2733         cifs_buf_release(pSMB);
2734
2735         if (rc == -EAGAIN)
2736                 goto copyRetry;
2737
2738         return rc;
2739 }
2740
2741 int
2742 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2743                       const char *fromName, const char *toName,
2744                       const struct nls_table *nls_codepage)
2745 {
2746         TRANSACTION2_SPI_REQ *pSMB = NULL;
2747         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2748         char *data_offset;
2749         int name_len;
2750         int name_len_target;
2751         int rc = 0;
2752         int bytes_returned = 0;
2753         __u16 params, param_offset, offset, byte_count;
2754
2755         cFYI(1, "In Symlink Unix style");
2756 createSymLinkRetry:
2757         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2758                       (void **) &pSMBr);
2759         if (rc)
2760                 return rc;
2761
2762         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2763                 name_len =
2764                     cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
2765                                     /* find define for this maxpathcomponent */
2766                                     PATH_MAX, nls_codepage);
2767                 name_len++;     /* trailing null */
2768                 name_len *= 2;
2769
2770         } else {        /* BB improve the check for buffer overruns BB */
2771                 name_len = strnlen(fromName, PATH_MAX);
2772                 name_len++;     /* trailing null */
2773                 strncpy(pSMB->FileName, fromName, name_len);
2774         }
2775         params = 6 + name_len;
2776         pSMB->MaxSetupCount = 0;
2777         pSMB->Reserved = 0;
2778         pSMB->Flags = 0;
2779         pSMB->Timeout = 0;
2780         pSMB->Reserved2 = 0;
2781         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2782                                 InformationLevel) - 4;
2783         offset = param_offset + params;
2784
2785         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2786         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2787                 name_len_target =
2788                     cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
2789                                     /* find define for this maxpathcomponent */
2790                                     , nls_codepage);
2791                 name_len_target++;      /* trailing null */
2792                 name_len_target *= 2;
2793         } else {        /* BB improve the check for buffer overruns BB */
2794                 name_len_target = strnlen(toName, PATH_MAX);
2795                 name_len_target++;      /* trailing null */
2796                 strncpy(data_offset, toName, name_len_target);
2797         }
2798
2799         pSMB->MaxParameterCount = cpu_to_le16(2);
2800         /* BB find exact max on data count below from sess */
2801         pSMB->MaxDataCount = cpu_to_le16(1000);
2802         pSMB->SetupCount = 1;
2803         pSMB->Reserved3 = 0;
2804         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2805         byte_count = 3 /* pad */  + params + name_len_target;
2806         pSMB->DataCount = cpu_to_le16(name_len_target);
2807         pSMB->ParameterCount = cpu_to_le16(params);
2808         pSMB->TotalDataCount = pSMB->DataCount;
2809         pSMB->TotalParameterCount = pSMB->ParameterCount;
2810         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2811         pSMB->DataOffset = cpu_to_le16(offset);
2812         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2813         pSMB->Reserved4 = 0;
2814         inc_rfc1001_len(pSMB, byte_count);
2815         pSMB->ByteCount = cpu_to_le16(byte_count);
2816         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2817                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2818         cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2819         if (rc)
2820                 cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
2821
2822         cifs_buf_release(pSMB);
2823
2824         if (rc == -EAGAIN)
2825                 goto createSymLinkRetry;
2826
2827         return rc;
2828 }
2829
2830 int
2831 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2832                        const char *fromName, const char *toName,
2833                        const struct nls_table *nls_codepage, int remap)
2834 {
2835         TRANSACTION2_SPI_REQ *pSMB = NULL;
2836         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2837         char *data_offset;
2838         int name_len;
2839         int name_len_target;
2840         int rc = 0;
2841         int bytes_returned = 0;
2842         __u16 params, param_offset, offset, byte_count;
2843
2844         cFYI(1, "In Create Hard link Unix style");
2845 createHardLinkRetry:
2846         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2847                       (void **) &pSMBr);
2848         if (rc)
2849                 return rc;
2850
2851         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2852                 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2853                                               PATH_MAX, nls_codepage, remap);
2854                 name_len++;     /* trailing null */
2855                 name_len *= 2;
2856
2857         } else {        /* BB improve the check for buffer overruns BB */
2858                 name_len = strnlen(toName, PATH_MAX);
2859                 name_len++;     /* trailing null */
2860                 strncpy(pSMB->FileName, toName, name_len);
2861         }
2862         params = 6 + name_len;
2863         pSMB->MaxSetupCount = 0;
2864         pSMB->Reserved = 0;
2865         pSMB->Flags = 0;
2866         pSMB->Timeout = 0;
2867         pSMB->Reserved2 = 0;
2868         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2869                                 InformationLevel) - 4;
2870         offset = param_offset + params;
2871
2872         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
2873         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2874                 name_len_target =
2875                     cifsConvertToUTF16((__le16 *) data_offset, fromName,
2876                                        PATH_MAX, nls_codepage, remap);
2877                 name_len_target++;      /* trailing null */
2878                 name_len_target *= 2;
2879         } else {        /* BB improve the check for buffer overruns BB */
2880                 name_len_target = strnlen(fromName, PATH_MAX);
2881                 name_len_target++;      /* trailing null */
2882                 strncpy(data_offset, fromName, name_len_target);
2883         }
2884
2885         pSMB->MaxParameterCount = cpu_to_le16(2);
2886         /* BB find exact max on data count below from sess*/
2887         pSMB->MaxDataCount = cpu_to_le16(1000);
2888         pSMB->SetupCount = 1;
2889         pSMB->Reserved3 = 0;
2890         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2891         byte_count = 3 /* pad */  + params + name_len_target;
2892         pSMB->ParameterCount = cpu_to_le16(params);
2893         pSMB->TotalParameterCount = pSMB->ParameterCount;
2894         pSMB->DataCount = cpu_to_le16(name_len_target);
2895         pSMB->TotalDataCount = pSMB->DataCount;
2896         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2897         pSMB->DataOffset = cpu_to_le16(offset);
2898         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2899         pSMB->Reserved4 = 0;
2900         inc_rfc1001_len(pSMB, byte_count);
2901         pSMB->ByteCount = cpu_to_le16(byte_count);
2902         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2903                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2904         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2905         if (rc)
2906                 cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
2907
2908         cifs_buf_release(pSMB);
2909         if (rc == -EAGAIN)
2910                 goto createHardLinkRetry;
2911
2912         return rc;
2913 }
2914
2915 int
2916 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2917                    const char *from_name, const char *to_name,
2918                    struct cifs_sb_info *cifs_sb)
2919 {
2920         int rc = 0;
2921         NT_RENAME_REQ *pSMB = NULL;
2922         RENAME_RSP *pSMBr = NULL;
2923         int bytes_returned;
2924         int name_len, name_len2;
2925         __u16 count;
2926         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
2927
2928         cFYI(1, "In CIFSCreateHardLink");
2929 winCreateHardLinkRetry:
2930
2931         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2932                       (void **) &pSMBr);
2933         if (rc)
2934                 return rc;
2935
2936         pSMB->SearchAttributes =
2937             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2938                         ATTR_DIRECTORY);
2939         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2940         pSMB->ClusterCount = 0;
2941
2942         pSMB->BufferFormat = 0x04;
2943
2944         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2945                 name_len =
2946                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2947                                        PATH_MAX, cifs_sb->local_nls, remap);
2948                 name_len++;     /* trailing null */
2949                 name_len *= 2;
2950
2951                 /* protocol specifies ASCII buffer format (0x04) for unicode */
2952                 pSMB->OldFileName[name_len] = 0x04;
2953                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2954                 name_len2 =
2955                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2956                                        to_name, PATH_MAX, cifs_sb->local_nls,
2957                                        remap);
2958                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2959                 name_len2 *= 2; /* convert to bytes */
2960         } else {        /* BB improve the check for buffer overruns BB */
2961                 name_len = strnlen(from_name, PATH_MAX);
2962                 name_len++;     /* trailing null */
2963                 strncpy(pSMB->OldFileName, from_name, name_len);
2964                 name_len2 = strnlen(to_name, PATH_MAX);
2965                 name_len2++;    /* trailing null */
2966                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
2967                 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
2968                 name_len2++;    /* trailing null */
2969                 name_len2++;    /* signature byte */
2970         }
2971
2972         count = 1 /* string type byte */  + name_len + name_len2;
2973         inc_rfc1001_len(pSMB, count);
2974         pSMB->ByteCount = cpu_to_le16(count);
2975
2976         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2977                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2978         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2979         if (rc)
2980                 cFYI(1, "Send error in hard link (NT rename) = %d", rc);
2981
2982         cifs_buf_release(pSMB);
2983         if (rc == -EAGAIN)
2984                 goto winCreateHardLinkRetry;
2985
2986         return rc;
2987 }
2988
2989 int
2990 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2991                         const unsigned char *searchName, char **symlinkinfo,
2992                         const struct nls_table *nls_codepage)
2993 {
2994 /* SMB_QUERY_FILE_UNIX_LINK */
2995         TRANSACTION2_QPI_REQ *pSMB = NULL;
2996         TRANSACTION2_QPI_RSP *pSMBr = NULL;
2997         int rc = 0;
2998         int bytes_returned;
2999         int name_len;
3000         __u16 params, byte_count;
3001         char *data_start;
3002
3003         cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
3004
3005 querySymLinkRetry:
3006         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3007                       (void **) &pSMBr);
3008         if (rc)
3009                 return rc;
3010
3011         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3012                 name_len =
3013                         cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
3014                                         PATH_MAX, nls_codepage);
3015                 name_len++;     /* trailing null */
3016                 name_len *= 2;
3017         } else {        /* BB improve the check for buffer overruns BB */
3018                 name_len = strnlen(searchName, PATH_MAX);
3019                 name_len++;     /* trailing null */
3020                 strncpy(pSMB->FileName, searchName, name_len);
3021         }
3022
3023         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3024         pSMB->TotalDataCount = 0;
3025         pSMB->MaxParameterCount = cpu_to_le16(2);
3026         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3027         pSMB->MaxSetupCount = 0;
3028         pSMB->Reserved = 0;
3029         pSMB->Flags = 0;
3030         pSMB->Timeout = 0;
3031         pSMB->Reserved2 = 0;
3032         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3033         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3034         pSMB->DataCount = 0;
3035         pSMB->DataOffset = 0;
3036         pSMB->SetupCount = 1;
3037         pSMB->Reserved3 = 0;
3038         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3039         byte_count = params + 1 /* pad */ ;
3040         pSMB->TotalParameterCount = cpu_to_le16(params);
3041         pSMB->ParameterCount = pSMB->TotalParameterCount;
3042         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3043         pSMB->Reserved4 = 0;
3044         inc_rfc1001_len(pSMB, byte_count);
3045         pSMB->ByteCount = cpu_to_le16(byte_count);
3046
3047         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3048                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3049         if (rc) {
3050                 cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
3051         } else {
3052                 /* decode response */
3053
3054                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3055                 /* BB also check enough total bytes returned */
3056                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3057                         rc = -EIO;
3058                 else {
3059                         bool is_unicode;
3060                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3061
3062                         data_start = ((char *) &pSMBr->hdr.Protocol) +
3063                                            le16_to_cpu(pSMBr->t2.DataOffset);
3064
3065                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3066                                 is_unicode = true;
3067                         else
3068                                 is_unicode = false;
3069
3070                         /* BB FIXME investigate remapping reserved chars here */
3071                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
3072                                         count, is_unicode, nls_codepage);
3073                         if (!*symlinkinfo)
3074                                 rc = -ENOMEM;
3075                 }
3076         }
3077         cifs_buf_release(pSMB);
3078         if (rc == -EAGAIN)
3079                 goto querySymLinkRetry;
3080         return rc;
3081 }
3082
3083 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3084 /*
3085  *      Recent Windows versions now create symlinks more frequently
3086  *      and they use the "reparse point" mechanism below.  We can of course
3087  *      do symlinks nicely to Samba and other servers which support the
3088  *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3089  *      "MF" symlinks optionally, but for recent Windows we really need to
3090  *      reenable the code below and fix the cifs_symlink callers to handle this.
3091  *      In the interim this code has been moved to its own config option so
3092  *      it is not compiled in by default until callers fixed up and more tested.
3093  */
3094 int
3095 CIFSSMBQueryReparseLinkInfo(const unsigned int xid, struct cifs_tcon *tcon,
3096                         const unsigned char *searchName,
3097                         char *symlinkinfo, const int buflen, __u16 fid,
3098                         const struct nls_table *nls_codepage)
3099 {
3100         int rc = 0;
3101         int bytes_returned;
3102         struct smb_com_transaction_ioctl_req *pSMB;
3103         struct smb_com_transaction_ioctl_rsp *pSMBr;
3104
3105         cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
3106         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3107                       (void **) &pSMBr);
3108         if (rc)
3109                 return rc;
3110
3111         pSMB->TotalParameterCount = 0 ;
3112         pSMB->TotalDataCount = 0;
3113         pSMB->MaxParameterCount = cpu_to_le32(2);
3114         /* BB find exact data count max from sess structure BB */
3115         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3116         pSMB->MaxSetupCount = 4;
3117         pSMB->Reserved = 0;
3118         pSMB->ParameterOffset = 0;
3119         pSMB->DataCount = 0;
3120         pSMB->DataOffset = 0;
3121         pSMB->SetupCount = 4;
3122         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3123         pSMB->ParameterCount = pSMB->TotalParameterCount;
3124         pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3125         pSMB->IsFsctl = 1; /* FSCTL */
3126         pSMB->IsRootFlag = 0;
3127         pSMB->Fid = fid; /* file handle always le */
3128         pSMB->ByteCount = 0;
3129
3130         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3131                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3132         if (rc) {
3133                 cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
3134         } else {                /* decode response */
3135                 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3136                 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3137                 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3138                         /* BB also check enough total bytes returned */
3139                         rc = -EIO;      /* bad smb */
3140                         goto qreparse_out;
3141                 }
3142                 if (data_count && (data_count < 2048)) {
3143                         char *end_of_smb = 2 /* sizeof byte count */ +
3144                                get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3145
3146                         struct reparse_data *reparse_buf =
3147                                                 (struct reparse_data *)
3148                                                 ((char *)&pSMBr->hdr.Protocol
3149                                                                  + data_offset);
3150                         if ((char *)reparse_buf >= end_of_smb) {
3151                                 rc = -EIO;
3152                                 goto qreparse_out;
3153                         }
3154                         if ((reparse_buf->LinkNamesBuf +
3155                                 reparse_buf->TargetNameOffset +
3156                                 reparse_buf->TargetNameLen) > end_of_smb) {
3157                                 cFYI(1, "reparse buf beyond SMB");
3158                                 rc = -EIO;
3159                                 goto qreparse_out;
3160                         }
3161
3162                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3163                                 cifs_from_ucs2(symlinkinfo, (__le16 *)
3164                                                 (reparse_buf->LinkNamesBuf +
3165                                                 reparse_buf->TargetNameOffset),
3166                                                 buflen,
3167                                                 reparse_buf->TargetNameLen,
3168                                                 nls_codepage, 0);
3169                         } else { /* ASCII names */
3170                                 strncpy(symlinkinfo,
3171                                         reparse_buf->LinkNamesBuf +
3172                                         reparse_buf->TargetNameOffset,
3173                                         min_t(const int, buflen,
3174                                            reparse_buf->TargetNameLen));
3175                         }
3176                 } else {
3177                         rc = -EIO;
3178                         cFYI(1, "Invalid return data count on "
3179                                  "get reparse info ioctl");
3180                 }
3181                 symlinkinfo[buflen] = 0; /* just in case so the caller
3182                                         does not go off the end of the buffer */
3183                 cFYI(1, "readlink result - %s", symlinkinfo);
3184         }
3185
3186 qreparse_out:
3187         cifs_buf_release(pSMB);
3188
3189         /* Note: On -EAGAIN error only caller can retry on handle based calls
3190                 since file handle passed in no longer valid */
3191
3192         return rc;
3193 }
3194 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3195
3196 #ifdef CONFIG_CIFS_POSIX
3197
3198 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3199 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3200                              struct cifs_posix_ace *cifs_ace)
3201 {
3202         /* u8 cifs fields do not need le conversion */
3203         ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3204         ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3205         ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3206         /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
3207
3208         return;
3209 }
3210
3211 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3212 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3213                                const int acl_type, const int size_of_data_area)
3214 {
3215         int size =  0;
3216         int i;
3217         __u16 count;
3218         struct cifs_posix_ace *pACE;
3219         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3220         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3221
3222         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3223                 return -EOPNOTSUPP;
3224
3225         if (acl_type & ACL_TYPE_ACCESS) {
3226                 count = le16_to_cpu(cifs_acl->access_entry_count);
3227                 pACE = &cifs_acl->ace_array[0];
3228                 size = sizeof(struct cifs_posix_acl);
3229                 size += sizeof(struct cifs_posix_ace) * count;
3230                 /* check if we would go beyond end of SMB */
3231                 if (size_of_data_area < size) {
3232                         cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
3233                                 size_of_data_area, size);
3234                         return -EINVAL;
3235                 }
3236         } else if (acl_type & ACL_TYPE_DEFAULT) {
3237                 count = le16_to_cpu(cifs_acl->access_entry_count);
3238                 size = sizeof(struct cifs_posix_acl);
3239                 size += sizeof(struct cifs_posix_ace) * count;
3240 /* skip past access ACEs to get to default ACEs */
3241                 pACE = &cifs_acl->ace_array[count];
3242                 count = le16_to_cpu(cifs_acl->default_entry_count);
3243                 size += sizeof(struct cifs_posix_ace) * count;
3244                 /* check if we would go beyond end of SMB */
3245                 if (size_of_data_area < size)
3246                         return -EINVAL;
3247         } else {
3248                 /* illegal type */
3249                 return -EINVAL;
3250         }
3251
3252         size = posix_acl_xattr_size(count);
3253         if ((buflen == 0) || (local_acl == NULL)) {
3254                 /* used to query ACL EA size */
3255         } else if (size > buflen) {
3256                 return -ERANGE;
3257         } else /* buffer big enough */ {
3258                 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3259                 for (i = 0; i < count ; i++) {
3260                         cifs_convert_ace(&local_acl->a_entries[i], pACE);
3261                         pACE++;
3262                 }
3263         }
3264         return size;
3265 }
3266
3267 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3268                                      const posix_acl_xattr_entry *local_ace)
3269 {
3270         __u16 rc = 0; /* 0 = ACL converted ok */
3271
3272         cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3273         cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
3274         /* BB is there a better way to handle the large uid? */
3275         if (local_ace->e_id == cpu_to_le32(-1)) {
3276         /* Probably no need to le convert -1 on any arch but can not hurt */
3277                 cifs_ace->cifs_uid = cpu_to_le64(-1);
3278         } else
3279                 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3280         /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
3281         return rc;
3282 }
3283
3284 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3285 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3286                                const int buflen, const int acl_type)
3287 {
3288         __u16 rc = 0;
3289         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3290         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3291         int count;
3292         int i;
3293
3294         if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3295                 return 0;
3296
3297         count = posix_acl_xattr_count((size_t)buflen);
3298         cFYI(1, "setting acl with %d entries from buf of length %d and "
3299                 "version of %d",
3300                 count, buflen, le32_to_cpu(local_acl->a_version));
3301         if (le32_to_cpu(local_acl->a_version) != 2) {
3302                 cFYI(1, "unknown POSIX ACL version %d",
3303                      le32_to_cpu(local_acl->a_version));
3304                 return 0;
3305         }
3306         cifs_acl->version = cpu_to_le16(1);
3307         if (acl_type == ACL_TYPE_ACCESS)
3308                 cifs_acl->access_entry_count = cpu_to_le16(count);
3309         else if (acl_type == ACL_TYPE_DEFAULT)
3310                 cifs_acl->default_entry_count = cpu_to_le16(count);
3311         else {
3312                 cFYI(1, "unknown ACL type %d", acl_type);
3313                 return 0;
3314         }
3315         for (i = 0; i < count; i++) {
3316                 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3317                                         &local_acl->a_entries[i]);
3318                 if (rc != 0) {
3319                         /* ACE not converted */
3320                         break;
3321                 }
3322         }
3323         if (rc == 0) {
3324                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3325                 rc += sizeof(struct cifs_posix_acl);
3326                 /* BB add check to make sure ACL does not overflow SMB */
3327         }
3328         return rc;
3329 }
3330
3331 int
3332 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3333                    const unsigned char *searchName,
3334                    char *acl_inf, const int buflen, const int acl_type,
3335                    const struct nls_table *nls_codepage, int remap)
3336 {
3337 /* SMB_QUERY_POSIX_ACL */
3338         TRANSACTION2_QPI_REQ *pSMB = NULL;
3339         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3340         int rc = 0;
3341         int bytes_returned;
3342         int name_len;
3343         __u16 params, byte_count;
3344
3345         cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
3346
3347 queryAclRetry:
3348         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3349                 (void **) &pSMBr);
3350         if (rc)
3351                 return rc;
3352
3353         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3354                 name_len =
3355                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3356                                            searchName, PATH_MAX, nls_codepage,
3357                                            remap);
3358                 name_len++;     /* trailing null */
3359                 name_len *= 2;
3360                 pSMB->FileName[name_len] = 0;
3361                 pSMB->FileName[name_len+1] = 0;
3362         } else {        /* BB improve the check for buffer overruns BB */
3363                 name_len = strnlen(searchName, PATH_MAX);
3364                 name_len++;     /* trailing null */
3365                 strncpy(pSMB->FileName, searchName, name_len);
3366         }
3367
3368         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3369         pSMB->TotalDataCount = 0;
3370         pSMB->MaxParameterCount = cpu_to_le16(2);
3371         /* BB find exact max data count below from sess structure BB */
3372         pSMB->MaxDataCount = cpu_to_le16(4000);
3373         pSMB->MaxSetupCount = 0;
3374         pSMB->Reserved = 0;
3375         pSMB->Flags = 0;
3376         pSMB->Timeout = 0;
3377         pSMB->Reserved2 = 0;
3378         pSMB->ParameterOffset = cpu_to_le16(
3379                 offsetof(struct smb_com_transaction2_qpi_req,
3380                          InformationLevel) - 4);
3381         pSMB->DataCount = 0;
3382         pSMB->DataOffset = 0;
3383         pSMB->SetupCount = 1;
3384         pSMB->Reserved3 = 0;
3385         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3386         byte_count = params + 1 /* pad */ ;
3387         pSMB->TotalParameterCount = cpu_to_le16(params);
3388         pSMB->ParameterCount = pSMB->TotalParameterCount;
3389         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3390         pSMB->Reserved4 = 0;
3391         inc_rfc1001_len(pSMB, byte_count);
3392         pSMB->ByteCount = cpu_to_le16(byte_count);
3393
3394         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3395                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3396         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3397         if (rc) {
3398                 cFYI(1, "Send error in Query POSIX ACL = %d", rc);
3399         } else {
3400                 /* decode response */
3401
3402                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3403                 /* BB also check enough total bytes returned */
3404                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3405                         rc = -EIO;      /* bad smb */
3406                 else {
3407                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3408                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3409                         rc = cifs_copy_posix_acl(acl_inf,
3410                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3411                                 buflen, acl_type, count);
3412                 }
3413         }
3414         cifs_buf_release(pSMB);
3415         if (rc == -EAGAIN)
3416                 goto queryAclRetry;
3417         return rc;
3418 }
3419
3420 int
3421 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3422                    const unsigned char *fileName,
3423                    const char *local_acl, const int buflen,
3424                    const int acl_type,
3425                    const struct nls_table *nls_codepage, int remap)
3426 {
3427         struct smb_com_transaction2_spi_req *pSMB = NULL;
3428         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3429         char *parm_data;
3430         int name_len;
3431         int rc = 0;
3432         int bytes_returned = 0;
3433         __u16 params, byte_count, data_count, param_offset, offset;
3434
3435         cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
3436 setAclRetry:
3437         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3438                       (void **) &pSMBr);
3439         if (rc)
3440                 return rc;
3441         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3442                 name_len =
3443                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3444                                            PATH_MAX, nls_codepage, remap);
3445                 name_len++;     /* trailing null */
3446                 name_len *= 2;
3447         } else {        /* BB improve the check for buffer overruns BB */
3448                 name_len = strnlen(fileName, PATH_MAX);
3449                 name_len++;     /* trailing null */
3450                 strncpy(pSMB->FileName, fileName, name_len);
3451         }
3452         params = 6 + name_len;
3453         pSMB->MaxParameterCount = cpu_to_le16(2);
3454         /* BB find max SMB size from sess */
3455         pSMB->MaxDataCount = cpu_to_le16(1000);
3456         pSMB->MaxSetupCount = 0;
3457         pSMB->Reserved = 0;
3458         pSMB->Flags = 0;
3459         pSMB->Timeout = 0;
3460         pSMB->Reserved2 = 0;
3461         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3462                                 InformationLevel) - 4;
3463         offset = param_offset + params;
3464         parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3465         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3466
3467         /* convert to on the wire format for POSIX ACL */
3468         data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3469
3470         if (data_count == 0) {
3471                 rc = -EOPNOTSUPP;
3472                 goto setACLerrorExit;
3473         }
3474         pSMB->DataOffset = cpu_to_le16(offset);
3475         pSMB->SetupCount = 1;
3476         pSMB->Reserved3 = 0;
3477         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3478         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3479         byte_count = 3 /* pad */  + params + data_count;
3480         pSMB->DataCount = cpu_to_le16(data_count);
3481         pSMB->TotalDataCount = pSMB->DataCount;
3482         pSMB->ParameterCount = cpu_to_le16(params);
3483         pSMB->TotalParameterCount = pSMB->ParameterCount;
3484         pSMB->Reserved4 = 0;
3485         inc_rfc1001_len(pSMB, byte_count);
3486         pSMB->ByteCount = cpu_to_le16(byte_count);
3487         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3488                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3489         if (rc)
3490                 cFYI(1, "Set POSIX ACL returned %d", rc);
3491
3492 setACLerrorExit:
3493         cifs_buf_release(pSMB);
3494         if (rc == -EAGAIN)
3495                 goto setAclRetry;
3496         return rc;
3497 }
3498
3499 /* BB fix tabs in this function FIXME BB */
3500 int
3501 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3502                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3503 {
3504         int rc = 0;
3505         struct smb_t2_qfi_req *pSMB = NULL;
3506         struct smb_t2_qfi_rsp *pSMBr = NULL;
3507         int bytes_returned;
3508         __u16 params, byte_count;
3509
3510         cFYI(1, "In GetExtAttr");
3511         if (tcon == NULL)
3512                 return -ENODEV;
3513
3514 GetExtAttrRetry:
3515         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3516                         (void **) &pSMBr);
3517         if (rc)
3518                 return rc;
3519
3520         params = 2 /* level */ + 2 /* fid */;
3521         pSMB->t2.TotalDataCount = 0;
3522         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3523         /* BB find exact max data count below from sess structure BB */
3524         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3525         pSMB->t2.MaxSetupCount = 0;
3526         pSMB->t2.Reserved = 0;
3527         pSMB->t2.Flags = 0;
3528         pSMB->t2.Timeout = 0;
3529         pSMB->t2.Reserved2 = 0;
3530         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3531                                                Fid) - 4);
3532         pSMB->t2.DataCount = 0;
3533         pSMB->t2.DataOffset = 0;
3534         pSMB->t2.SetupCount = 1;
3535         pSMB->t2.Reserved3 = 0;
3536         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3537         byte_count = params + 1 /* pad */ ;
3538         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3539         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3540         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3541         pSMB->Pad = 0;
3542         pSMB->Fid = netfid;
3543         inc_rfc1001_len(pSMB, byte_count);
3544         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3545
3546         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3547                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3548         if (rc) {
3549                 cFYI(1, "error %d in GetExtAttr", rc);
3550         } else {
3551                 /* decode response */
3552                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3553                 /* BB also check enough total bytes returned */
3554                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3555                         /* If rc should we check for EOPNOSUPP and
3556                            disable the srvino flag? or in caller? */
3557                         rc = -EIO;      /* bad smb */
3558                 else {
3559                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3560                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3561                         struct file_chattr_info *pfinfo;
3562                         /* BB Do we need a cast or hash here ? */
3563                         if (count != 16) {
3564                                 cFYI(1, "Illegal size ret in GetExtAttr");
3565                                 rc = -EIO;
3566                                 goto GetExtAttrOut;
3567                         }
3568                         pfinfo = (struct file_chattr_info *)
3569                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3570                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3571                         *pMask = le64_to_cpu(pfinfo->mask);
3572                 }
3573         }
3574 GetExtAttrOut:
3575         cifs_buf_release(pSMB);
3576         if (rc == -EAGAIN)
3577                 goto GetExtAttrRetry;
3578         return rc;
3579 }
3580
3581 #endif /* CONFIG_POSIX */
3582
3583 #ifdef CONFIG_CIFS_ACL
3584 /*
3585  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3586  * all NT TRANSACTS that we init here have total parm and data under about 400
3587  * bytes (to fit in small cifs buffer size), which is the case so far, it
3588  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3589  * returned setup area) and MaxParameterCount (returned parms size) must be set
3590  * by caller
3591  */
3592 static int
3593 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3594                    const int parm_len, struct cifs_tcon *tcon,
3595                    void **ret_buf)
3596 {
3597         int rc;
3598         __u32 temp_offset;
3599         struct smb_com_ntransact_req *pSMB;
3600
3601         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3602                                 (void **)&pSMB);
3603         if (rc)
3604                 return rc;
3605         *ret_buf = (void *)pSMB;
3606         pSMB->Reserved = 0;
3607         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3608         pSMB->TotalDataCount  = 0;
3609         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3610         pSMB->ParameterCount = pSMB->TotalParameterCount;
3611         pSMB->DataCount  = pSMB->TotalDataCount;
3612         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3613                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3614         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3615         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3616         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3617         pSMB->SubCommand = cpu_to_le16(sub_command);
3618         return 0;
3619 }
3620
3621 static int
3622 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3623                    __u32 *pparmlen, __u32 *pdatalen)
3624 {
3625         char *end_of_smb;
3626         __u32 data_count, data_offset, parm_count, parm_offset;
3627         struct smb_com_ntransact_rsp *pSMBr;
3628         u16 bcc;
3629
3630         *pdatalen = 0;
3631         *pparmlen = 0;
3632
3633         if (buf == NULL)
3634                 return -EINVAL;
3635
3636         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3637
3638         bcc = get_bcc(&pSMBr->hdr);
3639         end_of_smb = 2 /* sizeof byte count */ + bcc +
3640                         (char *)&pSMBr->ByteCount;
3641
3642         data_offset = le32_to_cpu(pSMBr->DataOffset);
3643         data_count = le32_to_cpu(pSMBr->DataCount);
3644         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3645         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3646
3647         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3648         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3649
3650         /* should we also check that parm and data areas do not overlap? */
3651         if (*ppparm > end_of_smb) {
3652                 cFYI(1, "parms start after end of smb");
3653                 return -EINVAL;
3654         } else if (parm_count + *ppparm > end_of_smb) {
3655                 cFYI(1, "parm end after end of smb");
3656                 return -EINVAL;
3657         } else if (*ppdata > end_of_smb) {
3658                 cFYI(1, "data starts after end of smb");
3659                 return -EINVAL;
3660         } else if (data_count + *ppdata > end_of_smb) {
3661                 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3662                         *ppdata, data_count, (data_count + *ppdata),
3663                         end_of_smb, pSMBr);
3664                 return -EINVAL;
3665         } else if (parm_count + data_count > bcc) {
3666                 cFYI(1, "parm count and data count larger than SMB");
3667                 return -EINVAL;
3668         }
3669         *pdatalen = data_count;
3670         *pparmlen = parm_count;
3671         return 0;
3672 }
3673
3674 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3675 int
3676 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3677                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3678 {
3679         int rc = 0;
3680         int buf_type = 0;
3681         QUERY_SEC_DESC_REQ *pSMB;
3682         struct kvec iov[1];
3683
3684         cFYI(1, "GetCifsACL");
3685
3686         *pbuflen = 0;
3687         *acl_inf = NULL;
3688
3689         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3690                         8 /* parm len */, tcon, (void **) &pSMB);
3691         if (rc)
3692                 return rc;
3693
3694         pSMB->MaxParameterCount = cpu_to_le32(4);
3695         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3696         pSMB->MaxSetupCount = 0;
3697         pSMB->Fid = fid; /* file handle always le */
3698         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3699                                      CIFS_ACL_DACL);
3700         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3701         inc_rfc1001_len(pSMB, 11);
3702         iov[0].iov_base = (char *)pSMB;
3703         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3704
3705         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3706                          0);
3707         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3708         if (rc) {
3709                 cFYI(1, "Send error in QuerySecDesc = %d", rc);
3710         } else {                /* decode response */
3711                 __le32 *parm;
3712                 __u32 parm_len;
3713                 __u32 acl_len;
3714                 struct smb_com_ntransact_rsp *pSMBr;
3715                 char *pdata;
3716
3717 /* validate_nttransact */
3718                 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3719                                         &pdata, &parm_len, pbuflen);
3720                 if (rc)
3721                         goto qsec_out;
3722                 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3723
3724                 cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
3725
3726                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3727                         rc = -EIO;      /* bad smb */
3728                         *pbuflen = 0;
3729                         goto qsec_out;
3730                 }
3731
3732 /* BB check that data area is minimum length and as big as acl_len */
3733
3734                 acl_len = le32_to_cpu(*parm);
3735                 if (acl_len != *pbuflen) {
3736                         cERROR(1, "acl length %d does not match %d",
3737                                    acl_len, *pbuflen);
3738                         if (*pbuflen > acl_len)
3739                                 *pbuflen = acl_len;
3740                 }
3741
3742                 /* check if buffer is big enough for the acl
3743                    header followed by the smallest SID */
3744                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3745                     (*pbuflen >= 64 * 1024)) {
3746                         cERROR(1, "bad acl length %d", *pbuflen);
3747                         rc = -EINVAL;
3748                         *pbuflen = 0;
3749                 } else {
3750                         *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
3751                         if (*acl_inf == NULL) {
3752                                 *pbuflen = 0;
3753                                 rc = -ENOMEM;
3754                         }
3755                         memcpy(*acl_inf, pdata, *pbuflen);
3756                 }
3757         }
3758 qsec_out:
3759         if (buf_type == CIFS_SMALL_BUFFER)
3760                 cifs_small_buf_release(iov[0].iov_base);
3761         else if (buf_type == CIFS_LARGE_BUFFER)
3762                 cifs_buf_release(iov[0].iov_base);
3763 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3764         return rc;
3765 }
3766
3767 int
3768 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3769                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3770 {
3771         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3772         int rc = 0;
3773         int bytes_returned = 0;
3774         SET_SEC_DESC_REQ *pSMB = NULL;
3775         void *pSMBr;
3776
3777 setCifsAclRetry:
3778         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3779         if (rc)
3780                 return rc;
3781
3782         pSMB->MaxSetupCount = 0;
3783         pSMB->Reserved = 0;
3784
3785         param_count = 8;
3786         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3787         data_count = acllen;
3788         data_offset = param_offset + param_count;
3789         byte_count = 3 /* pad */  + param_count;
3790
3791         pSMB->DataCount = cpu_to_le32(data_count);
3792         pSMB->TotalDataCount = pSMB->DataCount;
3793         pSMB->MaxParameterCount = cpu_to_le32(4);
3794         pSMB->MaxDataCount = cpu_to_le32(16384);
3795         pSMB->ParameterCount = cpu_to_le32(param_count);
3796         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3797         pSMB->TotalParameterCount = pSMB->ParameterCount;
3798         pSMB->DataOffset = cpu_to_le32(data_offset);
3799         pSMB->SetupCount = 0;
3800         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3801         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3802
3803         pSMB->Fid = fid; /* file handle always le */
3804         pSMB->Reserved2 = 0;
3805         pSMB->AclFlags = cpu_to_le32(aclflag);
3806
3807         if (pntsd && acllen) {
3808                 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3809                                 data_offset, pntsd, acllen);
3810                 inc_rfc1001_len(pSMB, byte_count + data_count);
3811         } else
3812                 inc_rfc1001_len(pSMB, byte_count);
3813
3814         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3815                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3816
3817         cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3818         if (rc)
3819                 cFYI(1, "Set CIFS ACL returned %d", rc);
3820         cifs_buf_release(pSMB);
3821
3822         if (rc == -EAGAIN)
3823                 goto setCifsAclRetry;
3824
3825         return (rc);
3826 }
3827
3828 #endif /* CONFIG_CIFS_ACL */
3829
3830 /* Legacy Query Path Information call for lookup to old servers such
3831    as Win9x/WinME */
3832 int
3833 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3834                     const char *search_name, FILE_ALL_INFO *data,
3835                     const struct nls_table *nls_codepage, int remap)
3836 {
3837         QUERY_INFORMATION_REQ *pSMB;
3838         QUERY_INFORMATION_RSP *pSMBr;
3839         int rc = 0;
3840         int bytes_returned;
3841         int name_len;
3842
3843         cFYI(1, "In SMBQPath path %s", search_name);
3844 QInfRetry:
3845         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3846                       (void **) &pSMBr);
3847         if (rc)
3848                 return rc;
3849
3850         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3851                 name_len =
3852                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3853                                            search_name, PATH_MAX, nls_codepage,
3854                                            remap);
3855                 name_len++;     /* trailing null */
3856                 name_len *= 2;
3857         } else {
3858                 name_len = strnlen(search_name, PATH_MAX);
3859                 name_len++;     /* trailing null */
3860                 strncpy(pSMB->FileName, search_name, name_len);
3861         }
3862         pSMB->BufferFormat = 0x04;
3863         name_len++; /* account for buffer type byte */
3864         inc_rfc1001_len(pSMB, (__u16)name_len);
3865         pSMB->ByteCount = cpu_to_le16(name_len);
3866
3867         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3868                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3869         if (rc) {
3870                 cFYI(1, "Send error in QueryInfo = %d", rc);
3871         } else if (data) {
3872                 struct timespec ts;
3873                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3874
3875                 /* decode response */
3876                 /* BB FIXME - add time zone adjustment BB */
3877                 memset(data, 0, sizeof(FILE_ALL_INFO));
3878                 ts.tv_nsec = 0;
3879                 ts.tv_sec = time;
3880                 /* decode time fields */
3881                 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3882                 data->LastWriteTime = data->ChangeTime;
3883                 data->LastAccessTime = 0;
3884                 data->AllocationSize =
3885                         cpu_to_le64(le32_to_cpu(pSMBr->size));
3886                 data->EndOfFile = data->AllocationSize;
3887                 data->Attributes =
3888                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
3889         } else
3890                 rc = -EIO; /* bad buffer passed in */
3891
3892         cifs_buf_release(pSMB);
3893
3894         if (rc == -EAGAIN)
3895                 goto QInfRetry;
3896
3897         return rc;
3898 }
3899
3900 int
3901 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3902                  u16 netfid, FILE_ALL_INFO *pFindData)
3903 {
3904         struct smb_t2_qfi_req *pSMB = NULL;
3905         struct smb_t2_qfi_rsp *pSMBr = NULL;
3906         int rc = 0;
3907         int bytes_returned;
3908         __u16 params, byte_count;
3909
3910 QFileInfoRetry:
3911         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3912                       (void **) &pSMBr);
3913         if (rc)
3914                 return rc;
3915
3916         params = 2 /* level */ + 2 /* fid */;
3917         pSMB->t2.TotalDataCount = 0;
3918         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3919         /* BB find exact max data count below from sess structure BB */
3920         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3921         pSMB->t2.MaxSetupCount = 0;
3922         pSMB->t2.Reserved = 0;
3923         pSMB->t2.Flags = 0;
3924         pSMB->t2.Timeout = 0;
3925         pSMB->t2.Reserved2 = 0;
3926         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3927                                                Fid) - 4);
3928         pSMB->t2.DataCount = 0;
3929         pSMB->t2.DataOffset = 0;
3930         pSMB->t2.SetupCount = 1;
3931         pSMB->t2.Reserved3 = 0;
3932         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3933         byte_count = params + 1 /* pad */ ;
3934         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3935         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3936         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3937         pSMB->Pad = 0;
3938         pSMB->Fid = netfid;
3939         inc_rfc1001_len(pSMB, byte_count);
3940
3941         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3942                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3943         if (rc) {
3944                 cFYI(1, "Send error in QPathInfo = %d", rc);
3945         } else {                /* decode response */
3946                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3947
3948                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3949                         rc = -EIO;
3950                 else if (get_bcc(&pSMBr->hdr) < 40)
3951                         rc = -EIO;      /* bad smb */
3952                 else if (pFindData) {
3953                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3954                         memcpy((char *) pFindData,
3955                                (char *) &pSMBr->hdr.Protocol +
3956                                data_offset, sizeof(FILE_ALL_INFO));
3957                 } else
3958                     rc = -ENOMEM;
3959         }
3960         cifs_buf_release(pSMB);
3961         if (rc == -EAGAIN)
3962                 goto QFileInfoRetry;
3963
3964         return rc;
3965 }
3966
3967 int
3968 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3969                  const char *search_name, FILE_ALL_INFO *data,
3970                  int legacy /* old style infolevel */,
3971                  const struct nls_table *nls_codepage, int remap)
3972 {
3973         /* level 263 SMB_QUERY_FILE_ALL_INFO */
3974         TRANSACTION2_QPI_REQ *pSMB = NULL;
3975         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3976         int rc = 0;
3977         int bytes_returned;
3978         int name_len;
3979         __u16 params, byte_count;
3980
3981         /* cFYI(1, "In QPathInfo path %s", search_name); */
3982 QPathInfoRetry:
3983         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3984                       (void **) &pSMBr);
3985         if (rc)
3986                 return rc;
3987
3988         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3989                 name_len =
3990                     cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3991                                        PATH_MAX, nls_codepage, remap);
3992                 name_len++;     /* trailing null */
3993                 name_len *= 2;
3994         } else {        /* BB improve the check for buffer overruns BB */
3995                 name_len = strnlen(search_name, PATH_MAX);
3996                 name_len++;     /* trailing null */
3997                 strncpy(pSMB->FileName, search_name, name_len);
3998         }
3999
4000         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4001         pSMB->TotalDataCount = 0;
4002         pSMB->MaxParameterCount = cpu_to_le16(2);
4003         /* BB find exact max SMB PDU from sess structure BB */
4004         pSMB->MaxDataCount = cpu_to_le16(4000);
4005         pSMB->MaxSetupCount = 0;
4006         pSMB->Reserved = 0;
4007         pSMB->Flags = 0;
4008         pSMB->Timeout = 0;
4009         pSMB->Reserved2 = 0;
4010         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4011         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4012         pSMB->DataCount = 0;
4013         pSMB->DataOffset = 0;
4014         pSMB->SetupCount = 1;
4015         pSMB->Reserved3 = 0;
4016         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4017         byte_count = params + 1 /* pad */ ;
4018         pSMB->TotalParameterCount = cpu_to_le16(params);
4019         pSMB->ParameterCount = pSMB->TotalParameterCount;
4020         if (legacy)
4021                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4022         else
4023                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4024         pSMB->Reserved4 = 0;
4025         inc_rfc1001_len(pSMB, byte_count);
4026         pSMB->ByteCount = cpu_to_le16(byte_count);
4027
4028         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4029                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4030         if (rc) {
4031                 cFYI(1, "Send error in QPathInfo = %d", rc);
4032         } else {                /* decode response */
4033                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4034
4035                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4036                         rc = -EIO;
4037                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4038                         rc = -EIO;      /* bad smb */
4039                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4040                         rc = -EIO;  /* 24 or 26 expected but we do not read
4041                                         last field */
4042                 else if (data) {
4043                         int size;
4044                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4045
4046                         /*
4047                          * On legacy responses we do not read the last field,
4048                          * EAsize, fortunately since it varies by subdialect and
4049                          * also note it differs on Set vs Get, ie two bytes or 4
4050                          * bytes depending but we don't care here.
4051                          */
4052                         if (legacy)
4053                                 size = sizeof(FILE_INFO_STANDARD);
4054                         else
4055                                 size = sizeof(FILE_ALL_INFO);
4056                         memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4057                                data_offset, size);
4058                 } else
4059                     rc = -ENOMEM;
4060         }
4061         cifs_buf_release(pSMB);
4062         if (rc == -EAGAIN)
4063                 goto QPathInfoRetry;
4064
4065         return rc;
4066 }
4067
4068 int
4069 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4070                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4071 {
4072         struct smb_t2_qfi_req *pSMB = NULL;
4073         struct smb_t2_qfi_rsp *pSMBr = NULL;
4074         int rc = 0;
4075         int bytes_returned;
4076         __u16 params, byte_count;
4077
4078 UnixQFileInfoRetry:
4079         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4080                       (void **) &pSMBr);
4081         if (rc)
4082                 return rc;
4083
4084         params = 2 /* level */ + 2 /* fid */;
4085         pSMB->t2.TotalDataCount = 0;
4086         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4087         /* BB find exact max data count below from sess structure BB */
4088         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4089         pSMB->t2.MaxSetupCount = 0;
4090         pSMB->t2.Reserved = 0;
4091         pSMB->t2.Flags = 0;
4092         pSMB->t2.Timeout = 0;
4093         pSMB->t2.Reserved2 = 0;
4094         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4095                                                Fid) - 4);
4096         pSMB->t2.DataCount = 0;
4097         pSMB->t2.DataOffset = 0;
4098         pSMB->t2.SetupCount = 1;
4099         pSMB->t2.Reserved3 = 0;
4100         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4101         byte_count = params + 1 /* pad */ ;
4102         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4103         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4104         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4105         pSMB->Pad = 0;
4106         pSMB->Fid = netfid;
4107         inc_rfc1001_len(pSMB, byte_count);
4108
4109         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4110                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4111         if (rc) {
4112                 cFYI(1, "Send error in QPathInfo = %d", rc);
4113         } else {                /* decode response */
4114                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4115
4116                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4117                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4118                                    "Unix Extensions can be disabled on mount "
4119                                    "by specifying the nosfu mount option.");
4120                         rc = -EIO;      /* bad smb */
4121                 } else {
4122                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4123                         memcpy((char *) pFindData,
4124                                (char *) &pSMBr->hdr.Protocol +
4125                                data_offset,
4126                                sizeof(FILE_UNIX_BASIC_INFO));
4127                 }
4128         }
4129
4130         cifs_buf_release(pSMB);
4131         if (rc == -EAGAIN)
4132                 goto UnixQFileInfoRetry;
4133
4134         return rc;
4135 }
4136
4137 int
4138 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4139                      const unsigned char *searchName,
4140                      FILE_UNIX_BASIC_INFO *pFindData,
4141                      const struct nls_table *nls_codepage, int remap)
4142 {
4143 /* SMB_QUERY_FILE_UNIX_BASIC */
4144         TRANSACTION2_QPI_REQ *pSMB = NULL;
4145         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4146         int rc = 0;
4147         int bytes_returned = 0;
4148         int name_len;
4149         __u16 params, byte_count;
4150
4151         cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4152 UnixQPathInfoRetry:
4153         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4154                       (void **) &pSMBr);
4155         if (rc)
4156                 return rc;
4157
4158         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4159                 name_len =
4160                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4161                                        PATH_MAX, nls_codepage, remap);
4162                 name_len++;     /* trailing null */
4163                 name_len *= 2;
4164         } else {        /* BB improve the check for buffer overruns BB */
4165                 name_len = strnlen(searchName, PATH_MAX);
4166                 name_len++;     /* trailing null */
4167                 strncpy(pSMB->FileName, searchName, name_len);
4168         }
4169
4170         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4171         pSMB->TotalDataCount = 0;
4172         pSMB->MaxParameterCount = cpu_to_le16(2);
4173         /* BB find exact max SMB PDU from sess structure BB */
4174         pSMB->MaxDataCount = cpu_to_le16(4000);
4175         pSMB->MaxSetupCount = 0;
4176         pSMB->Reserved = 0;
4177         pSMB->Flags = 0;
4178         pSMB->Timeout = 0;
4179         pSMB->Reserved2 = 0;
4180         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4181         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4182         pSMB->DataCount = 0;
4183         pSMB->DataOffset = 0;
4184         pSMB->SetupCount = 1;
4185         pSMB->Reserved3 = 0;
4186         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4187         byte_count = params + 1 /* pad */ ;
4188         pSMB->TotalParameterCount = cpu_to_le16(params);
4189         pSMB->ParameterCount = pSMB->TotalParameterCount;
4190         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4191         pSMB->Reserved4 = 0;
4192         inc_rfc1001_len(pSMB, byte_count);
4193         pSMB->ByteCount = cpu_to_le16(byte_count);
4194
4195         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4196                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4197         if (rc) {
4198                 cFYI(1, "Send error in QPathInfo = %d", rc);
4199         } else {                /* decode response */
4200                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4201
4202                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4203                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response. "
4204                                    "Unix Extensions can be disabled on mount "
4205                                    "by specifying the nosfu mount option.");
4206                         rc = -EIO;      /* bad smb */
4207                 } else {
4208                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4209                         memcpy((char *) pFindData,
4210                                (char *) &pSMBr->hdr.Protocol +
4211                                data_offset,
4212                                sizeof(FILE_UNIX_BASIC_INFO));
4213                 }
4214         }
4215         cifs_buf_release(pSMB);
4216         if (rc == -EAGAIN)
4217                 goto UnixQPathInfoRetry;
4218
4219         return rc;
4220 }
4221
4222 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4223 int
4224 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4225               const char *searchName,
4226               const struct nls_table *nls_codepage,
4227               __u16 *pnetfid, __u16 search_flags,
4228               struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4229 {
4230 /* level 257 SMB_ */
4231         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4232         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4233         T2_FFIRST_RSP_PARMS *parms;
4234         int rc = 0;
4235         int bytes_returned = 0;
4236         int name_len;
4237         __u16 params, byte_count;
4238
4239         cFYI(1, "In FindFirst for %s", searchName);
4240
4241 findFirstRetry:
4242         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4243                       (void **) &pSMBr);
4244         if (rc)
4245                 return rc;
4246
4247         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4248                 name_len =
4249                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4250                                        PATH_MAX, nls_codepage, remap);
4251                 /* We can not add the asterik earlier in case
4252                 it got remapped to 0xF03A as if it were part of the
4253                 directory name instead of a wildcard */
4254                 name_len *= 2;
4255                 pSMB->FileName[name_len] = dirsep;
4256                 pSMB->FileName[name_len+1] = 0;
4257                 pSMB->FileName[name_len+2] = '*';
4258                 pSMB->FileName[name_len+3] = 0;
4259                 name_len += 4; /* now the trailing null */
4260                 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4261                 pSMB->FileName[name_len+1] = 0;
4262                 name_len += 2;
4263         } else {        /* BB add check for overrun of SMB buf BB */
4264                 name_len = strnlen(searchName, PATH_MAX);
4265 /* BB fix here and in unicode clause above ie
4266                 if (name_len > buffersize-header)
4267                         free buffer exit; BB */
4268                 strncpy(pSMB->FileName, searchName, name_len);
4269                 pSMB->FileName[name_len] = dirsep;
4270                 pSMB->FileName[name_len+1] = '*';
4271                 pSMB->FileName[name_len+2] = 0;
4272                 name_len += 3;
4273         }
4274
4275         params = 12 + name_len /* includes null */ ;
4276         pSMB->TotalDataCount = 0;       /* no EAs */
4277         pSMB->MaxParameterCount = cpu_to_le16(10);
4278         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4279         pSMB->MaxSetupCount = 0;
4280         pSMB->Reserved = 0;
4281         pSMB->Flags = 0;
4282         pSMB->Timeout = 0;
4283         pSMB->Reserved2 = 0;
4284         byte_count = params + 1 /* pad */ ;
4285         pSMB->TotalParameterCount = cpu_to_le16(params);
4286         pSMB->ParameterCount = pSMB->TotalParameterCount;
4287         pSMB->ParameterOffset = cpu_to_le16(
4288               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4289                 - 4);
4290         pSMB->DataCount = 0;
4291         pSMB->DataOffset = 0;
4292         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4293         pSMB->Reserved3 = 0;
4294         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4295         pSMB->SearchAttributes =
4296             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4297                         ATTR_DIRECTORY);
4298         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4299         pSMB->SearchFlags = cpu_to_le16(search_flags);
4300         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4301
4302         /* BB what should we set StorageType to? Does it matter? BB */
4303         pSMB->SearchStorageType = 0;
4304         inc_rfc1001_len(pSMB, byte_count);
4305         pSMB->ByteCount = cpu_to_le16(byte_count);
4306
4307         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4308                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4309         cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4310
4311         if (rc) {/* BB add logic to retry regular search if Unix search
4312                         rejected unexpectedly by server */
4313                 /* BB Add code to handle unsupported level rc */
4314                 cFYI(1, "Error in FindFirst = %d", rc);
4315
4316                 cifs_buf_release(pSMB);
4317
4318                 /* BB eventually could optimize out free and realloc of buf */
4319                 /*    for this case */
4320                 if (rc == -EAGAIN)
4321                         goto findFirstRetry;
4322         } else { /* decode response */
4323                 /* BB remember to free buffer if error BB */
4324                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4325                 if (rc == 0) {
4326                         unsigned int lnoff;
4327
4328                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4329                                 psrch_inf->unicode = true;
4330                         else
4331                                 psrch_inf->unicode = false;
4332
4333                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4334                         psrch_inf->smallBuf = 0;
4335                         psrch_inf->srch_entries_start =
4336                                 (char *) &pSMBr->hdr.Protocol +
4337                                         le16_to_cpu(pSMBr->t2.DataOffset);
4338                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4339                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4340
4341                         if (parms->EndofSearch)
4342                                 psrch_inf->endOfSearch = true;
4343                         else
4344                                 psrch_inf->endOfSearch = false;
4345
4346                         psrch_inf->entries_in_buffer =
4347                                         le16_to_cpu(parms->SearchCount);
4348                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4349                                 psrch_inf->entries_in_buffer;
4350                         lnoff = le16_to_cpu(parms->LastNameOffset);
4351                         if (CIFSMaxBufSize < lnoff) {
4352                                 cERROR(1, "ignoring corrupt resume name");
4353                                 psrch_inf->last_entry = NULL;
4354                                 return rc;
4355                         }
4356
4357                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4358                                                         lnoff;
4359
4360                         *pnetfid = parms->SearchHandle;
4361                 } else {
4362                         cifs_buf_release(pSMB);
4363                 }
4364         }
4365
4366         return rc;
4367 }
4368
4369 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4370                  __u16 searchHandle, __u16 search_flags,
4371                  struct cifs_search_info *psrch_inf)
4372 {
4373         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4374         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4375         T2_FNEXT_RSP_PARMS *parms;
4376         char *response_data;
4377         int rc = 0;
4378         int bytes_returned;
4379         unsigned int name_len;
4380         __u16 params, byte_count;
4381
4382         cFYI(1, "In FindNext");
4383
4384         if (psrch_inf->endOfSearch)
4385                 return -ENOENT;
4386
4387         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4388                 (void **) &pSMBr);
4389         if (rc)
4390                 return rc;
4391
4392         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4393         byte_count = 0;
4394         pSMB->TotalDataCount = 0;       /* no EAs */
4395         pSMB->MaxParameterCount = cpu_to_le16(8);
4396         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4397         pSMB->MaxSetupCount = 0;
4398         pSMB->Reserved = 0;
4399         pSMB->Flags = 0;
4400         pSMB->Timeout = 0;
4401         pSMB->Reserved2 = 0;
4402         pSMB->ParameterOffset =  cpu_to_le16(
4403               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4404         pSMB->DataCount = 0;
4405         pSMB->DataOffset = 0;
4406         pSMB->SetupCount = 1;
4407         pSMB->Reserved3 = 0;
4408         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4409         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4410         pSMB->SearchCount =
4411                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4412         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4413         pSMB->ResumeKey = psrch_inf->resume_key;
4414         pSMB->SearchFlags = cpu_to_le16(search_flags);
4415
4416         name_len = psrch_inf->resume_name_len;
4417         params += name_len;
4418         if (name_len < PATH_MAX) {
4419                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4420                 byte_count += name_len;
4421                 /* 14 byte parm len above enough for 2 byte null terminator */
4422                 pSMB->ResumeFileName[name_len] = 0;
4423                 pSMB->ResumeFileName[name_len+1] = 0;
4424         } else {
4425                 rc = -EINVAL;
4426                 goto FNext2_err_exit;
4427         }
4428         byte_count = params + 1 /* pad */ ;
4429         pSMB->TotalParameterCount = cpu_to_le16(params);
4430         pSMB->ParameterCount = pSMB->TotalParameterCount;
4431         inc_rfc1001_len(pSMB, byte_count);
4432         pSMB->ByteCount = cpu_to_le16(byte_count);
4433
4434         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4435                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4436         cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4437         if (rc) {
4438                 if (rc == -EBADF) {
4439                         psrch_inf->endOfSearch = true;
4440                         cifs_buf_release(pSMB);
4441                         rc = 0; /* search probably was closed at end of search*/
4442                 } else
4443                         cFYI(1, "FindNext returned = %d", rc);
4444         } else {                /* decode response */
4445                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4446
4447                 if (rc == 0) {
4448                         unsigned int lnoff;
4449
4450                         /* BB fixme add lock for file (srch_info) struct here */
4451                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4452                                 psrch_inf->unicode = true;
4453                         else
4454                                 psrch_inf->unicode = false;
4455                         response_data = (char *) &pSMBr->hdr.Protocol +
4456                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4457                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4458                         response_data = (char *)&pSMBr->hdr.Protocol +
4459                                 le16_to_cpu(pSMBr->t2.DataOffset);
4460                         if (psrch_inf->smallBuf)
4461                                 cifs_small_buf_release(
4462                                         psrch_inf->ntwrk_buf_start);
4463                         else
4464                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4465                         psrch_inf->srch_entries_start = response_data;
4466                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4467                         psrch_inf->smallBuf = 0;
4468                         if (parms->EndofSearch)
4469                                 psrch_inf->endOfSearch = true;
4470                         else
4471                                 psrch_inf->endOfSearch = false;
4472                         psrch_inf->entries_in_buffer =
4473                                                 le16_to_cpu(parms->SearchCount);
4474                         psrch_inf->index_of_last_entry +=
4475                                 psrch_inf->entries_in_buffer;
4476                         lnoff = le16_to_cpu(parms->LastNameOffset);
4477                         if (CIFSMaxBufSize < lnoff) {
4478                                 cERROR(1, "ignoring corrupt resume name");
4479                                 psrch_inf->last_entry = NULL;
4480                                 return rc;
4481                         } else
4482                                 psrch_inf->last_entry =
4483                                         psrch_inf->srch_entries_start + lnoff;
4484
4485 /*  cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4486             psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4487
4488                         /* BB fixme add unlock here */
4489                 }
4490
4491         }
4492
4493         /* BB On error, should we leave previous search buf (and count and
4494         last entry fields) intact or free the previous one? */
4495
4496         /* Note: On -EAGAIN error only caller can retry on handle based calls
4497         since file handle passed in no longer valid */
4498 FNext2_err_exit:
4499         if (rc != 0)
4500                 cifs_buf_release(pSMB);
4501         return rc;
4502 }
4503
4504 int
4505 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4506               const __u16 searchHandle)
4507 {
4508         int rc = 0;
4509         FINDCLOSE_REQ *pSMB = NULL;
4510
4511         cFYI(1, "In CIFSSMBFindClose");
4512         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4513
4514         /* no sense returning error if session restarted
4515                 as file handle has been closed */
4516         if (rc == -EAGAIN)
4517                 return 0;
4518         if (rc)
4519                 return rc;
4520
4521         pSMB->FileID = searchHandle;
4522         pSMB->ByteCount = 0;
4523         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4524         if (rc)
4525                 cERROR(1, "Send error in FindClose = %d", rc);
4526
4527         cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4528
4529         /* Since session is dead, search handle closed on server already */
4530         if (rc == -EAGAIN)
4531                 rc = 0;
4532
4533         return rc;
4534 }
4535
4536 int
4537 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4538                       const char *search_name, __u64 *inode_number,
4539                       const struct nls_table *nls_codepage, int remap)
4540 {
4541         int rc = 0;
4542         TRANSACTION2_QPI_REQ *pSMB = NULL;
4543         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4544         int name_len, bytes_returned;
4545         __u16 params, byte_count;
4546
4547         cFYI(1, "In GetSrvInodeNum for %s", search_name);
4548         if (tcon == NULL)
4549                 return -ENODEV;
4550
4551 GetInodeNumberRetry:
4552         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4553                       (void **) &pSMBr);
4554         if (rc)
4555                 return rc;
4556
4557         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4558                 name_len =
4559                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4560                                            search_name, PATH_MAX, nls_codepage,
4561                                            remap);
4562                 name_len++;     /* trailing null */
4563                 name_len *= 2;
4564         } else {        /* BB improve the check for buffer overruns BB */
4565                 name_len = strnlen(search_name, PATH_MAX);
4566                 name_len++;     /* trailing null */
4567                 strncpy(pSMB->FileName, search_name, name_len);
4568         }
4569
4570         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4571         pSMB->TotalDataCount = 0;
4572         pSMB->MaxParameterCount = cpu_to_le16(2);
4573         /* BB find exact max data count below from sess structure BB */
4574         pSMB->MaxDataCount = cpu_to_le16(4000);
4575         pSMB->MaxSetupCount = 0;
4576         pSMB->Reserved = 0;
4577         pSMB->Flags = 0;
4578         pSMB->Timeout = 0;
4579         pSMB->Reserved2 = 0;
4580         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4581                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4582         pSMB->DataCount = 0;
4583         pSMB->DataOffset = 0;
4584         pSMB->SetupCount = 1;
4585         pSMB->Reserved3 = 0;
4586         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4587         byte_count = params + 1 /* pad */ ;
4588         pSMB->TotalParameterCount = cpu_to_le16(params);
4589         pSMB->ParameterCount = pSMB->TotalParameterCount;
4590         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4591         pSMB->Reserved4 = 0;
4592         inc_rfc1001_len(pSMB, byte_count);
4593         pSMB->ByteCount = cpu_to_le16(byte_count);
4594
4595         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4596                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4597         if (rc) {
4598                 cFYI(1, "error %d in QueryInternalInfo", rc);
4599         } else {
4600                 /* decode response */
4601                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4602                 /* BB also check enough total bytes returned */
4603                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4604                         /* If rc should we check for EOPNOSUPP and
4605                         disable the srvino flag? or in caller? */
4606                         rc = -EIO;      /* bad smb */
4607                 else {
4608                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4609                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4610                         struct file_internal_info *pfinfo;
4611                         /* BB Do we need a cast or hash here ? */
4612                         if (count < 8) {
4613                                 cFYI(1, "Illegal size ret in QryIntrnlInf");
4614                                 rc = -EIO;
4615                                 goto GetInodeNumOut;
4616                         }
4617                         pfinfo = (struct file_internal_info *)
4618                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4619                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4620                 }
4621         }
4622 GetInodeNumOut:
4623         cifs_buf_release(pSMB);
4624         if (rc == -EAGAIN)
4625                 goto GetInodeNumberRetry;
4626         return rc;
4627 }
4628
4629 /* parses DFS refferal V3 structure
4630  * caller is responsible for freeing target_nodes
4631  * returns:
4632  *      on success - 0
4633  *      on failure - errno
4634  */
4635 static int
4636 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4637                 unsigned int *num_of_nodes,
4638                 struct dfs_info3_param **target_nodes,
4639                 const struct nls_table *nls_codepage, int remap,
4640                 const char *searchName)
4641 {
4642         int i, rc = 0;
4643         char *data_end;
4644         bool is_unicode;
4645         struct dfs_referral_level_3 *ref;
4646
4647         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4648                 is_unicode = true;
4649         else
4650                 is_unicode = false;
4651         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4652
4653         if (*num_of_nodes < 1) {
4654                 cERROR(1, "num_referrals: must be at least > 0,"
4655                         "but we get num_referrals = %d", *num_of_nodes);
4656                 rc = -EINVAL;
4657                 goto parse_DFS_referrals_exit;
4658         }
4659
4660         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4661         if (ref->VersionNumber != cpu_to_le16(3)) {
4662                 cERROR(1, "Referrals of V%d version are not supported,"
4663                         "should be V3", le16_to_cpu(ref->VersionNumber));
4664                 rc = -EINVAL;
4665                 goto parse_DFS_referrals_exit;
4666         }
4667
4668         /* get the upper boundary of the resp buffer */
4669         data_end = (char *)(&(pSMBr->PathConsumed)) +
4670                                 le16_to_cpu(pSMBr->t2.DataCount);
4671
4672         cFYI(1, "num_referrals: %d dfs flags: 0x%x ...",
4673                         *num_of_nodes,
4674                         le32_to_cpu(pSMBr->DFSFlags));
4675
4676         *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4677                         *num_of_nodes, GFP_KERNEL);
4678         if (*target_nodes == NULL) {
4679                 cERROR(1, "Failed to allocate buffer for target_nodes");
4680                 rc = -ENOMEM;
4681                 goto parse_DFS_referrals_exit;
4682         }
4683
4684         /* collect necessary data from referrals */
4685         for (i = 0; i < *num_of_nodes; i++) {
4686                 char *temp;
4687                 int max_len;
4688                 struct dfs_info3_param *node = (*target_nodes)+i;
4689
4690                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4691                 if (is_unicode) {
4692                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4693                                                 GFP_KERNEL);
4694                         if (tmp == NULL) {
4695                                 rc = -ENOMEM;
4696                                 goto parse_DFS_referrals_exit;
4697                         }
4698                         cifsConvertToUTF16((__le16 *) tmp, searchName,
4699                                            PATH_MAX, nls_codepage, remap);
4700                         node->path_consumed = cifs_utf16_bytes(tmp,
4701                                         le16_to_cpu(pSMBr->PathConsumed),
4702                                         nls_codepage);
4703                         kfree(tmp);
4704                 } else
4705                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4706
4707                 node->server_type = le16_to_cpu(ref->ServerType);
4708                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4709
4710                 /* copy DfsPath */
4711                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4712                 max_len = data_end - temp;
4713                 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4714                                                 is_unicode, nls_codepage);
4715                 if (!node->path_name) {
4716                         rc = -ENOMEM;
4717                         goto parse_DFS_referrals_exit;
4718                 }
4719
4720                 /* copy link target UNC */
4721                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4722                 max_len = data_end - temp;
4723                 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4724                                                 is_unicode, nls_codepage);
4725                 if (!node->node_name) {
4726                         rc = -ENOMEM;
4727                         goto parse_DFS_referrals_exit;
4728                 }
4729
4730                 ref++;
4731         }
4732
4733 parse_DFS_referrals_exit:
4734         if (rc) {
4735                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4736                 *target_nodes = NULL;
4737                 *num_of_nodes = 0;
4738         }
4739         return rc;
4740 }
4741
4742 int
4743 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4744                 const char *search_name, struct dfs_info3_param **target_nodes,
4745                 unsigned int *num_of_nodes,
4746                 const struct nls_table *nls_codepage, int remap)
4747 {
4748 /* TRANS2_GET_DFS_REFERRAL */
4749         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4750         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4751         int rc = 0;
4752         int bytes_returned;
4753         int name_len;
4754         __u16 params, byte_count;
4755         *num_of_nodes = 0;
4756         *target_nodes = NULL;
4757
4758         cFYI(1, "In GetDFSRefer the path %s", search_name);
4759         if (ses == NULL)
4760                 return -ENODEV;
4761 getDFSRetry:
4762         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4763                       (void **) &pSMBr);
4764         if (rc)
4765                 return rc;
4766
4767         /* server pointer checked in called function,
4768         but should never be null here anyway */
4769         pSMB->hdr.Mid = get_next_mid(ses->server);
4770         pSMB->hdr.Tid = ses->ipc_tid;
4771         pSMB->hdr.Uid = ses->Suid;
4772         if (ses->capabilities & CAP_STATUS32)
4773                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4774         if (ses->capabilities & CAP_DFS)
4775                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4776
4777         if (ses->capabilities & CAP_UNICODE) {
4778                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4779                 name_len =
4780                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4781                                        search_name, PATH_MAX, nls_codepage,
4782                                        remap);
4783                 name_len++;     /* trailing null */
4784                 name_len *= 2;
4785         } else {        /* BB improve the check for buffer overruns BB */
4786                 name_len = strnlen(search_name, PATH_MAX);
4787                 name_len++;     /* trailing null */
4788                 strncpy(pSMB->RequestFileName, search_name, name_len);
4789         }
4790
4791         if (ses->server) {
4792                 if (ses->server->sec_mode &
4793                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4794                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4795         }
4796
4797         pSMB->hdr.Uid = ses->Suid;
4798
4799         params = 2 /* level */  + name_len /*includes null */ ;
4800         pSMB->TotalDataCount = 0;
4801         pSMB->DataCount = 0;
4802         pSMB->DataOffset = 0;
4803         pSMB->MaxParameterCount = 0;
4804         /* BB find exact max SMB PDU from sess structure BB */
4805         pSMB->MaxDataCount = cpu_to_le16(4000);
4806         pSMB->MaxSetupCount = 0;
4807         pSMB->Reserved = 0;
4808         pSMB->Flags = 0;
4809         pSMB->Timeout = 0;
4810         pSMB->Reserved2 = 0;
4811         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4812           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4813         pSMB->SetupCount = 1;
4814         pSMB->Reserved3 = 0;
4815         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4816         byte_count = params + 3 /* pad */ ;
4817         pSMB->ParameterCount = cpu_to_le16(params);
4818         pSMB->TotalParameterCount = pSMB->ParameterCount;
4819         pSMB->MaxReferralLevel = cpu_to_le16(3);
4820         inc_rfc1001_len(pSMB, byte_count);
4821         pSMB->ByteCount = cpu_to_le16(byte_count);
4822
4823         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4824                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4825         if (rc) {
4826                 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4827                 goto GetDFSRefExit;
4828         }
4829         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4830
4831         /* BB Also check if enough total bytes returned? */
4832         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4833                 rc = -EIO;      /* bad smb */
4834                 goto GetDFSRefExit;
4835         }
4836
4837         cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
4838                                 get_bcc(&pSMBr->hdr),
4839                                 le16_to_cpu(pSMBr->t2.DataOffset));
4840
4841         /* parse returned result into more usable form */
4842         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4843                                  target_nodes, nls_codepage, remap,
4844                                  search_name);
4845
4846 GetDFSRefExit:
4847         cifs_buf_release(pSMB);
4848
4849         if (rc == -EAGAIN)
4850                 goto getDFSRetry;
4851
4852         return rc;
4853 }
4854
4855 /* Query File System Info such as free space to old servers such as Win 9x */
4856 int
4857 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4858               struct kstatfs *FSData)
4859 {
4860 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4861         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4862         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4863         FILE_SYSTEM_ALLOC_INFO *response_data;
4864         int rc = 0;
4865         int bytes_returned = 0;
4866         __u16 params, byte_count;
4867
4868         cFYI(1, "OldQFSInfo");
4869 oldQFSInfoRetry:
4870         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4871                 (void **) &pSMBr);
4872         if (rc)
4873                 return rc;
4874
4875         params = 2;     /* level */
4876         pSMB->TotalDataCount = 0;
4877         pSMB->MaxParameterCount = cpu_to_le16(2);
4878         pSMB->MaxDataCount = cpu_to_le16(1000);
4879         pSMB->MaxSetupCount = 0;
4880         pSMB->Reserved = 0;
4881         pSMB->Flags = 0;
4882         pSMB->Timeout = 0;
4883         pSMB->Reserved2 = 0;
4884         byte_count = params + 1 /* pad */ ;
4885         pSMB->TotalParameterCount = cpu_to_le16(params);
4886         pSMB->ParameterCount = pSMB->TotalParameterCount;
4887         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4888         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4889         pSMB->DataCount = 0;
4890         pSMB->DataOffset = 0;
4891         pSMB->SetupCount = 1;
4892         pSMB->Reserved3 = 0;
4893         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4894         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4895         inc_rfc1001_len(pSMB, byte_count);
4896         pSMB->ByteCount = cpu_to_le16(byte_count);
4897
4898         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4899                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4900         if (rc) {
4901                 cFYI(1, "Send error in QFSInfo = %d", rc);
4902         } else {                /* decode response */
4903                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4904
4905                 if (rc || get_bcc(&pSMBr->hdr) < 18)
4906                         rc = -EIO;      /* bad smb */
4907                 else {
4908                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4909                         cFYI(1, "qfsinf resp BCC: %d  Offset %d",
4910                                  get_bcc(&pSMBr->hdr), data_offset);
4911
4912                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
4913                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4914                         FSData->f_bsize =
4915                                 le16_to_cpu(response_data->BytesPerSector) *
4916                                 le32_to_cpu(response_data->
4917                                         SectorsPerAllocationUnit);
4918                         FSData->f_blocks =
4919                                le32_to_cpu(response_data->TotalAllocationUnits);
4920                         FSData->f_bfree = FSData->f_bavail =
4921                                 le32_to_cpu(response_data->FreeAllocationUnits);
4922                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
4923                              (unsigned long long)FSData->f_blocks,
4924                              (unsigned long long)FSData->f_bfree,
4925                              FSData->f_bsize);
4926                 }
4927         }
4928         cifs_buf_release(pSMB);
4929
4930         if (rc == -EAGAIN)
4931                 goto oldQFSInfoRetry;
4932
4933         return rc;
4934 }
4935
4936 int
4937 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4938                struct kstatfs *FSData)
4939 {
4940 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4941         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4942         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4943         FILE_SYSTEM_INFO *response_data;
4944         int rc = 0;
4945         int bytes_returned = 0;
4946         __u16 params, byte_count;
4947
4948         cFYI(1, "In QFSInfo");
4949 QFSInfoRetry:
4950         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4951                       (void **) &pSMBr);
4952         if (rc)
4953                 return rc;
4954
4955         params = 2;     /* level */
4956         pSMB->TotalDataCount = 0;
4957         pSMB->MaxParameterCount = cpu_to_le16(2);
4958         pSMB->MaxDataCount = cpu_to_le16(1000);
4959         pSMB->MaxSetupCount = 0;
4960         pSMB->Reserved = 0;
4961         pSMB->Flags = 0;
4962         pSMB->Timeout = 0;
4963         pSMB->Reserved2 = 0;
4964         byte_count = params + 1 /* pad */ ;
4965         pSMB->TotalParameterCount = cpu_to_le16(params);
4966         pSMB->ParameterCount = pSMB->TotalParameterCount;
4967         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4968                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4969         pSMB->DataCount = 0;
4970         pSMB->DataOffset = 0;
4971         pSMB->SetupCount = 1;
4972         pSMB->Reserved3 = 0;
4973         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4974         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4975         inc_rfc1001_len(pSMB, byte_count);
4976         pSMB->ByteCount = cpu_to_le16(byte_count);
4977
4978         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4979                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4980         if (rc) {
4981                 cFYI(1, "Send error in QFSInfo = %d", rc);
4982         } else {                /* decode response */
4983                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4984
4985                 if (rc || get_bcc(&pSMBr->hdr) < 24)
4986                         rc = -EIO;      /* bad smb */
4987                 else {
4988                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4989
4990                         response_data =
4991                             (FILE_SYSTEM_INFO
4992                              *) (((char *) &pSMBr->hdr.Protocol) +
4993                                  data_offset);
4994                         FSData->f_bsize =
4995                             le32_to_cpu(response_data->BytesPerSector) *
4996                             le32_to_cpu(response_data->
4997                                         SectorsPerAllocationUnit);
4998                         FSData->f_blocks =
4999                             le64_to_cpu(response_data->TotalAllocationUnits);
5000                         FSData->f_bfree = FSData->f_bavail =
5001                             le64_to_cpu(response_data->FreeAllocationUnits);
5002                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5003                              (unsigned long long)FSData->f_blocks,
5004                              (unsigned long long)FSData->f_bfree,
5005                              FSData->f_bsize);
5006                 }
5007         }
5008         cifs_buf_release(pSMB);
5009
5010         if (rc == -EAGAIN)
5011                 goto QFSInfoRetry;
5012
5013         return rc;
5014 }
5015
5016 int
5017 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5018 {
5019 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5020         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5021         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5022         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5023         int rc = 0;
5024         int bytes_returned = 0;
5025         __u16 params, byte_count;
5026
5027         cFYI(1, "In QFSAttributeInfo");
5028 QFSAttributeRetry:
5029         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5030                       (void **) &pSMBr);
5031         if (rc)
5032                 return rc;
5033
5034         params = 2;     /* level */
5035         pSMB->TotalDataCount = 0;
5036         pSMB->MaxParameterCount = cpu_to_le16(2);
5037         /* BB find exact max SMB PDU from sess structure BB */
5038         pSMB->MaxDataCount = cpu_to_le16(1000);
5039         pSMB->MaxSetupCount = 0;
5040         pSMB->Reserved = 0;
5041         pSMB->Flags = 0;
5042         pSMB->Timeout = 0;
5043         pSMB->Reserved2 = 0;
5044         byte_count = params + 1 /* pad */ ;
5045         pSMB->TotalParameterCount = cpu_to_le16(params);
5046         pSMB->ParameterCount = pSMB->TotalParameterCount;
5047         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5048                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5049         pSMB->DataCount = 0;
5050         pSMB->DataOffset = 0;
5051         pSMB->SetupCount = 1;
5052         pSMB->Reserved3 = 0;
5053         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5054         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5055         inc_rfc1001_len(pSMB, byte_count);
5056         pSMB->ByteCount = cpu_to_le16(byte_count);
5057
5058         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5059                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5060         if (rc) {
5061                 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5062         } else {                /* decode response */
5063                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5064
5065                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5066                         /* BB also check if enough bytes returned */
5067                         rc = -EIO;      /* bad smb */
5068                 } else {
5069                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5070                         response_data =
5071                             (FILE_SYSTEM_ATTRIBUTE_INFO
5072                              *) (((char *) &pSMBr->hdr.Protocol) +
5073                                  data_offset);
5074                         memcpy(&tcon->fsAttrInfo, response_data,
5075                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5076                 }
5077         }
5078         cifs_buf_release(pSMB);
5079
5080         if (rc == -EAGAIN)
5081                 goto QFSAttributeRetry;
5082
5083         return rc;
5084 }
5085
5086 int
5087 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5088 {
5089 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5090         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5091         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5092         FILE_SYSTEM_DEVICE_INFO *response_data;
5093         int rc = 0;
5094         int bytes_returned = 0;
5095         __u16 params, byte_count;
5096
5097         cFYI(1, "In QFSDeviceInfo");
5098 QFSDeviceRetry:
5099         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5100                       (void **) &pSMBr);
5101         if (rc)
5102                 return rc;
5103
5104         params = 2;     /* level */
5105         pSMB->TotalDataCount = 0;
5106         pSMB->MaxParameterCount = cpu_to_le16(2);
5107         /* BB find exact max SMB PDU from sess structure BB */
5108         pSMB->MaxDataCount = cpu_to_le16(1000);
5109         pSMB->MaxSetupCount = 0;
5110         pSMB->Reserved = 0;
5111         pSMB->Flags = 0;
5112         pSMB->Timeout = 0;
5113         pSMB->Reserved2 = 0;
5114         byte_count = params + 1 /* pad */ ;
5115         pSMB->TotalParameterCount = cpu_to_le16(params);
5116         pSMB->ParameterCount = pSMB->TotalParameterCount;
5117         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5118                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5119
5120         pSMB->DataCount = 0;
5121         pSMB->DataOffset = 0;
5122         pSMB->SetupCount = 1;
5123         pSMB->Reserved3 = 0;
5124         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5125         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5126         inc_rfc1001_len(pSMB, byte_count);
5127         pSMB->ByteCount = cpu_to_le16(byte_count);
5128
5129         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5130                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5131         if (rc) {
5132                 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5133         } else {                /* decode response */
5134                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5135
5136                 if (rc || get_bcc(&pSMBr->hdr) <
5137                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5138                         rc = -EIO;      /* bad smb */
5139                 else {
5140                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5141                         response_data =
5142                             (FILE_SYSTEM_DEVICE_INFO *)
5143                                 (((char *) &pSMBr->hdr.Protocol) +
5144                                  data_offset);
5145                         memcpy(&tcon->fsDevInfo, response_data,
5146                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5147                 }
5148         }
5149         cifs_buf_release(pSMB);
5150
5151         if (rc == -EAGAIN)
5152                 goto QFSDeviceRetry;
5153
5154         return rc;
5155 }
5156
5157 int
5158 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5159 {
5160 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5161         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5162         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5163         FILE_SYSTEM_UNIX_INFO *response_data;
5164         int rc = 0;
5165         int bytes_returned = 0;
5166         __u16 params, byte_count;
5167
5168         cFYI(1, "In QFSUnixInfo");
5169 QFSUnixRetry:
5170         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5171                                    (void **) &pSMB, (void **) &pSMBr);
5172         if (rc)
5173                 return rc;
5174
5175         params = 2;     /* level */
5176         pSMB->TotalDataCount = 0;
5177         pSMB->DataCount = 0;
5178         pSMB->DataOffset = 0;
5179         pSMB->MaxParameterCount = cpu_to_le16(2);
5180         /* BB find exact max SMB PDU from sess structure BB */
5181         pSMB->MaxDataCount = cpu_to_le16(100);
5182         pSMB->MaxSetupCount = 0;
5183         pSMB->Reserved = 0;
5184         pSMB->Flags = 0;
5185         pSMB->Timeout = 0;
5186         pSMB->Reserved2 = 0;
5187         byte_count = params + 1 /* pad */ ;
5188         pSMB->ParameterCount = cpu_to_le16(params);
5189         pSMB->TotalParameterCount = pSMB->ParameterCount;
5190         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5191                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5192         pSMB->SetupCount = 1;
5193         pSMB->Reserved3 = 0;
5194         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5195         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5196         inc_rfc1001_len(pSMB, byte_count);
5197         pSMB->ByteCount = cpu_to_le16(byte_count);
5198
5199         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5200                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5201         if (rc) {
5202                 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5203         } else {                /* decode response */
5204                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5205
5206                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5207                         rc = -EIO;      /* bad smb */
5208                 } else {
5209                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5210                         response_data =
5211                             (FILE_SYSTEM_UNIX_INFO
5212                              *) (((char *) &pSMBr->hdr.Protocol) +
5213                                  data_offset);
5214                         memcpy(&tcon->fsUnixInfo, response_data,
5215                                sizeof(FILE_SYSTEM_UNIX_INFO));
5216                 }
5217         }
5218         cifs_buf_release(pSMB);
5219
5220         if (rc == -EAGAIN)
5221                 goto QFSUnixRetry;
5222
5223
5224         return rc;
5225 }
5226
5227 int
5228 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5229 {
5230 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5231         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5232         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5233         int rc = 0;
5234         int bytes_returned = 0;
5235         __u16 params, param_offset, offset, byte_count;
5236
5237         cFYI(1, "In SETFSUnixInfo");
5238 SETFSUnixRetry:
5239         /* BB switch to small buf init to save memory */
5240         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5241                                         (void **) &pSMB, (void **) &pSMBr);
5242         if (rc)
5243                 return rc;
5244
5245         params = 4;     /* 2 bytes zero followed by info level. */
5246         pSMB->MaxSetupCount = 0;
5247         pSMB->Reserved = 0;
5248         pSMB->Flags = 0;
5249         pSMB->Timeout = 0;
5250         pSMB->Reserved2 = 0;
5251         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5252                                 - 4;
5253         offset = param_offset + params;
5254
5255         pSMB->MaxParameterCount = cpu_to_le16(4);
5256         /* BB find exact max SMB PDU from sess structure BB */
5257         pSMB->MaxDataCount = cpu_to_le16(100);
5258         pSMB->SetupCount = 1;
5259         pSMB->Reserved3 = 0;
5260         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5261         byte_count = 1 /* pad */ + params + 12;
5262
5263         pSMB->DataCount = cpu_to_le16(12);
5264         pSMB->ParameterCount = cpu_to_le16(params);
5265         pSMB->TotalDataCount = pSMB->DataCount;
5266         pSMB->TotalParameterCount = pSMB->ParameterCount;
5267         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5268         pSMB->DataOffset = cpu_to_le16(offset);
5269
5270         /* Params. */
5271         pSMB->FileNum = 0;
5272         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5273
5274         /* Data. */
5275         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5276         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5277         pSMB->ClientUnixCap = cpu_to_le64(cap);
5278
5279         inc_rfc1001_len(pSMB, byte_count);
5280         pSMB->ByteCount = cpu_to_le16(byte_count);
5281
5282         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5283                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5284         if (rc) {
5285                 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5286         } else {                /* decode response */
5287                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5288                 if (rc)
5289                         rc = -EIO;      /* bad smb */
5290         }
5291         cifs_buf_release(pSMB);
5292
5293         if (rc == -EAGAIN)
5294                 goto SETFSUnixRetry;
5295
5296         return rc;
5297 }
5298
5299
5300
5301 int
5302 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5303                    struct kstatfs *FSData)
5304 {
5305 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5306         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5307         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5308         FILE_SYSTEM_POSIX_INFO *response_data;
5309         int rc = 0;
5310         int bytes_returned = 0;
5311         __u16 params, byte_count;
5312
5313         cFYI(1, "In QFSPosixInfo");
5314 QFSPosixRetry:
5315         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5316                       (void **) &pSMBr);
5317         if (rc)
5318                 return rc;
5319
5320         params = 2;     /* level */
5321         pSMB->TotalDataCount = 0;
5322         pSMB->DataCount = 0;
5323         pSMB->DataOffset = 0;
5324         pSMB->MaxParameterCount = cpu_to_le16(2);
5325         /* BB find exact max SMB PDU from sess structure BB */
5326         pSMB->MaxDataCount = cpu_to_le16(100);
5327         pSMB->MaxSetupCount = 0;
5328         pSMB->Reserved = 0;
5329         pSMB->Flags = 0;
5330         pSMB->Timeout = 0;
5331         pSMB->Reserved2 = 0;
5332         byte_count = params + 1 /* pad */ ;
5333         pSMB->ParameterCount = cpu_to_le16(params);
5334         pSMB->TotalParameterCount = pSMB->ParameterCount;
5335         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5336                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5337         pSMB->SetupCount = 1;
5338         pSMB->Reserved3 = 0;
5339         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5340         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5341         inc_rfc1001_len(pSMB, byte_count);
5342         pSMB->ByteCount = cpu_to_le16(byte_count);
5343
5344         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5345                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5346         if (rc) {
5347                 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5348         } else {                /* decode response */
5349                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5350
5351                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5352                         rc = -EIO;      /* bad smb */
5353                 } else {
5354                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5355                         response_data =
5356                             (FILE_SYSTEM_POSIX_INFO
5357                              *) (((char *) &pSMBr->hdr.Protocol) +
5358                                  data_offset);
5359                         FSData->f_bsize =
5360                                         le32_to_cpu(response_data->BlockSize);
5361                         FSData->f_blocks =
5362                                         le64_to_cpu(response_data->TotalBlocks);
5363                         FSData->f_bfree =
5364                             le64_to_cpu(response_data->BlocksAvail);
5365                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5366                                 FSData->f_bavail = FSData->f_bfree;
5367                         } else {
5368                                 FSData->f_bavail =
5369                                     le64_to_cpu(response_data->UserBlocksAvail);
5370                         }
5371                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5372                                 FSData->f_files =
5373                                      le64_to_cpu(response_data->TotalFileNodes);
5374                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5375                                 FSData->f_ffree =
5376                                       le64_to_cpu(response_data->FreeFileNodes);
5377                 }
5378         }
5379         cifs_buf_release(pSMB);
5380
5381         if (rc == -EAGAIN)
5382                 goto QFSPosixRetry;
5383
5384         return rc;
5385 }
5386
5387
5388 /*
5389  * We can not use write of zero bytes trick to set file size due to need for
5390  * large file support. Also note that this SetPathInfo is preferred to
5391  * SetFileInfo based method in next routine which is only needed to work around
5392  * a sharing violation bugin Samba which this routine can run into.
5393  */
5394 int
5395 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5396               const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5397               bool set_allocation)
5398 {
5399         struct smb_com_transaction2_spi_req *pSMB = NULL;
5400         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5401         struct file_end_of_file_info *parm_data;
5402         int name_len;
5403         int rc = 0;
5404         int bytes_returned = 0;
5405         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
5406
5407         __u16 params, byte_count, data_count, param_offset, offset;
5408
5409         cFYI(1, "In SetEOF");
5410 SetEOFRetry:
5411         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5412                       (void **) &pSMBr);
5413         if (rc)
5414                 return rc;
5415
5416         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5417                 name_len =
5418                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5419                                        PATH_MAX, cifs_sb->local_nls, remap);
5420                 name_len++;     /* trailing null */
5421                 name_len *= 2;
5422         } else {        /* BB improve the check for buffer overruns BB */
5423                 name_len = strnlen(file_name, PATH_MAX);
5424                 name_len++;     /* trailing null */
5425                 strncpy(pSMB->FileName, file_name, name_len);
5426         }
5427         params = 6 + name_len;
5428         data_count = sizeof(struct file_end_of_file_info);
5429         pSMB->MaxParameterCount = cpu_to_le16(2);
5430         pSMB->MaxDataCount = cpu_to_le16(4100);
5431         pSMB->MaxSetupCount = 0;
5432         pSMB->Reserved = 0;
5433         pSMB->Flags = 0;
5434         pSMB->Timeout = 0;
5435         pSMB->Reserved2 = 0;
5436         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5437                                 InformationLevel) - 4;
5438         offset = param_offset + params;
5439         if (set_allocation) {
5440                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5441                         pSMB->InformationLevel =
5442                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5443                 else
5444                         pSMB->InformationLevel =
5445                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5446         } else /* Set File Size */  {
5447             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5448                     pSMB->InformationLevel =
5449                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5450             else
5451                     pSMB->InformationLevel =
5452                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5453         }
5454
5455         parm_data =
5456             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5457                                        offset);
5458         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5459         pSMB->DataOffset = cpu_to_le16(offset);
5460         pSMB->SetupCount = 1;
5461         pSMB->Reserved3 = 0;
5462         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5463         byte_count = 3 /* pad */  + params + data_count;
5464         pSMB->DataCount = cpu_to_le16(data_count);
5465         pSMB->TotalDataCount = pSMB->DataCount;
5466         pSMB->ParameterCount = cpu_to_le16(params);
5467         pSMB->TotalParameterCount = pSMB->ParameterCount;
5468         pSMB->Reserved4 = 0;
5469         inc_rfc1001_len(pSMB, byte_count);
5470         parm_data->FileSize = cpu_to_le64(size);
5471         pSMB->ByteCount = cpu_to_le16(byte_count);
5472         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5473                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5474         if (rc)
5475                 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5476
5477         cifs_buf_release(pSMB);
5478
5479         if (rc == -EAGAIN)
5480                 goto SetEOFRetry;
5481
5482         return rc;
5483 }
5484
5485 int
5486 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5487                    struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5488 {
5489         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5490         struct file_end_of_file_info *parm_data;
5491         int rc = 0;
5492         __u16 params, param_offset, offset, byte_count, count;
5493
5494         cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5495                         (long long)size);
5496         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5497
5498         if (rc)
5499                 return rc;
5500
5501         pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5502         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5503
5504         params = 6;
5505         pSMB->MaxSetupCount = 0;
5506         pSMB->Reserved = 0;
5507         pSMB->Flags = 0;
5508         pSMB->Timeout = 0;
5509         pSMB->Reserved2 = 0;
5510         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5511         offset = param_offset + params;
5512
5513         count = sizeof(struct file_end_of_file_info);
5514         pSMB->MaxParameterCount = cpu_to_le16(2);
5515         /* BB find exact max SMB PDU from sess structure BB */
5516         pSMB->MaxDataCount = cpu_to_le16(1000);
5517         pSMB->SetupCount = 1;
5518         pSMB->Reserved3 = 0;
5519         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5520         byte_count = 3 /* pad */  + params + count;
5521         pSMB->DataCount = cpu_to_le16(count);
5522         pSMB->ParameterCount = cpu_to_le16(params);
5523         pSMB->TotalDataCount = pSMB->DataCount;
5524         pSMB->TotalParameterCount = pSMB->ParameterCount;
5525         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5526         parm_data =
5527                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5528                                 + offset);
5529         pSMB->DataOffset = cpu_to_le16(offset);
5530         parm_data->FileSize = cpu_to_le64(size);
5531         pSMB->Fid = cfile->fid.netfid;
5532         if (set_allocation) {
5533                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5534                         pSMB->InformationLevel =
5535                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5536                 else
5537                         pSMB->InformationLevel =
5538                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5539         } else /* Set File Size */  {
5540             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5541                     pSMB->InformationLevel =
5542                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5543             else
5544                     pSMB->InformationLevel =
5545                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5546         }
5547         pSMB->Reserved4 = 0;
5548         inc_rfc1001_len(pSMB, byte_count);
5549         pSMB->ByteCount = cpu_to_le16(byte_count);
5550         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5551         if (rc) {
5552                 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5553         }
5554
5555         /* Note: On -EAGAIN error only caller can retry on handle based calls
5556                 since file handle passed in no longer valid */
5557
5558         return rc;
5559 }
5560
5561 /* Some legacy servers such as NT4 require that the file times be set on
5562    an open handle, rather than by pathname - this is awkward due to
5563    potential access conflicts on the open, but it is unavoidable for these
5564    old servers since the only other choice is to go from 100 nanosecond DCE
5565    time and resort to the original setpathinfo level which takes the ancient
5566    DOS time format with 2 second granularity */
5567 int
5568 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5569                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5570 {
5571         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5572         char *data_offset;
5573         int rc = 0;
5574         __u16 params, param_offset, offset, byte_count, count;
5575
5576         cFYI(1, "Set Times (via SetFileInfo)");
5577         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5578
5579         if (rc)
5580                 return rc;
5581
5582         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5583         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5584
5585         params = 6;
5586         pSMB->MaxSetupCount = 0;
5587         pSMB->Reserved = 0;
5588         pSMB->Flags = 0;
5589         pSMB->Timeout = 0;
5590         pSMB->Reserved2 = 0;
5591         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5592         offset = param_offset + params;
5593
5594         data_offset = (char *)pSMB +
5595                         offsetof(struct smb_hdr, Protocol) + offset;
5596
5597         count = sizeof(FILE_BASIC_INFO);
5598         pSMB->MaxParameterCount = cpu_to_le16(2);
5599         /* BB find max SMB PDU from sess */
5600         pSMB->MaxDataCount = cpu_to_le16(1000);
5601         pSMB->SetupCount = 1;
5602         pSMB->Reserved3 = 0;
5603         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5604         byte_count = 3 /* pad */  + params + count;
5605         pSMB->DataCount = cpu_to_le16(count);
5606         pSMB->ParameterCount = cpu_to_le16(params);
5607         pSMB->TotalDataCount = pSMB->DataCount;
5608         pSMB->TotalParameterCount = pSMB->ParameterCount;
5609         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5610         pSMB->DataOffset = cpu_to_le16(offset);
5611         pSMB->Fid = fid;
5612         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5613                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5614         else
5615                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5616         pSMB->Reserved4 = 0;
5617         inc_rfc1001_len(pSMB, byte_count);
5618         pSMB->ByteCount = cpu_to_le16(byte_count);
5619         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5620         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5621         if (rc)
5622                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5623
5624         /* Note: On -EAGAIN error only caller can retry on handle based calls
5625                 since file handle passed in no longer valid */
5626
5627         return rc;
5628 }
5629
5630 int
5631 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5632                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5633 {
5634         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5635         char *data_offset;
5636         int rc = 0;
5637         __u16 params, param_offset, offset, byte_count, count;
5638
5639         cFYI(1, "Set File Disposition (via SetFileInfo)");
5640         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5641
5642         if (rc)
5643                 return rc;
5644
5645         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5646         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5647
5648         params = 6;
5649         pSMB->MaxSetupCount = 0;
5650         pSMB->Reserved = 0;
5651         pSMB->Flags = 0;
5652         pSMB->Timeout = 0;
5653         pSMB->Reserved2 = 0;
5654         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5655         offset = param_offset + params;
5656
5657         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5658
5659         count = 1;
5660         pSMB->MaxParameterCount = cpu_to_le16(2);
5661         /* BB find max SMB PDU from sess */
5662         pSMB->MaxDataCount = cpu_to_le16(1000);
5663         pSMB->SetupCount = 1;
5664         pSMB->Reserved3 = 0;
5665         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5666         byte_count = 3 /* pad */  + params + count;
5667         pSMB->DataCount = cpu_to_le16(count);
5668         pSMB->ParameterCount = cpu_to_le16(params);
5669         pSMB->TotalDataCount = pSMB->DataCount;
5670         pSMB->TotalParameterCount = pSMB->ParameterCount;
5671         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5672         pSMB->DataOffset = cpu_to_le16(offset);
5673         pSMB->Fid = fid;
5674         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5675         pSMB->Reserved4 = 0;
5676         inc_rfc1001_len(pSMB, byte_count);
5677         pSMB->ByteCount = cpu_to_le16(byte_count);
5678         *data_offset = delete_file ? 1 : 0;
5679         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5680         if (rc)
5681                 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5682
5683         return rc;
5684 }
5685
5686 int
5687 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5688                    const char *fileName, const FILE_BASIC_INFO *data,
5689                    const struct nls_table *nls_codepage, int remap)
5690 {
5691         TRANSACTION2_SPI_REQ *pSMB = NULL;
5692         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5693         int name_len;
5694         int rc = 0;
5695         int bytes_returned = 0;
5696         char *data_offset;
5697         __u16 params, param_offset, offset, byte_count, count;
5698
5699         cFYI(1, "In SetTimes");
5700
5701 SetTimesRetry:
5702         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5703                       (void **) &pSMBr);
5704         if (rc)
5705                 return rc;
5706
5707         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5708                 name_len =
5709                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5710                                        PATH_MAX, nls_codepage, remap);
5711                 name_len++;     /* trailing null */
5712                 name_len *= 2;
5713         } else {        /* BB improve the check for buffer overruns BB */
5714                 name_len = strnlen(fileName, PATH_MAX);
5715                 name_len++;     /* trailing null */
5716                 strncpy(pSMB->FileName, fileName, name_len);
5717         }
5718
5719         params = 6 + name_len;
5720         count = sizeof(FILE_BASIC_INFO);
5721         pSMB->MaxParameterCount = cpu_to_le16(2);
5722         /* BB find max SMB PDU from sess structure BB */
5723         pSMB->MaxDataCount = cpu_to_le16(1000);
5724         pSMB->MaxSetupCount = 0;
5725         pSMB->Reserved = 0;
5726         pSMB->Flags = 0;
5727         pSMB->Timeout = 0;
5728         pSMB->Reserved2 = 0;
5729         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5730                                 InformationLevel) - 4;
5731         offset = param_offset + params;
5732         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5733         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5734         pSMB->DataOffset = cpu_to_le16(offset);
5735         pSMB->SetupCount = 1;
5736         pSMB->Reserved3 = 0;
5737         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5738         byte_count = 3 /* pad */  + params + count;
5739
5740         pSMB->DataCount = cpu_to_le16(count);
5741         pSMB->ParameterCount = cpu_to_le16(params);
5742         pSMB->TotalDataCount = pSMB->DataCount;
5743         pSMB->TotalParameterCount = pSMB->ParameterCount;
5744         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5745                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5746         else
5747                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5748         pSMB->Reserved4 = 0;
5749         inc_rfc1001_len(pSMB, byte_count);
5750         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5751         pSMB->ByteCount = cpu_to_le16(byte_count);
5752         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5753                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5754         if (rc)
5755                 cFYI(1, "SetPathInfo (times) returned %d", rc);
5756
5757         cifs_buf_release(pSMB);
5758
5759         if (rc == -EAGAIN)
5760                 goto SetTimesRetry;
5761
5762         return rc;
5763 }
5764
5765 /* Can not be used to set time stamps yet (due to old DOS time format) */
5766 /* Can be used to set attributes */
5767 #if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
5768           handling it anyway and NT4 was what we thought it would be needed for
5769           Do not delete it until we prove whether needed for Win9x though */
5770 int
5771 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5772                 __u16 dos_attrs, const struct nls_table *nls_codepage)
5773 {
5774         SETATTR_REQ *pSMB = NULL;
5775         SETATTR_RSP *pSMBr = NULL;
5776         int rc = 0;
5777         int bytes_returned;
5778         int name_len;
5779
5780         cFYI(1, "In SetAttrLegacy");
5781
5782 SetAttrLgcyRetry:
5783         rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5784                       (void **) &pSMBr);
5785         if (rc)
5786                 return rc;
5787
5788         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5789                 name_len =
5790                         ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5791                                        PATH_MAX, nls_codepage);
5792                 name_len++;     /* trailing null */
5793                 name_len *= 2;
5794         } else {        /* BB improve the check for buffer overruns BB */
5795                 name_len = strnlen(fileName, PATH_MAX);
5796                 name_len++;     /* trailing null */
5797                 strncpy(pSMB->fileName, fileName, name_len);
5798         }
5799         pSMB->attr = cpu_to_le16(dos_attrs);
5800         pSMB->BufferFormat = 0x04;
5801         inc_rfc1001_len(pSMB, name_len + 1);
5802         pSMB->ByteCount = cpu_to_le16(name_len + 1);
5803         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5804                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5805         if (rc)
5806                 cFYI(1, "Error in LegacySetAttr = %d", rc);
5807
5808         cifs_buf_release(pSMB);
5809
5810         if (rc == -EAGAIN)
5811                 goto SetAttrLgcyRetry;
5812
5813         return rc;
5814 }
5815 #endif /* temporarily unneeded SetAttr legacy function */
5816
5817 static void
5818 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5819                         const struct cifs_unix_set_info_args *args)
5820 {
5821         u64 mode = args->mode;
5822
5823         /*
5824          * Samba server ignores set of file size to zero due to bugs in some
5825          * older clients, but we should be precise - we use SetFileSize to
5826          * set file size and do not want to truncate file size to zero
5827          * accidentally as happened on one Samba server beta by putting
5828          * zero instead of -1 here
5829          */
5830         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5831         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5832         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5833         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5834         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5835         data_offset->Uid = cpu_to_le64(args->uid);
5836         data_offset->Gid = cpu_to_le64(args->gid);
5837         /* better to leave device as zero when it is  */
5838         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5839         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5840         data_offset->Permissions = cpu_to_le64(mode);
5841
5842         if (S_ISREG(mode))
5843                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5844         else if (S_ISDIR(mode))
5845                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5846         else if (S_ISLNK(mode))
5847                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5848         else if (S_ISCHR(mode))
5849                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5850         else if (S_ISBLK(mode))
5851                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5852         else if (S_ISFIFO(mode))
5853                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5854         else if (S_ISSOCK(mode))
5855                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5856 }
5857
5858 int
5859 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5860                        const struct cifs_unix_set_info_args *args,
5861                        u16 fid, u32 pid_of_opener)
5862 {
5863         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5864         char *data_offset;
5865         int rc = 0;
5866         u16 params, param_offset, offset, byte_count, count;
5867
5868         cFYI(1, "Set Unix Info (via SetFileInfo)");
5869         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5870
5871         if (rc)
5872                 return rc;
5873
5874         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5875         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5876
5877         params = 6;
5878         pSMB->MaxSetupCount = 0;
5879         pSMB->Reserved = 0;
5880         pSMB->Flags = 0;
5881         pSMB->Timeout = 0;
5882         pSMB->Reserved2 = 0;
5883         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5884         offset = param_offset + params;
5885
5886         data_offset = (char *)pSMB +
5887                         offsetof(struct smb_hdr, Protocol) + offset;
5888
5889         count = sizeof(FILE_UNIX_BASIC_INFO);
5890
5891         pSMB->MaxParameterCount = cpu_to_le16(2);
5892         /* BB find max SMB PDU from sess */
5893         pSMB->MaxDataCount = cpu_to_le16(1000);
5894         pSMB->SetupCount = 1;
5895         pSMB->Reserved3 = 0;
5896         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5897         byte_count = 3 /* pad */  + params + count;
5898         pSMB->DataCount = cpu_to_le16(count);
5899         pSMB->ParameterCount = cpu_to_le16(params);
5900         pSMB->TotalDataCount = pSMB->DataCount;
5901         pSMB->TotalParameterCount = pSMB->ParameterCount;
5902         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5903         pSMB->DataOffset = cpu_to_le16(offset);
5904         pSMB->Fid = fid;
5905         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5906         pSMB->Reserved4 = 0;
5907         inc_rfc1001_len(pSMB, byte_count);
5908         pSMB->ByteCount = cpu_to_le16(byte_count);
5909
5910         cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5911
5912         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5913         if (rc)
5914                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5915
5916         /* Note: On -EAGAIN error only caller can retry on handle based calls
5917                 since file handle passed in no longer valid */
5918
5919         return rc;
5920 }
5921
5922 int
5923 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5924                        const char *file_name,
5925                        const struct cifs_unix_set_info_args *args,
5926                        const struct nls_table *nls_codepage, int remap)
5927 {
5928         TRANSACTION2_SPI_REQ *pSMB = NULL;
5929         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5930         int name_len;
5931         int rc = 0;
5932         int bytes_returned = 0;
5933         FILE_UNIX_BASIC_INFO *data_offset;
5934         __u16 params, param_offset, offset, count, byte_count;
5935
5936         cFYI(1, "In SetUID/GID/Mode");
5937 setPermsRetry:
5938         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5939                       (void **) &pSMBr);
5940         if (rc)
5941                 return rc;
5942
5943         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5944                 name_len =
5945                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5946                                        PATH_MAX, nls_codepage, remap);
5947                 name_len++;     /* trailing null */
5948                 name_len *= 2;
5949         } else {        /* BB improve the check for buffer overruns BB */
5950                 name_len = strnlen(file_name, PATH_MAX);
5951                 name_len++;     /* trailing null */
5952                 strncpy(pSMB->FileName, file_name, name_len);
5953         }
5954
5955         params = 6 + name_len;
5956         count = sizeof(FILE_UNIX_BASIC_INFO);
5957         pSMB->MaxParameterCount = cpu_to_le16(2);
5958         /* BB find max SMB PDU from sess structure BB */
5959         pSMB->MaxDataCount = cpu_to_le16(1000);
5960         pSMB->MaxSetupCount = 0;
5961         pSMB->Reserved = 0;
5962         pSMB->Flags = 0;
5963         pSMB->Timeout = 0;
5964         pSMB->Reserved2 = 0;
5965         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5966                                 InformationLevel) - 4;
5967         offset = param_offset + params;
5968         data_offset =
5969             (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
5970                                       offset);
5971         memset(data_offset, 0, count);
5972         pSMB->DataOffset = cpu_to_le16(offset);
5973         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5974         pSMB->SetupCount = 1;
5975         pSMB->Reserved3 = 0;
5976         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5977         byte_count = 3 /* pad */  + params + count;
5978         pSMB->ParameterCount = cpu_to_le16(params);
5979         pSMB->DataCount = cpu_to_le16(count);
5980         pSMB->TotalParameterCount = pSMB->ParameterCount;
5981         pSMB->TotalDataCount = pSMB->DataCount;
5982         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5983         pSMB->Reserved4 = 0;
5984         inc_rfc1001_len(pSMB, byte_count);
5985
5986         cifs_fill_unix_set_info(data_offset, args);
5987
5988         pSMB->ByteCount = cpu_to_le16(byte_count);
5989         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5990                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5991         if (rc)
5992                 cFYI(1, "SetPathInfo (perms) returned %d", rc);
5993
5994         cifs_buf_release(pSMB);
5995         if (rc == -EAGAIN)
5996                 goto setPermsRetry;
5997         return rc;
5998 }
5999
6000 #ifdef CONFIG_CIFS_XATTR
6001 /*
6002  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6003  * function used by listxattr and getxattr type calls. When ea_name is set,
6004  * it looks for that attribute name and stuffs that value into the EAData
6005  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6006  * buffer. In both cases, the return value is either the length of the
6007  * resulting data or a negative error code. If EAData is a NULL pointer then
6008  * the data isn't copied to it, but the length is returned.
6009  */
6010 ssize_t
6011 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6012                 const unsigned char *searchName, const unsigned char *ea_name,
6013                 char *EAData, size_t buf_size,
6014                 const struct nls_table *nls_codepage, int remap)
6015 {
6016                 /* BB assumes one setup word */
6017         TRANSACTION2_QPI_REQ *pSMB = NULL;
6018         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6019         int rc = 0;
6020         int bytes_returned;
6021         int list_len;
6022         struct fealist *ea_response_data;
6023         struct fea *temp_fea;
6024         char *temp_ptr;
6025         char *end_of_smb;
6026         __u16 params, byte_count, data_offset;
6027         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6028
6029         cFYI(1, "In Query All EAs path %s", searchName);
6030 QAllEAsRetry:
6031         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6032                       (void **) &pSMBr);
6033         if (rc)
6034                 return rc;
6035
6036         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6037                 list_len =
6038                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6039                                        PATH_MAX, nls_codepage, remap);
6040                 list_len++;     /* trailing null */
6041                 list_len *= 2;
6042         } else {        /* BB improve the check for buffer overruns BB */
6043                 list_len = strnlen(searchName, PATH_MAX);
6044                 list_len++;     /* trailing null */
6045                 strncpy(pSMB->FileName, searchName, list_len);
6046         }
6047
6048         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6049         pSMB->TotalDataCount = 0;
6050         pSMB->MaxParameterCount = cpu_to_le16(2);
6051         /* BB find exact max SMB PDU from sess structure BB */
6052         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6053         pSMB->MaxSetupCount = 0;
6054         pSMB->Reserved = 0;
6055         pSMB->Flags = 0;
6056         pSMB->Timeout = 0;
6057         pSMB->Reserved2 = 0;
6058         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6059         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6060         pSMB->DataCount = 0;
6061         pSMB->DataOffset = 0;
6062         pSMB->SetupCount = 1;
6063         pSMB->Reserved3 = 0;
6064         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6065         byte_count = params + 1 /* pad */ ;
6066         pSMB->TotalParameterCount = cpu_to_le16(params);
6067         pSMB->ParameterCount = pSMB->TotalParameterCount;
6068         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6069         pSMB->Reserved4 = 0;
6070         inc_rfc1001_len(pSMB, byte_count);
6071         pSMB->ByteCount = cpu_to_le16(byte_count);
6072
6073         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6074                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6075         if (rc) {
6076                 cFYI(1, "Send error in QueryAllEAs = %d", rc);
6077                 goto QAllEAsOut;
6078         }
6079
6080
6081         /* BB also check enough total bytes returned */
6082         /* BB we need to improve the validity checking
6083         of these trans2 responses */
6084
6085         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6086         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6087                 rc = -EIO;      /* bad smb */
6088                 goto QAllEAsOut;
6089         }
6090
6091         /* check that length of list is not more than bcc */
6092         /* check that each entry does not go beyond length
6093            of list */
6094         /* check that each element of each entry does not
6095            go beyond end of list */
6096         /* validate_trans2_offsets() */
6097         /* BB check if start of smb + data_offset > &bcc+ bcc */
6098
6099         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6100         ea_response_data = (struct fealist *)
6101                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6102
6103         list_len = le32_to_cpu(ea_response_data->list_len);
6104         cFYI(1, "ea length %d", list_len);
6105         if (list_len <= 8) {
6106                 cFYI(1, "empty EA list returned from server");
6107                 goto QAllEAsOut;
6108         }
6109
6110         /* make sure list_len doesn't go past end of SMB */
6111         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6112         if ((char *)ea_response_data + list_len > end_of_smb) {
6113                 cFYI(1, "EA list appears to go beyond SMB");
6114                 rc = -EIO;
6115                 goto QAllEAsOut;
6116         }
6117
6118         /* account for ea list len */
6119         list_len -= 4;
6120         temp_fea = ea_response_data->list;
6121         temp_ptr = (char *)temp_fea;
6122         while (list_len > 0) {
6123                 unsigned int name_len;
6124                 __u16 value_len;
6125
6126                 list_len -= 4;
6127                 temp_ptr += 4;
6128                 /* make sure we can read name_len and value_len */
6129                 if (list_len < 0) {
6130                         cFYI(1, "EA entry goes beyond length of list");
6131                         rc = -EIO;
6132                         goto QAllEAsOut;
6133                 }
6134
6135                 name_len = temp_fea->name_len;
6136                 value_len = le16_to_cpu(temp_fea->value_len);
6137                 list_len -= name_len + 1 + value_len;
6138                 if (list_len < 0) {
6139                         cFYI(1, "EA entry goes beyond length of list");
6140                         rc = -EIO;
6141                         goto QAllEAsOut;
6142                 }
6143
6144                 if (ea_name) {
6145                         if (ea_name_len == name_len &&
6146                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6147                                 temp_ptr += name_len + 1;
6148                                 rc = value_len;
6149                                 if (buf_size == 0)
6150                                         goto QAllEAsOut;
6151                                 if ((size_t)value_len > buf_size) {
6152                                         rc = -ERANGE;
6153                                         goto QAllEAsOut;
6154                                 }
6155                                 memcpy(EAData, temp_ptr, value_len);
6156                                 goto QAllEAsOut;
6157                         }
6158                 } else {
6159                         /* account for prefix user. and trailing null */
6160                         rc += (5 + 1 + name_len);
6161                         if (rc < (int) buf_size) {
6162                                 memcpy(EAData, "user.", 5);
6163                                 EAData += 5;
6164                                 memcpy(EAData, temp_ptr, name_len);
6165                                 EAData += name_len;
6166                                 /* null terminate name */
6167                                 *EAData = 0;
6168                                 ++EAData;
6169                         } else if (buf_size == 0) {
6170                                 /* skip copy - calc size only */
6171                         } else {
6172                                 /* stop before overrun buffer */
6173                                 rc = -ERANGE;
6174                                 break;
6175                         }
6176                 }
6177                 temp_ptr += name_len + 1 + value_len;
6178                 temp_fea = (struct fea *)temp_ptr;
6179         }
6180
6181         /* didn't find the named attribute */
6182         if (ea_name)
6183                 rc = -ENODATA;
6184
6185 QAllEAsOut:
6186         cifs_buf_release(pSMB);
6187         if (rc == -EAGAIN)
6188                 goto QAllEAsRetry;
6189
6190         return (ssize_t)rc;
6191 }
6192
6193 int
6194 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6195              const char *fileName, const char *ea_name, const void *ea_value,
6196              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6197              int remap)
6198 {
6199         struct smb_com_transaction2_spi_req *pSMB = NULL;
6200         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6201         struct fealist *parm_data;
6202         int name_len;
6203         int rc = 0;
6204         int bytes_returned = 0;
6205         __u16 params, param_offset, byte_count, offset, count;
6206
6207         cFYI(1, "In SetEA");
6208 SetEARetry:
6209         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6210                       (void **) &pSMBr);
6211         if (rc)
6212                 return rc;
6213
6214         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6215                 name_len =
6216                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6217                                        PATH_MAX, nls_codepage, remap);
6218                 name_len++;     /* trailing null */
6219                 name_len *= 2;
6220         } else {        /* BB improve the check for buffer overruns BB */
6221                 name_len = strnlen(fileName, PATH_MAX);
6222                 name_len++;     /* trailing null */
6223                 strncpy(pSMB->FileName, fileName, name_len);
6224         }
6225
6226         params = 6 + name_len;
6227
6228         /* done calculating parms using name_len of file name,
6229         now use name_len to calculate length of ea name
6230         we are going to create in the inode xattrs */
6231         if (ea_name == NULL)
6232                 name_len = 0;
6233         else
6234                 name_len = strnlen(ea_name, 255);
6235
6236         count = sizeof(*parm_data) + ea_value_len + name_len;
6237         pSMB->MaxParameterCount = cpu_to_le16(2);
6238         /* BB find max SMB PDU from sess */
6239         pSMB->MaxDataCount = cpu_to_le16(1000);
6240         pSMB->MaxSetupCount = 0;
6241         pSMB->Reserved = 0;
6242         pSMB->Flags = 0;
6243         pSMB->Timeout = 0;
6244         pSMB->Reserved2 = 0;
6245         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6246                                 InformationLevel) - 4;
6247         offset = param_offset + params;
6248         pSMB->InformationLevel =
6249                 cpu_to_le16(SMB_SET_FILE_EA);
6250
6251         parm_data =
6252                 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6253                                        offset);
6254         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6255         pSMB->DataOffset = cpu_to_le16(offset);
6256         pSMB->SetupCount = 1;
6257         pSMB->Reserved3 = 0;
6258         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6259         byte_count = 3 /* pad */  + params + count;
6260         pSMB->DataCount = cpu_to_le16(count);
6261         parm_data->list_len = cpu_to_le32(count);
6262         parm_data->list[0].EA_flags = 0;
6263         /* we checked above that name len is less than 255 */
6264         parm_data->list[0].name_len = (__u8)name_len;
6265         /* EA names are always ASCII */
6266         if (ea_name)
6267                 strncpy(parm_data->list[0].name, ea_name, name_len);
6268         parm_data->list[0].name[name_len] = 0;
6269         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6270         /* caller ensures that ea_value_len is less than 64K but
6271         we need to ensure that it fits within the smb */
6272
6273         /*BB add length check to see if it would fit in
6274              negotiated SMB buffer size BB */
6275         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6276         if (ea_value_len)
6277                 memcpy(parm_data->list[0].name+name_len+1,
6278                        ea_value, ea_value_len);
6279
6280         pSMB->TotalDataCount = pSMB->DataCount;
6281         pSMB->ParameterCount = cpu_to_le16(params);
6282         pSMB->TotalParameterCount = pSMB->ParameterCount;
6283         pSMB->Reserved4 = 0;
6284         inc_rfc1001_len(pSMB, byte_count);
6285         pSMB->ByteCount = cpu_to_le16(byte_count);
6286         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6287                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6288         if (rc)
6289                 cFYI(1, "SetPathInfo (EA) returned %d", rc);
6290
6291         cifs_buf_release(pSMB);
6292
6293         if (rc == -EAGAIN)
6294                 goto SetEARetry;
6295
6296         return rc;
6297 }
6298 #endif
6299
6300 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6301 /*
6302  *      Years ago the kernel added a "dnotify" function for Samba server,
6303  *      to allow network clients (such as Windows) to display updated
6304  *      lists of files in directory listings automatically when
6305  *      files are added by one user when another user has the
6306  *      same directory open on their desktop.  The Linux cifs kernel
6307  *      client hooked into the kernel side of this interface for
6308  *      the same reason, but ironically when the VFS moved from
6309  *      "dnotify" to "inotify" it became harder to plug in Linux
6310  *      network file system clients (the most obvious use case
6311  *      for notify interfaces is when multiple users can update
6312  *      the contents of the same directory - exactly what network
6313  *      file systems can do) although the server (Samba) could
6314  *      still use it.  For the short term we leave the worker
6315  *      function ifdeffed out (below) until inotify is fixed
6316  *      in the VFS to make it easier to plug in network file
6317  *      system clients.  If inotify turns out to be permanently
6318  *      incompatible for network fs clients, we could instead simply
6319  *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
6320  */
6321 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6322                   const int notify_subdirs, const __u16 netfid,
6323                   __u32 filter, struct file *pfile, int multishot,
6324                   const struct nls_table *nls_codepage)
6325 {
6326         int rc = 0;
6327         struct smb_com_transaction_change_notify_req *pSMB = NULL;
6328         struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6329         struct dir_notify_req *dnotify_req;
6330         int bytes_returned;
6331
6332         cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
6333         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6334                       (void **) &pSMBr);
6335         if (rc)
6336                 return rc;
6337
6338         pSMB->TotalParameterCount = 0 ;
6339         pSMB->TotalDataCount = 0;
6340         pSMB->MaxParameterCount = cpu_to_le32(2);
6341         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6342         pSMB->MaxSetupCount = 4;
6343         pSMB->Reserved = 0;
6344         pSMB->ParameterOffset = 0;
6345         pSMB->DataCount = 0;
6346         pSMB->DataOffset = 0;
6347         pSMB->SetupCount = 4; /* single byte does not need le conversion */
6348         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6349         pSMB->ParameterCount = pSMB->TotalParameterCount;
6350         if (notify_subdirs)
6351                 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6352         pSMB->Reserved2 = 0;
6353         pSMB->CompletionFilter = cpu_to_le32(filter);
6354         pSMB->Fid = netfid; /* file handle always le */
6355         pSMB->ByteCount = 0;
6356
6357         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6358                          (struct smb_hdr *)pSMBr, &bytes_returned,
6359                          CIFS_ASYNC_OP);
6360         if (rc) {
6361                 cFYI(1, "Error in Notify = %d", rc);
6362         } else {
6363                 /* Add file to outstanding requests */
6364                 /* BB change to kmem cache alloc */
6365                 dnotify_req = kmalloc(
6366                                                 sizeof(struct dir_notify_req),
6367                                                  GFP_KERNEL);
6368                 if (dnotify_req) {
6369                         dnotify_req->Pid = pSMB->hdr.Pid;
6370                         dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6371                         dnotify_req->Mid = pSMB->hdr.Mid;
6372                         dnotify_req->Tid = pSMB->hdr.Tid;
6373                         dnotify_req->Uid = pSMB->hdr.Uid;
6374                         dnotify_req->netfid = netfid;
6375                         dnotify_req->pfile = pfile;
6376                         dnotify_req->filter = filter;
6377                         dnotify_req->multishot = multishot;
6378                         spin_lock(&GlobalMid_Lock);
6379                         list_add_tail(&dnotify_req->lhead,
6380                                         &GlobalDnotifyReqList);
6381                         spin_unlock(&GlobalMid_Lock);
6382                 } else
6383                         rc = -ENOMEM;
6384         }
6385         cifs_buf_release(pSMB);
6386         return rc;
6387 }
6388 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */