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