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