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