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