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