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