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