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