6371b9eebdad82009070fc120687bef373812053
[releases.git] / 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->ses_status != SES_GOOD) || (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 readahead 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) ?
2562                                  le64_to_cpu(parm_data->length) - 1 : 0);
2563                         pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2564                 }
2565         }
2566
2567 plk_err_exit:
2568         free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2569
2570         /* Note: On -EAGAIN error only caller can retry on handle based calls
2571            since file handle passed in no longer valid */
2572
2573         return rc;
2574 }
2575
2576
2577 int
2578 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2579 {
2580         int rc = 0;
2581         CLOSE_REQ *pSMB = NULL;
2582         cifs_dbg(FYI, "In CIFSSMBClose\n");
2583
2584 /* do not retry on dead session on close */
2585         rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2586         if (rc == -EAGAIN)
2587                 return 0;
2588         if (rc)
2589                 return rc;
2590
2591         pSMB->FileID = (__u16) smb_file_id;
2592         pSMB->LastWriteTime = 0xFFFFFFFF;
2593         pSMB->ByteCount = 0;
2594         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2595         cifs_small_buf_release(pSMB);
2596         cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2597         if (rc) {
2598                 if (rc != -EINTR) {
2599                         /* EINTR is expected when user ctl-c to kill app */
2600                         cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2601                 }
2602         }
2603
2604         /* Since session is dead, file will be closed on server already */
2605         if (rc == -EAGAIN)
2606                 rc = 0;
2607
2608         return rc;
2609 }
2610
2611 int
2612 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2613 {
2614         int rc = 0;
2615         FLUSH_REQ *pSMB = NULL;
2616         cifs_dbg(FYI, "In CIFSSMBFlush\n");
2617
2618         rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2619         if (rc)
2620                 return rc;
2621
2622         pSMB->FileID = (__u16) smb_file_id;
2623         pSMB->ByteCount = 0;
2624         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2625         cifs_small_buf_release(pSMB);
2626         cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2627         if (rc)
2628                 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2629
2630         return rc;
2631 }
2632
2633 int
2634 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2635               const char *from_name, const char *to_name,
2636               struct cifs_sb_info *cifs_sb)
2637 {
2638         int rc = 0;
2639         RENAME_REQ *pSMB = NULL;
2640         RENAME_RSP *pSMBr = NULL;
2641         int bytes_returned;
2642         int name_len, name_len2;
2643         __u16 count;
2644         int remap = cifs_remap(cifs_sb);
2645
2646         cifs_dbg(FYI, "In CIFSSMBRename\n");
2647 renameRetry:
2648         rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2649                       (void **) &pSMBr);
2650         if (rc)
2651                 return rc;
2652
2653         pSMB->BufferFormat = 0x04;
2654         pSMB->SearchAttributes =
2655             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2656                         ATTR_DIRECTORY);
2657
2658         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2659                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2660                                               from_name, PATH_MAX,
2661                                               cifs_sb->local_nls, remap);
2662                 name_len++;     /* trailing null */
2663                 name_len *= 2;
2664                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2665         /* protocol requires ASCII signature byte on Unicode string */
2666                 pSMB->OldFileName[name_len + 1] = 0x00;
2667                 name_len2 =
2668                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2669                                        to_name, PATH_MAX, cifs_sb->local_nls,
2670                                        remap);
2671                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2672                 name_len2 *= 2; /* convert to bytes */
2673         } else {
2674                 name_len = copy_path_name(pSMB->OldFileName, from_name);
2675                 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2676                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2677                 name_len2++;    /* signature byte */
2678         }
2679
2680         count = 1 /* 1st signature byte */  + name_len + name_len2;
2681         inc_rfc1001_len(pSMB, count);
2682         pSMB->ByteCount = cpu_to_le16(count);
2683
2684         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2685                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2686         cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2687         if (rc)
2688                 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2689
2690         cifs_buf_release(pSMB);
2691
2692         if (rc == -EAGAIN)
2693                 goto renameRetry;
2694
2695         return rc;
2696 }
2697
2698 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2699                 int netfid, const char *target_name,
2700                 const struct nls_table *nls_codepage, int remap)
2701 {
2702         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2703         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2704         struct set_file_rename *rename_info;
2705         char *data_offset;
2706         char dummy_string[30];
2707         int rc = 0;
2708         int bytes_returned = 0;
2709         int len_of_str;
2710         __u16 params, param_offset, offset, count, byte_count;
2711
2712         cifs_dbg(FYI, "Rename to File by handle\n");
2713         rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2714                         (void **) &pSMBr);
2715         if (rc)
2716                 return rc;
2717
2718         params = 6;
2719         pSMB->MaxSetupCount = 0;
2720         pSMB->Reserved = 0;
2721         pSMB->Flags = 0;
2722         pSMB->Timeout = 0;
2723         pSMB->Reserved2 = 0;
2724         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2725         offset = param_offset + params;
2726
2727         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2728         data_offset = (char *)(pSMB) + offset + 4;
2729         rename_info = (struct set_file_rename *) data_offset;
2730         pSMB->MaxParameterCount = cpu_to_le16(2);
2731         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2732         pSMB->SetupCount = 1;
2733         pSMB->Reserved3 = 0;
2734         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2735         byte_count = 3 /* pad */  + params;
2736         pSMB->ParameterCount = cpu_to_le16(params);
2737         pSMB->TotalParameterCount = pSMB->ParameterCount;
2738         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2739         pSMB->DataOffset = cpu_to_le16(offset);
2740         /* construct random name ".cifs_tmp<inodenum><mid>" */
2741         rename_info->overwrite = cpu_to_le32(1);
2742         rename_info->root_fid  = 0;
2743         /* unicode only call */
2744         if (target_name == NULL) {
2745                 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2746                 len_of_str =
2747                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2748                                         dummy_string, 24, nls_codepage, remap);
2749         } else {
2750                 len_of_str =
2751                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2752                                         target_name, PATH_MAX, nls_codepage,
2753                                         remap);
2754         }
2755         rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2756         count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2757         byte_count += count;
2758         pSMB->DataCount = cpu_to_le16(count);
2759         pSMB->TotalDataCount = pSMB->DataCount;
2760         pSMB->Fid = netfid;
2761         pSMB->InformationLevel =
2762                 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2763         pSMB->Reserved4 = 0;
2764         inc_rfc1001_len(pSMB, byte_count);
2765         pSMB->ByteCount = cpu_to_le16(byte_count);
2766         rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2767                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2768         cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2769         if (rc)
2770                 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2771                          rc);
2772
2773         cifs_buf_release(pSMB);
2774
2775         /* Note: On -EAGAIN error only caller can retry on handle based calls
2776                 since file handle passed in no longer valid */
2777
2778         return rc;
2779 }
2780
2781 int
2782 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2783             const char *fromName, const __u16 target_tid, const char *toName,
2784             const int flags, const struct nls_table *nls_codepage, int remap)
2785 {
2786         int rc = 0;
2787         COPY_REQ *pSMB = NULL;
2788         COPY_RSP *pSMBr = NULL;
2789         int bytes_returned;
2790         int name_len, name_len2;
2791         __u16 count;
2792
2793         cifs_dbg(FYI, "In CIFSSMBCopy\n");
2794 copyRetry:
2795         rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2796                         (void **) &pSMBr);
2797         if (rc)
2798                 return rc;
2799
2800         pSMB->BufferFormat = 0x04;
2801         pSMB->Tid2 = target_tid;
2802
2803         pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2804
2805         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2806                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2807                                               fromName, PATH_MAX, nls_codepage,
2808                                               remap);
2809                 name_len++;     /* trailing null */
2810                 name_len *= 2;
2811                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2812                 /* protocol requires ASCII signature byte on Unicode string */
2813                 pSMB->OldFileName[name_len + 1] = 0x00;
2814                 name_len2 =
2815                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2816                                        toName, PATH_MAX, nls_codepage, remap);
2817                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2818                 name_len2 *= 2; /* convert to bytes */
2819         } else {
2820                 name_len = copy_path_name(pSMB->OldFileName, fromName);
2821                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2822                 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2823                 name_len2++;    /* signature byte */
2824         }
2825
2826         count = 1 /* 1st signature byte */  + name_len + name_len2;
2827         inc_rfc1001_len(pSMB, count);
2828         pSMB->ByteCount = cpu_to_le16(count);
2829
2830         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2831                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2832         if (rc) {
2833                 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2834                          rc, le16_to_cpu(pSMBr->CopyCount));
2835         }
2836         cifs_buf_release(pSMB);
2837
2838         if (rc == -EAGAIN)
2839                 goto copyRetry;
2840
2841         return rc;
2842 }
2843
2844 int
2845 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2846                       const char *fromName, const char *toName,
2847                       const struct nls_table *nls_codepage, int remap)
2848 {
2849         TRANSACTION2_SPI_REQ *pSMB = NULL;
2850         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2851         char *data_offset;
2852         int name_len;
2853         int name_len_target;
2854         int rc = 0;
2855         int bytes_returned = 0;
2856         __u16 params, param_offset, offset, byte_count;
2857
2858         cifs_dbg(FYI, "In Symlink Unix style\n");
2859 createSymLinkRetry:
2860         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2861                       (void **) &pSMBr);
2862         if (rc)
2863                 return rc;
2864
2865         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2866                 name_len =
2867                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2868                                 /* find define for this maxpathcomponent */
2869                                         PATH_MAX, nls_codepage, remap);
2870                 name_len++;     /* trailing null */
2871                 name_len *= 2;
2872
2873         } else {
2874                 name_len = copy_path_name(pSMB->FileName, fromName);
2875         }
2876         params = 6 + name_len;
2877         pSMB->MaxSetupCount = 0;
2878         pSMB->Reserved = 0;
2879         pSMB->Flags = 0;
2880         pSMB->Timeout = 0;
2881         pSMB->Reserved2 = 0;
2882         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2883                                 InformationLevel) - 4;
2884         offset = param_offset + params;
2885
2886         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2887         data_offset = (char *)pSMB + offset + 4;
2888         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2889                 name_len_target =
2890                     cifsConvertToUTF16((__le16 *) data_offset, toName,
2891                                 /* find define for this maxpathcomponent */
2892                                         PATH_MAX, nls_codepage, remap);
2893                 name_len_target++;      /* trailing null */
2894                 name_len_target *= 2;
2895         } else {
2896                 name_len_target = copy_path_name(data_offset, toName);
2897         }
2898
2899         pSMB->MaxParameterCount = cpu_to_le16(2);
2900         /* BB find exact max on data count below from sess */
2901         pSMB->MaxDataCount = cpu_to_le16(1000);
2902         pSMB->SetupCount = 1;
2903         pSMB->Reserved3 = 0;
2904         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2905         byte_count = 3 /* pad */  + params + name_len_target;
2906         pSMB->DataCount = cpu_to_le16(name_len_target);
2907         pSMB->ParameterCount = cpu_to_le16(params);
2908         pSMB->TotalDataCount = pSMB->DataCount;
2909         pSMB->TotalParameterCount = pSMB->ParameterCount;
2910         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2911         pSMB->DataOffset = cpu_to_le16(offset);
2912         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2913         pSMB->Reserved4 = 0;
2914         inc_rfc1001_len(pSMB, byte_count);
2915         pSMB->ByteCount = cpu_to_le16(byte_count);
2916         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2917                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2918         cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2919         if (rc)
2920                 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2921                          rc);
2922
2923         cifs_buf_release(pSMB);
2924
2925         if (rc == -EAGAIN)
2926                 goto createSymLinkRetry;
2927
2928         return rc;
2929 }
2930
2931 int
2932 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2933                        const char *fromName, const char *toName,
2934                        const struct nls_table *nls_codepage, int remap)
2935 {
2936         TRANSACTION2_SPI_REQ *pSMB = NULL;
2937         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2938         char *data_offset;
2939         int name_len;
2940         int name_len_target;
2941         int rc = 0;
2942         int bytes_returned = 0;
2943         __u16 params, param_offset, offset, byte_count;
2944
2945         cifs_dbg(FYI, "In Create Hard link Unix style\n");
2946 createHardLinkRetry:
2947         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2948                       (void **) &pSMBr);
2949         if (rc)
2950                 return rc;
2951
2952         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2953                 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2954                                               PATH_MAX, nls_codepage, remap);
2955                 name_len++;     /* trailing null */
2956                 name_len *= 2;
2957
2958         } else {
2959                 name_len = copy_path_name(pSMB->FileName, toName);
2960         }
2961         params = 6 + name_len;
2962         pSMB->MaxSetupCount = 0;
2963         pSMB->Reserved = 0;
2964         pSMB->Flags = 0;
2965         pSMB->Timeout = 0;
2966         pSMB->Reserved2 = 0;
2967         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2968                                 InformationLevel) - 4;
2969         offset = param_offset + params;
2970
2971         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2972         data_offset = (char *)pSMB + offset + 4;
2973         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2974                 name_len_target =
2975                     cifsConvertToUTF16((__le16 *) data_offset, fromName,
2976                                        PATH_MAX, nls_codepage, remap);
2977                 name_len_target++;      /* trailing null */
2978                 name_len_target *= 2;
2979         } else {
2980                 name_len_target = copy_path_name(data_offset, fromName);
2981         }
2982
2983         pSMB->MaxParameterCount = cpu_to_le16(2);
2984         /* BB find exact max on data count below from sess*/
2985         pSMB->MaxDataCount = cpu_to_le16(1000);
2986         pSMB->SetupCount = 1;
2987         pSMB->Reserved3 = 0;
2988         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2989         byte_count = 3 /* pad */  + params + name_len_target;
2990         pSMB->ParameterCount = cpu_to_le16(params);
2991         pSMB->TotalParameterCount = pSMB->ParameterCount;
2992         pSMB->DataCount = cpu_to_le16(name_len_target);
2993         pSMB->TotalDataCount = pSMB->DataCount;
2994         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2995         pSMB->DataOffset = cpu_to_le16(offset);
2996         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2997         pSMB->Reserved4 = 0;
2998         inc_rfc1001_len(pSMB, byte_count);
2999         pSMB->ByteCount = cpu_to_le16(byte_count);
3000         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3001                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3002         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3003         if (rc)
3004                 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3005                          rc);
3006
3007         cifs_buf_release(pSMB);
3008         if (rc == -EAGAIN)
3009                 goto createHardLinkRetry;
3010
3011         return rc;
3012 }
3013
3014 int
3015 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3016                    const char *from_name, const char *to_name,
3017                    struct cifs_sb_info *cifs_sb)
3018 {
3019         int rc = 0;
3020         NT_RENAME_REQ *pSMB = NULL;
3021         RENAME_RSP *pSMBr = NULL;
3022         int bytes_returned;
3023         int name_len, name_len2;
3024         __u16 count;
3025         int remap = cifs_remap(cifs_sb);
3026
3027         cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3028 winCreateHardLinkRetry:
3029
3030         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3031                       (void **) &pSMBr);
3032         if (rc)
3033                 return rc;
3034
3035         pSMB->SearchAttributes =
3036             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3037                         ATTR_DIRECTORY);
3038         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3039         pSMB->ClusterCount = 0;
3040
3041         pSMB->BufferFormat = 0x04;
3042
3043         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3044                 name_len =
3045                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3046                                        PATH_MAX, cifs_sb->local_nls, remap);
3047                 name_len++;     /* trailing null */
3048                 name_len *= 2;
3049
3050                 /* protocol specifies ASCII buffer format (0x04) for unicode */
3051                 pSMB->OldFileName[name_len] = 0x04;
3052                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3053                 name_len2 =
3054                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3055                                        to_name, PATH_MAX, cifs_sb->local_nls,
3056                                        remap);
3057                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
3058                 name_len2 *= 2; /* convert to bytes */
3059         } else {
3060                 name_len = copy_path_name(pSMB->OldFileName, from_name);
3061                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
3062                 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3063                 name_len2++;    /* signature byte */
3064         }
3065
3066         count = 1 /* string type byte */  + name_len + name_len2;
3067         inc_rfc1001_len(pSMB, count);
3068         pSMB->ByteCount = cpu_to_le16(count);
3069
3070         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3071                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3072         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3073         if (rc)
3074                 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3075
3076         cifs_buf_release(pSMB);
3077         if (rc == -EAGAIN)
3078                 goto winCreateHardLinkRetry;
3079
3080         return rc;
3081 }
3082
3083 int
3084 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3085                         const unsigned char *searchName, char **symlinkinfo,
3086                         const struct nls_table *nls_codepage, int remap)
3087 {
3088 /* SMB_QUERY_FILE_UNIX_LINK */
3089         TRANSACTION2_QPI_REQ *pSMB = NULL;
3090         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3091         int rc = 0;
3092         int bytes_returned;
3093         int name_len;
3094         __u16 params, byte_count;
3095         char *data_start;
3096
3097         cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3098
3099 querySymLinkRetry:
3100         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3101                       (void **) &pSMBr);
3102         if (rc)
3103                 return rc;
3104
3105         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3106                 name_len =
3107                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3108                                            searchName, PATH_MAX, nls_codepage,
3109                                            remap);
3110                 name_len++;     /* trailing null */
3111                 name_len *= 2;
3112         } else {
3113                 name_len = copy_path_name(pSMB->FileName, searchName);
3114         }
3115
3116         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3117         pSMB->TotalDataCount = 0;
3118         pSMB->MaxParameterCount = cpu_to_le16(2);
3119         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3120         pSMB->MaxSetupCount = 0;
3121         pSMB->Reserved = 0;
3122         pSMB->Flags = 0;
3123         pSMB->Timeout = 0;
3124         pSMB->Reserved2 = 0;
3125         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3126         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3127         pSMB->DataCount = 0;
3128         pSMB->DataOffset = 0;
3129         pSMB->SetupCount = 1;
3130         pSMB->Reserved3 = 0;
3131         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3132         byte_count = params + 1 /* pad */ ;
3133         pSMB->TotalParameterCount = cpu_to_le16(params);
3134         pSMB->ParameterCount = pSMB->TotalParameterCount;
3135         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3136         pSMB->Reserved4 = 0;
3137         inc_rfc1001_len(pSMB, byte_count);
3138         pSMB->ByteCount = cpu_to_le16(byte_count);
3139
3140         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3141                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3142         if (rc) {
3143                 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3144         } else {
3145                 /* decode response */
3146
3147                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3148                 /* BB also check enough total bytes returned */
3149                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3150                         rc = -EIO;
3151                 else {
3152                         bool is_unicode;
3153                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3154
3155                         data_start = ((char *) &pSMBr->hdr.Protocol) +
3156                                            le16_to_cpu(pSMBr->t2.DataOffset);
3157
3158                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3159                                 is_unicode = true;
3160                         else
3161                                 is_unicode = false;
3162
3163                         /* BB FIXME investigate remapping reserved chars here */
3164                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
3165                                         count, is_unicode, nls_codepage);
3166                         if (!*symlinkinfo)
3167                                 rc = -ENOMEM;
3168                 }
3169         }
3170         cifs_buf_release(pSMB);
3171         if (rc == -EAGAIN)
3172                 goto querySymLinkRetry;
3173         return rc;
3174 }
3175
3176 /*
3177  *      Recent Windows versions now create symlinks more frequently
3178  *      and they use the "reparse point" mechanism below.  We can of course
3179  *      do symlinks nicely to Samba and other servers which support the
3180  *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3181  *      "MF" symlinks optionally, but for recent Windows we really need to
3182  *      reenable the code below and fix the cifs_symlink callers to handle this.
3183  *      In the interim this code has been moved to its own config option so
3184  *      it is not compiled in by default until callers fixed up and more tested.
3185  */
3186 int
3187 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3188                     __u16 fid, char **symlinkinfo,
3189                     const struct nls_table *nls_codepage)
3190 {
3191         int rc = 0;
3192         int bytes_returned;
3193         struct smb_com_transaction_ioctl_req *pSMB;
3194         struct smb_com_transaction_ioctl_rsp *pSMBr;
3195         bool is_unicode;
3196         unsigned int sub_len;
3197         char *sub_start;
3198         struct reparse_symlink_data *reparse_buf;
3199         struct reparse_posix_data *posix_buf;
3200         __u32 data_offset, data_count;
3201         char *end_of_smb;
3202
3203         cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3204         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3205                       (void **) &pSMBr);
3206         if (rc)
3207                 return rc;
3208
3209         pSMB->TotalParameterCount = 0 ;
3210         pSMB->TotalDataCount = 0;
3211         pSMB->MaxParameterCount = cpu_to_le32(2);
3212         /* BB find exact data count max from sess structure BB */
3213         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3214         pSMB->MaxSetupCount = 4;
3215         pSMB->Reserved = 0;
3216         pSMB->ParameterOffset = 0;
3217         pSMB->DataCount = 0;
3218         pSMB->DataOffset = 0;
3219         pSMB->SetupCount = 4;
3220         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3221         pSMB->ParameterCount = pSMB->TotalParameterCount;
3222         pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3223         pSMB->IsFsctl = 1; /* FSCTL */
3224         pSMB->IsRootFlag = 0;
3225         pSMB->Fid = fid; /* file handle always le */
3226         pSMB->ByteCount = 0;
3227
3228         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3229                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3230         if (rc) {
3231                 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3232                 goto qreparse_out;
3233         }
3234
3235         data_offset = le32_to_cpu(pSMBr->DataOffset);
3236         data_count = le32_to_cpu(pSMBr->DataCount);
3237         if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3238                 /* BB also check enough total bytes returned */
3239                 rc = -EIO;      /* bad smb */
3240                 goto qreparse_out;
3241         }
3242         if (!data_count || (data_count > 2048)) {
3243                 rc = -EIO;
3244                 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3245                 goto qreparse_out;
3246         }
3247         end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3248         reparse_buf = (struct reparse_symlink_data *)
3249                                 ((char *)&pSMBr->hdr.Protocol + data_offset);
3250         if ((char *)reparse_buf >= end_of_smb) {
3251                 rc = -EIO;
3252                 goto qreparse_out;
3253         }
3254         if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3255                 cifs_dbg(FYI, "NFS style reparse tag\n");
3256                 posix_buf =  (struct reparse_posix_data *)reparse_buf;
3257
3258                 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3259                         cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3260                                  le64_to_cpu(posix_buf->InodeType));
3261                         rc = -EOPNOTSUPP;
3262                         goto qreparse_out;
3263                 }
3264                 is_unicode = true;
3265                 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3266                 if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3267                         cifs_dbg(FYI, "reparse buf beyond SMB\n");
3268                         rc = -EIO;
3269                         goto qreparse_out;
3270                 }
3271                 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3272                                 sub_len, is_unicode, nls_codepage);
3273                 goto qreparse_out;
3274         } else if (reparse_buf->ReparseTag !=
3275                         cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3276                 rc = -EOPNOTSUPP;
3277                 goto qreparse_out;
3278         }
3279
3280         /* Reparse tag is NTFS symlink */
3281         sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3282                                 reparse_buf->PathBuffer;
3283         sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3284         if (sub_start + sub_len > end_of_smb) {
3285                 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3286                 rc = -EIO;
3287                 goto qreparse_out;
3288         }
3289         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3290                 is_unicode = true;
3291         else
3292                 is_unicode = false;
3293
3294         /* BB FIXME investigate remapping reserved chars here */
3295         *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3296                                                nls_codepage);
3297         if (!*symlinkinfo)
3298                 rc = -ENOMEM;
3299 qreparse_out:
3300         cifs_buf_release(pSMB);
3301
3302         /*
3303          * Note: On -EAGAIN error only caller can retry on handle based calls
3304          * since file handle passed in no longer valid.
3305          */
3306         return rc;
3307 }
3308
3309 int
3310 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3311                     __u16 fid)
3312 {
3313         int rc = 0;
3314         int bytes_returned;
3315         struct smb_com_transaction_compr_ioctl_req *pSMB;
3316         struct smb_com_transaction_ioctl_rsp *pSMBr;
3317
3318         cifs_dbg(FYI, "Set compression for %u\n", fid);
3319         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3320                       (void **) &pSMBr);
3321         if (rc)
3322                 return rc;
3323
3324         pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3325
3326         pSMB->TotalParameterCount = 0;
3327         pSMB->TotalDataCount = cpu_to_le32(2);
3328         pSMB->MaxParameterCount = 0;
3329         pSMB->MaxDataCount = 0;
3330         pSMB->MaxSetupCount = 4;
3331         pSMB->Reserved = 0;
3332         pSMB->ParameterOffset = 0;
3333         pSMB->DataCount = cpu_to_le32(2);
3334         pSMB->DataOffset =
3335                 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3336                                 compression_state) - 4);  /* 84 */
3337         pSMB->SetupCount = 4;
3338         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3339         pSMB->ParameterCount = 0;
3340         pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3341         pSMB->IsFsctl = 1; /* FSCTL */
3342         pSMB->IsRootFlag = 0;
3343         pSMB->Fid = fid; /* file handle always le */
3344         /* 3 byte pad, followed by 2 byte compress state */
3345         pSMB->ByteCount = cpu_to_le16(5);
3346         inc_rfc1001_len(pSMB, 5);
3347
3348         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3349                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3350         if (rc)
3351                 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3352
3353         cifs_buf_release(pSMB);
3354
3355         /*
3356          * Note: On -EAGAIN error only caller can retry on handle based calls
3357          * since file handle passed in no longer valid.
3358          */
3359         return rc;
3360 }
3361
3362
3363 #ifdef CONFIG_CIFS_POSIX
3364
3365 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3366 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3367                              struct cifs_posix_ace *cifs_ace)
3368 {
3369         /* u8 cifs fields do not need le conversion */
3370         ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3371         ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3372         ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3373 /*
3374         cifs_dbg(FYI, "perm %d tag %d id %d\n",
3375                  ace->e_perm, ace->e_tag, ace->e_id);
3376 */
3377
3378         return;
3379 }
3380
3381 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3382 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3383                                const int acl_type, const int size_of_data_area)
3384 {
3385         int size =  0;
3386         int i;
3387         __u16 count;
3388         struct cifs_posix_ace *pACE;
3389         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3390         struct posix_acl_xattr_header *local_acl = (void *)trgt;
3391
3392         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3393                 return -EOPNOTSUPP;
3394
3395         if (acl_type == ACL_TYPE_ACCESS) {
3396                 count = le16_to_cpu(cifs_acl->access_entry_count);
3397                 pACE = &cifs_acl->ace_array[0];
3398                 size = sizeof(struct cifs_posix_acl);
3399                 size += sizeof(struct cifs_posix_ace) * count;
3400                 /* check if we would go beyond end of SMB */
3401                 if (size_of_data_area < size) {
3402                         cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3403                                  size_of_data_area, size);
3404                         return -EINVAL;
3405                 }
3406         } else if (acl_type == ACL_TYPE_DEFAULT) {
3407                 count = le16_to_cpu(cifs_acl->access_entry_count);
3408                 size = sizeof(struct cifs_posix_acl);
3409                 size += sizeof(struct cifs_posix_ace) * count;
3410 /* skip past access ACEs to get to default ACEs */
3411                 pACE = &cifs_acl->ace_array[count];
3412                 count = le16_to_cpu(cifs_acl->default_entry_count);
3413                 size += sizeof(struct cifs_posix_ace) * count;
3414                 /* check if we would go beyond end of SMB */
3415                 if (size_of_data_area < size)
3416                         return -EINVAL;
3417         } else {
3418                 /* illegal type */
3419                 return -EINVAL;
3420         }
3421
3422         size = posix_acl_xattr_size(count);
3423         if ((buflen == 0) || (local_acl == NULL)) {
3424                 /* used to query ACL EA size */
3425         } else if (size > buflen) {
3426                 return -ERANGE;
3427         } else /* buffer big enough */ {
3428                 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3429
3430                 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3431                 for (i = 0; i < count ; i++) {
3432                         cifs_convert_ace(&ace[i], pACE);
3433                         pACE++;
3434                 }
3435         }
3436         return size;
3437 }
3438
3439 static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3440                                      const struct posix_acl_xattr_entry *local_ace)
3441 {
3442         cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3443         cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
3444         /* BB is there a better way to handle the large uid? */
3445         if (local_ace->e_id == cpu_to_le32(-1)) {
3446         /* Probably no need to le convert -1 on any arch but can not hurt */
3447                 cifs_ace->cifs_uid = cpu_to_le64(-1);
3448         } else
3449                 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3450 /*
3451         cifs_dbg(FYI, "perm %d tag %d id %d\n",
3452                  ace->e_perm, ace->e_tag, ace->e_id);
3453 */
3454 }
3455
3456 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3457 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3458                                const int buflen, const int acl_type)
3459 {
3460         __u16 rc = 0;
3461         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3462         struct posix_acl_xattr_header *local_acl = (void *)pACL;
3463         struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3464         int count;
3465         int i;
3466
3467         if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3468                 return 0;
3469
3470         count = posix_acl_xattr_count((size_t)buflen);
3471         cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3472                  count, buflen, le32_to_cpu(local_acl->a_version));
3473         if (le32_to_cpu(local_acl->a_version) != 2) {
3474                 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3475                          le32_to_cpu(local_acl->a_version));
3476                 return 0;
3477         }
3478         cifs_acl->version = cpu_to_le16(1);
3479         if (acl_type == ACL_TYPE_ACCESS) {
3480                 cifs_acl->access_entry_count = cpu_to_le16(count);
3481                 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3482         } else if (acl_type == ACL_TYPE_DEFAULT) {
3483                 cifs_acl->default_entry_count = cpu_to_le16(count);
3484                 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3485         } else {
3486                 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3487                 return 0;
3488         }
3489         for (i = 0; i < count; i++)
3490                 convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3491         if (rc == 0) {
3492                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3493                 rc += sizeof(struct cifs_posix_acl);
3494                 /* BB add check to make sure ACL does not overflow SMB */
3495         }
3496         return rc;
3497 }
3498
3499 int
3500 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3501                    const unsigned char *searchName,
3502                    char *acl_inf, const int buflen, const int acl_type,
3503                    const struct nls_table *nls_codepage, int remap)
3504 {
3505 /* SMB_QUERY_POSIX_ACL */
3506         TRANSACTION2_QPI_REQ *pSMB = NULL;
3507         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3508         int rc = 0;
3509         int bytes_returned;
3510         int name_len;
3511         __u16 params, byte_count;
3512
3513         cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3514
3515 queryAclRetry:
3516         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3517                 (void **) &pSMBr);
3518         if (rc)
3519                 return rc;
3520
3521         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3522                 name_len =
3523                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3524                                            searchName, PATH_MAX, nls_codepage,
3525                                            remap);
3526                 name_len++;     /* trailing null */
3527                 name_len *= 2;
3528                 pSMB->FileName[name_len] = 0;
3529                 pSMB->FileName[name_len+1] = 0;
3530         } else {
3531                 name_len = copy_path_name(pSMB->FileName, searchName);
3532         }
3533
3534         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3535         pSMB->TotalDataCount = 0;
3536         pSMB->MaxParameterCount = cpu_to_le16(2);
3537         /* BB find exact max data count below from sess structure BB */
3538         pSMB->MaxDataCount = cpu_to_le16(4000);
3539         pSMB->MaxSetupCount = 0;
3540         pSMB->Reserved = 0;
3541         pSMB->Flags = 0;
3542         pSMB->Timeout = 0;
3543         pSMB->Reserved2 = 0;
3544         pSMB->ParameterOffset = cpu_to_le16(
3545                 offsetof(struct smb_com_transaction2_qpi_req,
3546                          InformationLevel) - 4);
3547         pSMB->DataCount = 0;
3548         pSMB->DataOffset = 0;
3549         pSMB->SetupCount = 1;
3550         pSMB->Reserved3 = 0;
3551         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3552         byte_count = params + 1 /* pad */ ;
3553         pSMB->TotalParameterCount = cpu_to_le16(params);
3554         pSMB->ParameterCount = pSMB->TotalParameterCount;
3555         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3556         pSMB->Reserved4 = 0;
3557         inc_rfc1001_len(pSMB, byte_count);
3558         pSMB->ByteCount = cpu_to_le16(byte_count);
3559
3560         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3561                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3562         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3563         if (rc) {
3564                 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3565         } else {
3566                 /* decode response */
3567
3568                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3569                 /* BB also check enough total bytes returned */
3570                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3571                         rc = -EIO;      /* bad smb */
3572                 else {
3573                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3574                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3575                         rc = cifs_copy_posix_acl(acl_inf,
3576                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3577                                 buflen, acl_type, count);
3578                 }
3579         }
3580         cifs_buf_release(pSMB);
3581         if (rc == -EAGAIN)
3582                 goto queryAclRetry;
3583         return rc;
3584 }
3585
3586 int
3587 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3588                    const unsigned char *fileName,
3589                    const char *local_acl, const int buflen,
3590                    const int acl_type,
3591                    const struct nls_table *nls_codepage, int remap)
3592 {
3593         struct smb_com_transaction2_spi_req *pSMB = NULL;
3594         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3595         char *parm_data;
3596         int name_len;
3597         int rc = 0;
3598         int bytes_returned = 0;
3599         __u16 params, byte_count, data_count, param_offset, offset;
3600
3601         cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3602 setAclRetry:
3603         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3604                       (void **) &pSMBr);
3605         if (rc)
3606                 return rc;
3607         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3608                 name_len =
3609                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3610                                            PATH_MAX, nls_codepage, remap);
3611                 name_len++;     /* trailing null */
3612                 name_len *= 2;
3613         } else {
3614                 name_len = copy_path_name(pSMB->FileName, fileName);
3615         }
3616         params = 6 + name_len;
3617         pSMB->MaxParameterCount = cpu_to_le16(2);
3618         /* BB find max SMB size from sess */
3619         pSMB->MaxDataCount = cpu_to_le16(1000);
3620         pSMB->MaxSetupCount = 0;
3621         pSMB->Reserved = 0;
3622         pSMB->Flags = 0;
3623         pSMB->Timeout = 0;
3624         pSMB->Reserved2 = 0;
3625         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3626                                 InformationLevel) - 4;
3627         offset = param_offset + params;
3628         parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3629         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3630
3631         /* convert to on the wire format for POSIX ACL */
3632         data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3633
3634         if (data_count == 0) {
3635                 rc = -EOPNOTSUPP;
3636                 goto setACLerrorExit;
3637         }
3638         pSMB->DataOffset = cpu_to_le16(offset);
3639         pSMB->SetupCount = 1;
3640         pSMB->Reserved3 = 0;
3641         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3642         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3643         byte_count = 3 /* pad */  + params + data_count;
3644         pSMB->DataCount = cpu_to_le16(data_count);
3645         pSMB->TotalDataCount = pSMB->DataCount;
3646         pSMB->ParameterCount = cpu_to_le16(params);
3647         pSMB->TotalParameterCount = pSMB->ParameterCount;
3648         pSMB->Reserved4 = 0;
3649         inc_rfc1001_len(pSMB, byte_count);
3650         pSMB->ByteCount = cpu_to_le16(byte_count);
3651         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3652                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3653         if (rc)
3654                 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3655
3656 setACLerrorExit:
3657         cifs_buf_release(pSMB);
3658         if (rc == -EAGAIN)
3659                 goto setAclRetry;
3660         return rc;
3661 }
3662
3663 /* BB fix tabs in this function FIXME BB */
3664 int
3665 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3666                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3667 {
3668         int rc = 0;
3669         struct smb_t2_qfi_req *pSMB = NULL;
3670         struct smb_t2_qfi_rsp *pSMBr = NULL;
3671         int bytes_returned;
3672         __u16 params, byte_count;
3673
3674         cifs_dbg(FYI, "In GetExtAttr\n");
3675         if (tcon == NULL)
3676                 return -ENODEV;
3677
3678 GetExtAttrRetry:
3679         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3680                         (void **) &pSMBr);
3681         if (rc)
3682                 return rc;
3683
3684         params = 2 /* level */ + 2 /* fid */;
3685         pSMB->t2.TotalDataCount = 0;
3686         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3687         /* BB find exact max data count below from sess structure BB */
3688         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3689         pSMB->t2.MaxSetupCount = 0;
3690         pSMB->t2.Reserved = 0;
3691         pSMB->t2.Flags = 0;
3692         pSMB->t2.Timeout = 0;
3693         pSMB->t2.Reserved2 = 0;
3694         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3695                                                Fid) - 4);
3696         pSMB->t2.DataCount = 0;
3697         pSMB->t2.DataOffset = 0;
3698         pSMB->t2.SetupCount = 1;
3699         pSMB->t2.Reserved3 = 0;
3700         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3701         byte_count = params + 1 /* pad */ ;
3702         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3703         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3704         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3705         pSMB->Pad = 0;
3706         pSMB->Fid = netfid;
3707         inc_rfc1001_len(pSMB, byte_count);
3708         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3709
3710         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3711                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3712         if (rc) {
3713                 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3714         } else {
3715                 /* decode response */
3716                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3717                 /* BB also check enough total bytes returned */
3718                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3719                         /* If rc should we check for EOPNOSUPP and
3720                            disable the srvino flag? or in caller? */
3721                         rc = -EIO;      /* bad smb */
3722                 else {
3723                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3724                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3725                         struct file_chattr_info *pfinfo;
3726                         /* BB Do we need a cast or hash here ? */
3727                         if (count != 16) {
3728                                 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3729                                 rc = -EIO;
3730                                 goto GetExtAttrOut;
3731                         }
3732                         pfinfo = (struct file_chattr_info *)
3733                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3734                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3735                         *pMask = le64_to_cpu(pfinfo->mask);
3736                 }
3737         }
3738 GetExtAttrOut:
3739         cifs_buf_release(pSMB);
3740         if (rc == -EAGAIN)
3741                 goto GetExtAttrRetry;
3742         return rc;
3743 }
3744
3745 #endif /* CONFIG_POSIX */
3746
3747 /*
3748  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3749  * all NT TRANSACTS that we init here have total parm and data under about 400
3750  * bytes (to fit in small cifs buffer size), which is the case so far, it
3751  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3752  * returned setup area) and MaxParameterCount (returned parms size) must be set
3753  * by caller
3754  */
3755 static int
3756 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3757                    const int parm_len, struct cifs_tcon *tcon,
3758                    void **ret_buf)
3759 {
3760         int rc;
3761         __u32 temp_offset;
3762         struct smb_com_ntransact_req *pSMB;
3763
3764         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3765                                 (void **)&pSMB);
3766         if (rc)
3767                 return rc;
3768         *ret_buf = (void *)pSMB;
3769         pSMB->Reserved = 0;
3770         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3771         pSMB->TotalDataCount  = 0;
3772         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3773         pSMB->ParameterCount = pSMB->TotalParameterCount;
3774         pSMB->DataCount  = pSMB->TotalDataCount;
3775         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3776                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3777         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3778         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3779         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3780         pSMB->SubCommand = cpu_to_le16(sub_command);
3781         return 0;
3782 }
3783
3784 static int
3785 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3786                    __u32 *pparmlen, __u32 *pdatalen)
3787 {
3788         char *end_of_smb;
3789         __u32 data_count, data_offset, parm_count, parm_offset;
3790         struct smb_com_ntransact_rsp *pSMBr;
3791         u16 bcc;
3792
3793         *pdatalen = 0;
3794         *pparmlen = 0;
3795
3796         if (buf == NULL)
3797                 return -EINVAL;
3798
3799         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3800
3801         bcc = get_bcc(&pSMBr->hdr);
3802         end_of_smb = 2 /* sizeof byte count */ + bcc +
3803                         (char *)&pSMBr->ByteCount;
3804
3805         data_offset = le32_to_cpu(pSMBr->DataOffset);
3806         data_count = le32_to_cpu(pSMBr->DataCount);
3807         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3808         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3809
3810         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3811         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3812
3813         /* should we also check that parm and data areas do not overlap? */
3814         if (*ppparm > end_of_smb) {
3815                 cifs_dbg(FYI, "parms start after end of smb\n");
3816                 return -EINVAL;
3817         } else if (parm_count + *ppparm > end_of_smb) {
3818                 cifs_dbg(FYI, "parm end after end of smb\n");
3819                 return -EINVAL;
3820         } else if (*ppdata > end_of_smb) {
3821                 cifs_dbg(FYI, "data starts after end of smb\n");
3822                 return -EINVAL;
3823         } else if (data_count + *ppdata > end_of_smb) {
3824                 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3825                          *ppdata, data_count, (data_count + *ppdata),
3826                          end_of_smb, pSMBr);
3827                 return -EINVAL;
3828         } else if (parm_count + data_count > bcc) {
3829                 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3830                 return -EINVAL;
3831         }
3832         *pdatalen = data_count;
3833         *pparmlen = parm_count;
3834         return 0;
3835 }
3836
3837 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3838 int
3839 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3840                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3841 {
3842         int rc = 0;
3843         int buf_type = 0;
3844         QUERY_SEC_DESC_REQ *pSMB;
3845         struct kvec iov[1];
3846         struct kvec rsp_iov;
3847
3848         cifs_dbg(FYI, "GetCifsACL\n");
3849
3850         *pbuflen = 0;
3851         *acl_inf = NULL;
3852
3853         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3854                         8 /* parm len */, tcon, (void **) &pSMB);
3855         if (rc)
3856                 return rc;
3857
3858         pSMB->MaxParameterCount = cpu_to_le32(4);
3859         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3860         pSMB->MaxSetupCount = 0;
3861         pSMB->Fid = fid; /* file handle always le */
3862         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3863                                      CIFS_ACL_DACL);
3864         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3865         inc_rfc1001_len(pSMB, 11);
3866         iov[0].iov_base = (char *)pSMB;
3867         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3868
3869         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3870                           0, &rsp_iov);
3871         cifs_small_buf_release(pSMB);
3872         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3873         if (rc) {
3874                 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3875         } else {                /* decode response */
3876                 __le32 *parm;
3877                 __u32 parm_len;
3878                 __u32 acl_len;
3879                 struct smb_com_ntransact_rsp *pSMBr;
3880                 char *pdata;
3881
3882 /* validate_nttransact */
3883                 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3884                                         &pdata, &parm_len, pbuflen);
3885                 if (rc)
3886                         goto qsec_out;
3887                 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3888
3889                 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3890                          pSMBr, parm, *acl_inf);
3891
3892                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3893                         rc = -EIO;      /* bad smb */
3894                         *pbuflen = 0;
3895                         goto qsec_out;
3896                 }
3897
3898 /* BB check that data area is minimum length and as big as acl_len */
3899
3900                 acl_len = le32_to_cpu(*parm);
3901                 if (acl_len != *pbuflen) {
3902                         cifs_dbg(VFS, "acl length %d does not match %d\n",
3903                                  acl_len, *pbuflen);
3904                         if (*pbuflen > acl_len)
3905                                 *pbuflen = acl_len;
3906                 }
3907
3908                 /* check if buffer is big enough for the acl
3909                    header followed by the smallest SID */
3910                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3911                     (*pbuflen >= 64 * 1024)) {
3912                         cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3913                         rc = -EINVAL;
3914                         *pbuflen = 0;
3915                 } else {
3916                         *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3917                         if (*acl_inf == NULL) {
3918                                 *pbuflen = 0;
3919                                 rc = -ENOMEM;
3920                         }
3921                 }
3922         }
3923 qsec_out:
3924         free_rsp_buf(buf_type, rsp_iov.iov_base);
3925         return rc;
3926 }
3927
3928 int
3929 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3930                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3931 {
3932         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3933         int rc = 0;
3934         int bytes_returned = 0;
3935         SET_SEC_DESC_REQ *pSMB = NULL;
3936         void *pSMBr;
3937
3938 setCifsAclRetry:
3939         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3940         if (rc)
3941                 return rc;
3942
3943         pSMB->MaxSetupCount = 0;
3944         pSMB->Reserved = 0;
3945
3946         param_count = 8;
3947         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3948         data_count = acllen;
3949         data_offset = param_offset + param_count;
3950         byte_count = 3 /* pad */  + param_count;
3951
3952         pSMB->DataCount = cpu_to_le32(data_count);
3953         pSMB->TotalDataCount = pSMB->DataCount;
3954         pSMB->MaxParameterCount = cpu_to_le32(4);
3955         pSMB->MaxDataCount = cpu_to_le32(16384);
3956         pSMB->ParameterCount = cpu_to_le32(param_count);
3957         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3958         pSMB->TotalParameterCount = pSMB->ParameterCount;
3959         pSMB->DataOffset = cpu_to_le32(data_offset);
3960         pSMB->SetupCount = 0;
3961         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3962         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3963
3964         pSMB->Fid = fid; /* file handle always le */
3965         pSMB->Reserved2 = 0;
3966         pSMB->AclFlags = cpu_to_le32(aclflag);
3967
3968         if (pntsd && acllen) {
3969                 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3970                                 data_offset, pntsd, acllen);
3971                 inc_rfc1001_len(pSMB, byte_count + data_count);
3972         } else
3973                 inc_rfc1001_len(pSMB, byte_count);
3974
3975         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3976                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3977
3978         cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3979                  bytes_returned, rc);
3980         if (rc)
3981                 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3982         cifs_buf_release(pSMB);
3983
3984         if (rc == -EAGAIN)
3985                 goto setCifsAclRetry;
3986
3987         return (rc);
3988 }
3989
3990
3991 /* Legacy Query Path Information call for lookup to old servers such
3992    as Win9x/WinME */
3993 int
3994 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3995                     const char *search_name, FILE_ALL_INFO *data,
3996                     const struct nls_table *nls_codepage, int remap)
3997 {
3998         QUERY_INFORMATION_REQ *pSMB;
3999         QUERY_INFORMATION_RSP *pSMBr;
4000         int rc = 0;
4001         int bytes_returned;
4002         int name_len;
4003
4004         cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4005 QInfRetry:
4006         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4007                       (void **) &pSMBr);
4008         if (rc)
4009                 return rc;
4010
4011         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4012                 name_len =
4013                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4014                                            search_name, PATH_MAX, nls_codepage,
4015                                            remap);
4016                 name_len++;     /* trailing null */
4017                 name_len *= 2;
4018         } else {
4019                 name_len = copy_path_name(pSMB->FileName, search_name);
4020         }
4021         pSMB->BufferFormat = 0x04;
4022         name_len++; /* account for buffer type byte */
4023         inc_rfc1001_len(pSMB, (__u16)name_len);
4024         pSMB->ByteCount = cpu_to_le16(name_len);
4025
4026         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4027                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4028         if (rc) {
4029                 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4030         } else if (data) {
4031                 struct timespec64 ts;
4032                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4033
4034                 /* decode response */
4035                 /* BB FIXME - add time zone adjustment BB */
4036                 memset(data, 0, sizeof(FILE_ALL_INFO));
4037                 ts.tv_nsec = 0;
4038                 ts.tv_sec = time;
4039                 /* decode time fields */
4040                 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4041                 data->LastWriteTime = data->ChangeTime;
4042                 data->LastAccessTime = 0;
4043                 data->AllocationSize =
4044                         cpu_to_le64(le32_to_cpu(pSMBr->size));
4045                 data->EndOfFile = data->AllocationSize;
4046                 data->Attributes =
4047                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
4048         } else
4049                 rc = -EIO; /* bad buffer passed in */
4050
4051         cifs_buf_release(pSMB);
4052
4053         if (rc == -EAGAIN)
4054                 goto QInfRetry;
4055
4056         return rc;
4057 }
4058
4059 int
4060 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4061                  u16 netfid, FILE_ALL_INFO *pFindData)
4062 {
4063         struct smb_t2_qfi_req *pSMB = NULL;
4064         struct smb_t2_qfi_rsp *pSMBr = NULL;
4065         int rc = 0;
4066         int bytes_returned;
4067         __u16 params, byte_count;
4068
4069 QFileInfoRetry:
4070         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4071                       (void **) &pSMBr);
4072         if (rc)
4073                 return rc;
4074
4075         params = 2 /* level */ + 2 /* fid */;
4076         pSMB->t2.TotalDataCount = 0;
4077         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4078         /* BB find exact max data count below from sess structure BB */
4079         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4080         pSMB->t2.MaxSetupCount = 0;
4081         pSMB->t2.Reserved = 0;
4082         pSMB->t2.Flags = 0;
4083         pSMB->t2.Timeout = 0;
4084         pSMB->t2.Reserved2 = 0;
4085         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4086                                                Fid) - 4);
4087         pSMB->t2.DataCount = 0;
4088         pSMB->t2.DataOffset = 0;
4089         pSMB->t2.SetupCount = 1;
4090         pSMB->t2.Reserved3 = 0;
4091         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4092         byte_count = params + 1 /* pad */ ;
4093         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4094         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4095         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4096         pSMB->Pad = 0;
4097         pSMB->Fid = netfid;
4098         inc_rfc1001_len(pSMB, byte_count);
4099         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4100
4101         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4102                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4103         if (rc) {
4104                 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4105         } else {                /* decode response */
4106                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4107
4108                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4109                         rc = -EIO;
4110                 else if (get_bcc(&pSMBr->hdr) < 40)
4111                         rc = -EIO;      /* bad smb */
4112                 else if (pFindData) {
4113                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4114                         memcpy((char *) pFindData,
4115                                (char *) &pSMBr->hdr.Protocol +
4116                                data_offset, sizeof(FILE_ALL_INFO));
4117                 } else
4118                     rc = -ENOMEM;
4119         }
4120         cifs_buf_release(pSMB);
4121         if (rc == -EAGAIN)
4122                 goto QFileInfoRetry;
4123
4124         return rc;
4125 }
4126
4127 int
4128 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4129                  const char *search_name, FILE_ALL_INFO *data,
4130                  int legacy /* old style infolevel */,
4131                  const struct nls_table *nls_codepage, int remap)
4132 {
4133         /* level 263 SMB_QUERY_FILE_ALL_INFO */
4134         TRANSACTION2_QPI_REQ *pSMB = NULL;
4135         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4136         int rc = 0;
4137         int bytes_returned;
4138         int name_len;
4139         __u16 params, byte_count;
4140
4141         /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4142 QPathInfoRetry:
4143         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4144                       (void **) &pSMBr);
4145         if (rc)
4146                 return rc;
4147
4148         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4149                 name_len =
4150                     cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4151                                        PATH_MAX, nls_codepage, remap);
4152                 name_len++;     /* trailing null */
4153                 name_len *= 2;
4154         } else {
4155                 name_len = copy_path_name(pSMB->FileName, search_name);
4156         }
4157
4158         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4159         pSMB->TotalDataCount = 0;
4160         pSMB->MaxParameterCount = cpu_to_le16(2);
4161         /* BB find exact max SMB PDU from sess structure BB */
4162         pSMB->MaxDataCount = cpu_to_le16(4000);
4163         pSMB->MaxSetupCount = 0;
4164         pSMB->Reserved = 0;
4165         pSMB->Flags = 0;
4166         pSMB->Timeout = 0;
4167         pSMB->Reserved2 = 0;
4168         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4169         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4170         pSMB->DataCount = 0;
4171         pSMB->DataOffset = 0;
4172         pSMB->SetupCount = 1;
4173         pSMB->Reserved3 = 0;
4174         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4175         byte_count = params + 1 /* pad */ ;
4176         pSMB->TotalParameterCount = cpu_to_le16(params);
4177         pSMB->ParameterCount = pSMB->TotalParameterCount;
4178         if (legacy)
4179                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4180         else
4181                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4182         pSMB->Reserved4 = 0;
4183         inc_rfc1001_len(pSMB, byte_count);
4184         pSMB->ByteCount = cpu_to_le16(byte_count);
4185
4186         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4187                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4188         if (rc) {
4189                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4190         } else {                /* decode response */
4191                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4192
4193                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4194                         rc = -EIO;
4195                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4196                         rc = -EIO;      /* bad smb */
4197                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4198                         rc = -EIO;  /* 24 or 26 expected but we do not read
4199                                         last field */
4200                 else if (data) {
4201                         int size;
4202                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4203
4204                         /*
4205                          * On legacy responses we do not read the last field,
4206                          * EAsize, fortunately since it varies by subdialect and
4207                          * also note it differs on Set vs Get, ie two bytes or 4
4208                          * bytes depending but we don't care here.
4209                          */
4210                         if (legacy)
4211                                 size = sizeof(FILE_INFO_STANDARD);
4212                         else
4213                                 size = sizeof(FILE_ALL_INFO);
4214                         memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4215                                data_offset, size);
4216                 } else
4217                     rc = -ENOMEM;
4218         }
4219         cifs_buf_release(pSMB);
4220         if (rc == -EAGAIN)
4221                 goto QPathInfoRetry;
4222
4223         return rc;
4224 }
4225
4226 int
4227 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4228                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4229 {
4230         struct smb_t2_qfi_req *pSMB = NULL;
4231         struct smb_t2_qfi_rsp *pSMBr = NULL;
4232         int rc = 0;
4233         int bytes_returned;
4234         __u16 params, byte_count;
4235
4236 UnixQFileInfoRetry:
4237         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4238                       (void **) &pSMBr);
4239         if (rc)
4240                 return rc;
4241
4242         params = 2 /* level */ + 2 /* fid */;
4243         pSMB->t2.TotalDataCount = 0;
4244         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4245         /* BB find exact max data count below from sess structure BB */
4246         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4247         pSMB->t2.MaxSetupCount = 0;
4248         pSMB->t2.Reserved = 0;
4249         pSMB->t2.Flags = 0;
4250         pSMB->t2.Timeout = 0;
4251         pSMB->t2.Reserved2 = 0;
4252         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4253                                                Fid) - 4);
4254         pSMB->t2.DataCount = 0;
4255         pSMB->t2.DataOffset = 0;
4256         pSMB->t2.SetupCount = 1;
4257         pSMB->t2.Reserved3 = 0;
4258         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4259         byte_count = params + 1 /* pad */ ;
4260         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4261         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4262         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4263         pSMB->Pad = 0;
4264         pSMB->Fid = netfid;
4265         inc_rfc1001_len(pSMB, byte_count);
4266         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4267
4268         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4269                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4270         if (rc) {
4271                 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4272         } else {                /* decode response */
4273                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4274
4275                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4276                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4277                         rc = -EIO;      /* bad smb */
4278                 } else {
4279                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4280                         memcpy((char *) pFindData,
4281                                (char *) &pSMBr->hdr.Protocol +
4282                                data_offset,
4283                                sizeof(FILE_UNIX_BASIC_INFO));
4284                 }
4285         }
4286
4287         cifs_buf_release(pSMB);
4288         if (rc == -EAGAIN)
4289                 goto UnixQFileInfoRetry;
4290
4291         return rc;
4292 }
4293
4294 int
4295 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4296                      const unsigned char *searchName,
4297                      FILE_UNIX_BASIC_INFO *pFindData,
4298                      const struct nls_table *nls_codepage, int remap)
4299 {
4300 /* SMB_QUERY_FILE_UNIX_BASIC */
4301         TRANSACTION2_QPI_REQ *pSMB = NULL;
4302         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4303         int rc = 0;
4304         int bytes_returned = 0;
4305         int name_len;
4306         __u16 params, byte_count;
4307
4308         cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4309 UnixQPathInfoRetry:
4310         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4311                       (void **) &pSMBr);
4312         if (rc)
4313                 return rc;
4314
4315         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4316                 name_len =
4317                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4318                                        PATH_MAX, nls_codepage, remap);
4319                 name_len++;     /* trailing null */
4320                 name_len *= 2;
4321         } else {
4322                 name_len = copy_path_name(pSMB->FileName, searchName);
4323         }
4324
4325         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4326         pSMB->TotalDataCount = 0;
4327         pSMB->MaxParameterCount = cpu_to_le16(2);
4328         /* BB find exact max SMB PDU from sess structure BB */
4329         pSMB->MaxDataCount = cpu_to_le16(4000);
4330         pSMB->MaxSetupCount = 0;
4331         pSMB->Reserved = 0;
4332         pSMB->Flags = 0;
4333         pSMB->Timeout = 0;
4334         pSMB->Reserved2 = 0;
4335         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4336         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4337         pSMB->DataCount = 0;
4338         pSMB->DataOffset = 0;
4339         pSMB->SetupCount = 1;
4340         pSMB->Reserved3 = 0;
4341         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4342         byte_count = params + 1 /* pad */ ;
4343         pSMB->TotalParameterCount = cpu_to_le16(params);
4344         pSMB->ParameterCount = pSMB->TotalParameterCount;
4345         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4346         pSMB->Reserved4 = 0;
4347         inc_rfc1001_len(pSMB, byte_count);
4348         pSMB->ByteCount = cpu_to_le16(byte_count);
4349
4350         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4351                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4352         if (rc) {
4353                 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4354         } else {                /* decode response */
4355                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4356
4357                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4358                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4359                         rc = -EIO;      /* bad smb */
4360                 } else {
4361                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4362                         memcpy((char *) pFindData,
4363                                (char *) &pSMBr->hdr.Protocol +
4364                                data_offset,
4365                                sizeof(FILE_UNIX_BASIC_INFO));
4366                 }
4367         }
4368         cifs_buf_release(pSMB);
4369         if (rc == -EAGAIN)
4370                 goto UnixQPathInfoRetry;
4371
4372         return rc;
4373 }
4374
4375 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4376 int
4377 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4378               const char *searchName, struct cifs_sb_info *cifs_sb,
4379               __u16 *pnetfid, __u16 search_flags,
4380               struct cifs_search_info *psrch_inf, bool msearch)
4381 {
4382 /* level 257 SMB_ */
4383         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4384         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4385         T2_FFIRST_RSP_PARMS *parms;
4386         int rc = 0;
4387         int bytes_returned = 0;
4388         int name_len, remap;
4389         __u16 params, byte_count;
4390         struct nls_table *nls_codepage;
4391
4392         cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4393
4394 findFirstRetry:
4395         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4396                       (void **) &pSMBr);
4397         if (rc)
4398                 return rc;
4399
4400         nls_codepage = cifs_sb->local_nls;
4401         remap = cifs_remap(cifs_sb);
4402
4403         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4404                 name_len =
4405                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4406                                        PATH_MAX, nls_codepage, remap);
4407                 /* We can not add the asterik earlier in case
4408                 it got remapped to 0xF03A as if it were part of the
4409                 directory name instead of a wildcard */
4410                 name_len *= 2;
4411                 if (msearch) {
4412                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4413                         pSMB->FileName[name_len+1] = 0;
4414                         pSMB->FileName[name_len+2] = '*';
4415                         pSMB->FileName[name_len+3] = 0;
4416                         name_len += 4; /* now the trailing null */
4417                         /* null terminate just in case */
4418                         pSMB->FileName[name_len] = 0;
4419                         pSMB->FileName[name_len+1] = 0;
4420                         name_len += 2;
4421                 }
4422         } else {
4423                 name_len = copy_path_name(pSMB->FileName, searchName);
4424                 if (msearch) {
4425                         if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4426                                 name_len = PATH_MAX-2;
4427                         /* overwrite nul byte */
4428                         pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4429                         pSMB->FileName[name_len] = '*';
4430                         pSMB->FileName[name_len+1] = 0;
4431                         name_len += 2;
4432                 }
4433         }
4434
4435         params = 12 + name_len /* includes null */ ;
4436         pSMB->TotalDataCount = 0;       /* no EAs */
4437         pSMB->MaxParameterCount = cpu_to_le16(10);
4438         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4439         pSMB->MaxSetupCount = 0;
4440         pSMB->Reserved = 0;
4441         pSMB->Flags = 0;
4442         pSMB->Timeout = 0;
4443         pSMB->Reserved2 = 0;
4444         byte_count = params + 1 /* pad */ ;
4445         pSMB->TotalParameterCount = cpu_to_le16(params);
4446         pSMB->ParameterCount = pSMB->TotalParameterCount;
4447         pSMB->ParameterOffset = cpu_to_le16(
4448               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4449                 - 4);
4450         pSMB->DataCount = 0;
4451         pSMB->DataOffset = 0;
4452         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4453         pSMB->Reserved3 = 0;
4454         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4455         pSMB->SearchAttributes =
4456             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4457                         ATTR_DIRECTORY);
4458         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4459         pSMB->SearchFlags = cpu_to_le16(search_flags);
4460         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4461
4462         /* BB what should we set StorageType to? Does it matter? BB */
4463         pSMB->SearchStorageType = 0;
4464         inc_rfc1001_len(pSMB, byte_count);
4465         pSMB->ByteCount = cpu_to_le16(byte_count);
4466
4467         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4468                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4469         cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4470
4471         if (rc) {/* BB add logic to retry regular search if Unix search
4472                         rejected unexpectedly by server */
4473                 /* BB Add code to handle unsupported level rc */
4474                 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4475
4476                 cifs_buf_release(pSMB);
4477
4478                 /* BB eventually could optimize out free and realloc of buf */
4479                 /*    for this case */
4480                 if (rc == -EAGAIN)
4481                         goto findFirstRetry;
4482         } else { /* decode response */
4483                 /* BB remember to free buffer if error BB */
4484                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4485                 if (rc == 0) {
4486                         unsigned int lnoff;
4487
4488                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4489                                 psrch_inf->unicode = true;
4490                         else
4491                                 psrch_inf->unicode = false;
4492
4493                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4494                         psrch_inf->smallBuf = false;
4495                         psrch_inf->srch_entries_start =
4496                                 (char *) &pSMBr->hdr.Protocol +
4497                                         le16_to_cpu(pSMBr->t2.DataOffset);
4498                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4499                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4500
4501                         if (parms->EndofSearch)
4502                                 psrch_inf->endOfSearch = true;
4503                         else
4504                                 psrch_inf->endOfSearch = false;
4505
4506                         psrch_inf->entries_in_buffer =
4507                                         le16_to_cpu(parms->SearchCount);
4508                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4509                                 psrch_inf->entries_in_buffer;
4510                         lnoff = le16_to_cpu(parms->LastNameOffset);
4511                         if (CIFSMaxBufSize < lnoff) {
4512                                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4513                                 psrch_inf->last_entry = NULL;
4514                                 return rc;
4515                         }
4516
4517                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4518                                                         lnoff;
4519
4520                         if (pnetfid)
4521                                 *pnetfid = parms->SearchHandle;
4522                 } else {
4523                         cifs_buf_release(pSMB);
4524                 }
4525         }
4526
4527         return rc;
4528 }
4529
4530 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4531                  __u16 searchHandle, __u16 search_flags,
4532                  struct cifs_search_info *psrch_inf)
4533 {
4534         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4535         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4536         T2_FNEXT_RSP_PARMS *parms;
4537         char *response_data;
4538         int rc = 0;
4539         int bytes_returned;
4540         unsigned int name_len;
4541         __u16 params, byte_count;
4542
4543         cifs_dbg(FYI, "In FindNext\n");
4544
4545         if (psrch_inf->endOfSearch)
4546                 return -ENOENT;
4547
4548         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4549                 (void **) &pSMBr);
4550         if (rc)
4551                 return rc;
4552
4553         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4554         byte_count = 0;
4555         pSMB->TotalDataCount = 0;       /* no EAs */
4556         pSMB->MaxParameterCount = cpu_to_le16(8);
4557         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4558         pSMB->MaxSetupCount = 0;
4559         pSMB->Reserved = 0;
4560         pSMB->Flags = 0;
4561         pSMB->Timeout = 0;
4562         pSMB->Reserved2 = 0;
4563         pSMB->ParameterOffset =  cpu_to_le16(
4564               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4565         pSMB->DataCount = 0;
4566         pSMB->DataOffset = 0;
4567         pSMB->SetupCount = 1;
4568         pSMB->Reserved3 = 0;
4569         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4570         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4571         pSMB->SearchCount =
4572                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4573         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4574         pSMB->ResumeKey = psrch_inf->resume_key;
4575         pSMB->SearchFlags = cpu_to_le16(search_flags);
4576
4577         name_len = psrch_inf->resume_name_len;
4578         params += name_len;
4579         if (name_len < PATH_MAX) {
4580                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4581                 byte_count += name_len;
4582                 /* 14 byte parm len above enough for 2 byte null terminator */
4583                 pSMB->ResumeFileName[name_len] = 0;
4584                 pSMB->ResumeFileName[name_len+1] = 0;
4585         } else {
4586                 rc = -EINVAL;
4587                 goto FNext2_err_exit;
4588         }
4589         byte_count = params + 1 /* pad */ ;
4590         pSMB->TotalParameterCount = cpu_to_le16(params);
4591         pSMB->ParameterCount = pSMB->TotalParameterCount;
4592         inc_rfc1001_len(pSMB, byte_count);
4593         pSMB->ByteCount = cpu_to_le16(byte_count);
4594
4595         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4596                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4597         cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4598         if (rc) {
4599                 if (rc == -EBADF) {
4600                         psrch_inf->endOfSearch = true;
4601                         cifs_buf_release(pSMB);
4602                         rc = 0; /* search probably was closed at end of search*/
4603                 } else
4604                         cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4605         } else {                /* decode response */
4606                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4607
4608                 if (rc == 0) {
4609                         unsigned int lnoff;
4610
4611                         /* BB fixme add lock for file (srch_info) struct here */
4612                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4613                                 psrch_inf->unicode = true;
4614                         else
4615                                 psrch_inf->unicode = false;
4616                         response_data = (char *) &pSMBr->hdr.Protocol +
4617                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4618                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4619                         response_data = (char *)&pSMBr->hdr.Protocol +
4620                                 le16_to_cpu(pSMBr->t2.DataOffset);
4621                         if (psrch_inf->smallBuf)
4622                                 cifs_small_buf_release(
4623                                         psrch_inf->ntwrk_buf_start);
4624                         else
4625                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4626                         psrch_inf->srch_entries_start = response_data;
4627                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4628                         psrch_inf->smallBuf = false;
4629                         if (parms->EndofSearch)
4630                                 psrch_inf->endOfSearch = true;
4631                         else
4632                                 psrch_inf->endOfSearch = false;
4633                         psrch_inf->entries_in_buffer =
4634                                                 le16_to_cpu(parms->SearchCount);
4635                         psrch_inf->index_of_last_entry +=
4636                                 psrch_inf->entries_in_buffer;
4637                         lnoff = le16_to_cpu(parms->LastNameOffset);
4638                         if (CIFSMaxBufSize < lnoff) {
4639                                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4640                                 psrch_inf->last_entry = NULL;
4641                                 return rc;
4642                         } else
4643                                 psrch_inf->last_entry =
4644                                         psrch_inf->srch_entries_start + lnoff;
4645
4646 /*  cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4647     psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4648
4649                         /* BB fixme add unlock here */
4650                 }
4651
4652         }
4653
4654         /* BB On error, should we leave previous search buf (and count and
4655         last entry fields) intact or free the previous one? */
4656
4657         /* Note: On -EAGAIN error only caller can retry on handle based calls
4658         since file handle passed in no longer valid */
4659 FNext2_err_exit:
4660         if (rc != 0)
4661                 cifs_buf_release(pSMB);
4662         return rc;
4663 }
4664
4665 int
4666 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4667               const __u16 searchHandle)
4668 {
4669         int rc = 0;
4670         FINDCLOSE_REQ *pSMB = NULL;
4671
4672         cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4673         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4674
4675         /* no sense returning error if session restarted
4676                 as file handle has been closed */
4677         if (rc == -EAGAIN)
4678                 return 0;
4679         if (rc)
4680                 return rc;
4681
4682         pSMB->FileID = searchHandle;
4683         pSMB->ByteCount = 0;
4684         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4685         cifs_small_buf_release(pSMB);
4686         if (rc)
4687                 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4688
4689         cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4690
4691         /* Since session is dead, search handle closed on server already */
4692         if (rc == -EAGAIN)
4693                 rc = 0;
4694
4695         return rc;
4696 }
4697
4698 int
4699 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4700                       const char *search_name, __u64 *inode_number,
4701                       const struct nls_table *nls_codepage, int remap)
4702 {
4703         int rc = 0;
4704         TRANSACTION2_QPI_REQ *pSMB = NULL;
4705         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4706         int name_len, bytes_returned;
4707         __u16 params, byte_count;
4708
4709         cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4710         if (tcon == NULL)
4711                 return -ENODEV;
4712
4713 GetInodeNumberRetry:
4714         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4715                       (void **) &pSMBr);
4716         if (rc)
4717                 return rc;
4718
4719         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4720                 name_len =
4721                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4722                                            search_name, PATH_MAX, nls_codepage,
4723                                            remap);
4724                 name_len++;     /* trailing null */
4725                 name_len *= 2;
4726         } else {
4727                 name_len = copy_path_name(pSMB->FileName, search_name);
4728         }
4729
4730         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4731         pSMB->TotalDataCount = 0;
4732         pSMB->MaxParameterCount = cpu_to_le16(2);
4733         /* BB find exact max data count below from sess structure BB */
4734         pSMB->MaxDataCount = cpu_to_le16(4000);
4735         pSMB->MaxSetupCount = 0;
4736         pSMB->Reserved = 0;
4737         pSMB->Flags = 0;
4738         pSMB->Timeout = 0;
4739         pSMB->Reserved2 = 0;
4740         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4741                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4742         pSMB->DataCount = 0;
4743         pSMB->DataOffset = 0;
4744         pSMB->SetupCount = 1;
4745         pSMB->Reserved3 = 0;
4746         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4747         byte_count = params + 1 /* pad */ ;
4748         pSMB->TotalParameterCount = cpu_to_le16(params);
4749         pSMB->ParameterCount = pSMB->TotalParameterCount;
4750         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4751         pSMB->Reserved4 = 0;
4752         inc_rfc1001_len(pSMB, byte_count);
4753         pSMB->ByteCount = cpu_to_le16(byte_count);
4754
4755         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4756                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4757         if (rc) {
4758                 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4759         } else {
4760                 /* decode response */
4761                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4762                 /* BB also check enough total bytes returned */
4763                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4764                         /* If rc should we check for EOPNOSUPP and
4765                         disable the srvino flag? or in caller? */
4766                         rc = -EIO;      /* bad smb */
4767                 else {
4768                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4769                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4770                         struct file_internal_info *pfinfo;
4771                         /* BB Do we need a cast or hash here ? */
4772                         if (count < 8) {
4773                                 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4774                                 rc = -EIO;
4775                                 goto GetInodeNumOut;
4776                         }
4777                         pfinfo = (struct file_internal_info *)
4778                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4779                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4780                 }
4781         }
4782 GetInodeNumOut:
4783         cifs_buf_release(pSMB);
4784         if (rc == -EAGAIN)
4785                 goto GetInodeNumberRetry;
4786         return rc;
4787 }
4788
4789 int
4790 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4791                 const char *search_name, struct dfs_info3_param **target_nodes,
4792                 unsigned int *num_of_nodes,
4793                 const struct nls_table *nls_codepage, int remap)
4794 {
4795 /* TRANS2_GET_DFS_REFERRAL */
4796         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4797         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4798         int rc = 0;
4799         int bytes_returned;
4800         int name_len;
4801         __u16 params, byte_count;
4802         *num_of_nodes = 0;
4803         *target_nodes = NULL;
4804
4805         cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4806         if (ses == NULL || ses->tcon_ipc == NULL)
4807                 return -ENODEV;
4808
4809 getDFSRetry:
4810         rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4811                       (void **) &pSMBr);
4812         if (rc)
4813                 return rc;
4814
4815         /* server pointer checked in called function,
4816         but should never be null here anyway */
4817         pSMB->hdr.Mid = get_next_mid(ses->server);
4818         pSMB->hdr.Tid = ses->tcon_ipc->tid;
4819         pSMB->hdr.Uid = ses->Suid;
4820         if (ses->capabilities & CAP_STATUS32)
4821                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4822         if (ses->capabilities & CAP_DFS)
4823                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4824
4825         if (ses->capabilities & CAP_UNICODE) {
4826                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4827                 name_len =
4828                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4829                                        search_name, PATH_MAX, nls_codepage,
4830                                        remap);
4831                 name_len++;     /* trailing null */
4832                 name_len *= 2;
4833         } else {        /* BB improve the check for buffer overruns BB */
4834                 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4835         }
4836
4837         if (ses->server->sign)
4838                 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4839
4840         pSMB->hdr.Uid = ses->Suid;
4841
4842         params = 2 /* level */  + name_len /*includes null */ ;
4843         pSMB->TotalDataCount = 0;
4844         pSMB->DataCount = 0;
4845         pSMB->DataOffset = 0;
4846         pSMB->MaxParameterCount = 0;
4847         /* BB find exact max SMB PDU from sess structure BB */
4848         pSMB->MaxDataCount = cpu_to_le16(4000);
4849         pSMB->MaxSetupCount = 0;
4850         pSMB->Reserved = 0;
4851         pSMB->Flags = 0;
4852         pSMB->Timeout = 0;
4853         pSMB->Reserved2 = 0;
4854         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4855           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4856         pSMB->SetupCount = 1;
4857         pSMB->Reserved3 = 0;
4858         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4859         byte_count = params + 3 /* pad */ ;
4860         pSMB->ParameterCount = cpu_to_le16(params);
4861         pSMB->TotalParameterCount = pSMB->ParameterCount;
4862         pSMB->MaxReferralLevel = cpu_to_le16(3);
4863         inc_rfc1001_len(pSMB, byte_count);
4864         pSMB->ByteCount = cpu_to_le16(byte_count);
4865
4866         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4867                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4868         if (rc) {
4869                 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4870                 goto GetDFSRefExit;
4871         }
4872         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4873
4874         /* BB Also check if enough total bytes returned? */
4875         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4876                 rc = -EIO;      /* bad smb */
4877                 goto GetDFSRefExit;
4878         }
4879
4880         cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4881                  get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4882
4883         /* parse returned result into more usable form */
4884         rc = parse_dfs_referrals(&pSMBr->dfs_data,
4885                                  le16_to_cpu(pSMBr->t2.DataCount),
4886                                  num_of_nodes, target_nodes, nls_codepage,
4887                                  remap, search_name,
4888                                  (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4889
4890 GetDFSRefExit:
4891         cifs_buf_release(pSMB);
4892
4893         if (rc == -EAGAIN)
4894                 goto getDFSRetry;
4895
4896         return rc;
4897 }
4898
4899 /* Query File System Info such as free space to old servers such as Win 9x */
4900 int
4901 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4902               struct kstatfs *FSData)
4903 {
4904 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4905         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4906         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4907         FILE_SYSTEM_ALLOC_INFO *response_data;
4908         int rc = 0;
4909         int bytes_returned = 0;
4910         __u16 params, byte_count;
4911
4912         cifs_dbg(FYI, "OldQFSInfo\n");
4913 oldQFSInfoRetry:
4914         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4915                 (void **) &pSMBr);
4916         if (rc)
4917                 return rc;
4918
4919         params = 2;     /* level */
4920         pSMB->TotalDataCount = 0;
4921         pSMB->MaxParameterCount = cpu_to_le16(2);
4922         pSMB->MaxDataCount = cpu_to_le16(1000);
4923         pSMB->MaxSetupCount = 0;
4924         pSMB->Reserved = 0;
4925         pSMB->Flags = 0;
4926         pSMB->Timeout = 0;
4927         pSMB->Reserved2 = 0;
4928         byte_count = params + 1 /* pad */ ;
4929         pSMB->TotalParameterCount = cpu_to_le16(params);
4930         pSMB->ParameterCount = pSMB->TotalParameterCount;
4931         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4932         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4933         pSMB->DataCount = 0;
4934         pSMB->DataOffset = 0;
4935         pSMB->SetupCount = 1;
4936         pSMB->Reserved3 = 0;
4937         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4938         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4939         inc_rfc1001_len(pSMB, byte_count);
4940         pSMB->ByteCount = cpu_to_le16(byte_count);
4941
4942         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4943                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4944         if (rc) {
4945                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4946         } else {                /* decode response */
4947                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4948
4949                 if (rc || get_bcc(&pSMBr->hdr) < 18)
4950                         rc = -EIO;      /* bad smb */
4951                 else {
4952                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4953                         cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
4954                                  get_bcc(&pSMBr->hdr), data_offset);
4955
4956                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
4957                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4958                         FSData->f_bsize =
4959                                 le16_to_cpu(response_data->BytesPerSector) *
4960                                 le32_to_cpu(response_data->
4961                                         SectorsPerAllocationUnit);
4962                         /*
4963                          * much prefer larger but if server doesn't report
4964                          * a valid size than 4K is a reasonable minimum
4965                          */
4966                         if (FSData->f_bsize < 512)
4967                                 FSData->f_bsize = 4096;
4968
4969                         FSData->f_blocks =
4970                                le32_to_cpu(response_data->TotalAllocationUnits);
4971                         FSData->f_bfree = FSData->f_bavail =
4972                                 le32_to_cpu(response_data->FreeAllocationUnits);
4973                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4974                                  (unsigned long long)FSData->f_blocks,
4975                                  (unsigned long long)FSData->f_bfree,
4976                                  FSData->f_bsize);
4977                 }
4978         }
4979         cifs_buf_release(pSMB);
4980
4981         if (rc == -EAGAIN)
4982                 goto oldQFSInfoRetry;
4983
4984         return rc;
4985 }
4986
4987 int
4988 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4989                struct kstatfs *FSData)
4990 {
4991 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4992         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4993         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4994         FILE_SYSTEM_INFO *response_data;
4995         int rc = 0;
4996         int bytes_returned = 0;
4997         __u16 params, byte_count;
4998
4999         cifs_dbg(FYI, "In QFSInfo\n");
5000 QFSInfoRetry:
5001         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5002                       (void **) &pSMBr);
5003         if (rc)
5004                 return rc;
5005
5006         params = 2;     /* level */
5007         pSMB->TotalDataCount = 0;
5008         pSMB->MaxParameterCount = cpu_to_le16(2);
5009         pSMB->MaxDataCount = cpu_to_le16(1000);
5010         pSMB->MaxSetupCount = 0;
5011         pSMB->Reserved = 0;
5012         pSMB->Flags = 0;
5013         pSMB->Timeout = 0;
5014         pSMB->Reserved2 = 0;
5015         byte_count = params + 1 /* pad */ ;
5016         pSMB->TotalParameterCount = cpu_to_le16(params);
5017         pSMB->ParameterCount = pSMB->TotalParameterCount;
5018         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5019                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5020         pSMB->DataCount = 0;
5021         pSMB->DataOffset = 0;
5022         pSMB->SetupCount = 1;
5023         pSMB->Reserved3 = 0;
5024         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5025         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5026         inc_rfc1001_len(pSMB, byte_count);
5027         pSMB->ByteCount = cpu_to_le16(byte_count);
5028
5029         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5030                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5031         if (rc) {
5032                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5033         } else {                /* decode response */
5034                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5035
5036                 if (rc || get_bcc(&pSMBr->hdr) < 24)
5037                         rc = -EIO;      /* bad smb */
5038                 else {
5039                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5040
5041                         response_data =
5042                             (FILE_SYSTEM_INFO
5043                              *) (((char *) &pSMBr->hdr.Protocol) +
5044                                  data_offset);
5045                         FSData->f_bsize =
5046                             le32_to_cpu(response_data->BytesPerSector) *
5047                             le32_to_cpu(response_data->
5048                                         SectorsPerAllocationUnit);
5049                         /*
5050                          * much prefer larger but if server doesn't report
5051                          * a valid size than 4K is a reasonable minimum
5052                          */
5053                         if (FSData->f_bsize < 512)
5054                                 FSData->f_bsize = 4096;
5055
5056                         FSData->f_blocks =
5057                             le64_to_cpu(response_data->TotalAllocationUnits);
5058                         FSData->f_bfree = FSData->f_bavail =
5059                             le64_to_cpu(response_data->FreeAllocationUnits);
5060                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
5061                                  (unsigned long long)FSData->f_blocks,
5062                                  (unsigned long long)FSData->f_bfree,
5063                                  FSData->f_bsize);
5064                 }
5065         }
5066         cifs_buf_release(pSMB);
5067
5068         if (rc == -EAGAIN)
5069                 goto QFSInfoRetry;
5070
5071         return rc;
5072 }
5073
5074 int
5075 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5076 {
5077 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5078         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5079         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5080         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5081         int rc = 0;
5082         int bytes_returned = 0;
5083         __u16 params, byte_count;
5084
5085         cifs_dbg(FYI, "In QFSAttributeInfo\n");
5086 QFSAttributeRetry:
5087         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5088                       (void **) &pSMBr);
5089         if (rc)
5090                 return rc;
5091
5092         params = 2;     /* level */
5093         pSMB->TotalDataCount = 0;
5094         pSMB->MaxParameterCount = cpu_to_le16(2);
5095         /* BB find exact max SMB PDU from sess structure BB */
5096         pSMB->MaxDataCount = cpu_to_le16(1000);
5097         pSMB->MaxSetupCount = 0;
5098         pSMB->Reserved = 0;
5099         pSMB->Flags = 0;
5100         pSMB->Timeout = 0;
5101         pSMB->Reserved2 = 0;
5102         byte_count = params + 1 /* pad */ ;
5103         pSMB->TotalParameterCount = cpu_to_le16(params);
5104         pSMB->ParameterCount = pSMB->TotalParameterCount;
5105         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5106                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5107         pSMB->DataCount = 0;
5108         pSMB->DataOffset = 0;
5109         pSMB->SetupCount = 1;
5110         pSMB->Reserved3 = 0;
5111         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5112         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5113         inc_rfc1001_len(pSMB, byte_count);
5114         pSMB->ByteCount = cpu_to_le16(byte_count);
5115
5116         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5117                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5118         if (rc) {
5119                 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5120         } else {                /* decode response */
5121                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5122
5123                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5124                         /* BB also check if enough bytes returned */
5125                         rc = -EIO;      /* bad smb */
5126                 } else {
5127                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5128                         response_data =
5129                             (FILE_SYSTEM_ATTRIBUTE_INFO
5130                              *) (((char *) &pSMBr->hdr.Protocol) +
5131                                  data_offset);
5132                         memcpy(&tcon->fsAttrInfo, response_data,
5133                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5134                 }
5135         }
5136         cifs_buf_release(pSMB);
5137
5138         if (rc == -EAGAIN)
5139                 goto QFSAttributeRetry;
5140
5141         return rc;
5142 }
5143
5144 int
5145 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5146 {
5147 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5148         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5149         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5150         FILE_SYSTEM_DEVICE_INFO *response_data;
5151         int rc = 0;
5152         int bytes_returned = 0;
5153         __u16 params, byte_count;
5154
5155         cifs_dbg(FYI, "In QFSDeviceInfo\n");
5156 QFSDeviceRetry:
5157         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5158                       (void **) &pSMBr);
5159         if (rc)
5160                 return rc;
5161
5162         params = 2;     /* level */
5163         pSMB->TotalDataCount = 0;
5164         pSMB->MaxParameterCount = cpu_to_le16(2);
5165         /* BB find exact max SMB PDU from sess structure BB */
5166         pSMB->MaxDataCount = cpu_to_le16(1000);
5167         pSMB->MaxSetupCount = 0;
5168         pSMB->Reserved = 0;
5169         pSMB->Flags = 0;
5170         pSMB->Timeout = 0;
5171         pSMB->Reserved2 = 0;
5172         byte_count = params + 1 /* pad */ ;
5173         pSMB->TotalParameterCount = cpu_to_le16(params);
5174         pSMB->ParameterCount = pSMB->TotalParameterCount;
5175         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5176                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5177
5178         pSMB->DataCount = 0;
5179         pSMB->DataOffset = 0;
5180         pSMB->SetupCount = 1;
5181         pSMB->Reserved3 = 0;
5182         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5183         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5184         inc_rfc1001_len(pSMB, byte_count);
5185         pSMB->ByteCount = cpu_to_le16(byte_count);
5186
5187         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5188                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5189         if (rc) {
5190                 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5191         } else {                /* decode response */
5192                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5193
5194                 if (rc || get_bcc(&pSMBr->hdr) <
5195                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5196                         rc = -EIO;      /* bad smb */
5197                 else {
5198                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5199                         response_data =
5200                             (FILE_SYSTEM_DEVICE_INFO *)
5201                                 (((char *) &pSMBr->hdr.Protocol) +
5202                                  data_offset);
5203                         memcpy(&tcon->fsDevInfo, response_data,
5204                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5205                 }
5206         }
5207         cifs_buf_release(pSMB);
5208
5209         if (rc == -EAGAIN)
5210                 goto QFSDeviceRetry;
5211
5212         return rc;
5213 }
5214
5215 int
5216 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5217 {
5218 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5219         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5220         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5221         FILE_SYSTEM_UNIX_INFO *response_data;
5222         int rc = 0;
5223         int bytes_returned = 0;
5224         __u16 params, byte_count;
5225
5226         cifs_dbg(FYI, "In QFSUnixInfo\n");
5227 QFSUnixRetry:
5228         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5229                                    (void **) &pSMB, (void **) &pSMBr);
5230         if (rc)
5231                 return rc;
5232
5233         params = 2;     /* level */
5234         pSMB->TotalDataCount = 0;
5235         pSMB->DataCount = 0;
5236         pSMB->DataOffset = 0;
5237         pSMB->MaxParameterCount = cpu_to_le16(2);
5238         /* BB find exact max SMB PDU from sess structure BB */
5239         pSMB->MaxDataCount = cpu_to_le16(100);
5240         pSMB->MaxSetupCount = 0;
5241         pSMB->Reserved = 0;
5242         pSMB->Flags = 0;
5243         pSMB->Timeout = 0;
5244         pSMB->Reserved2 = 0;
5245         byte_count = params + 1 /* pad */ ;
5246         pSMB->ParameterCount = cpu_to_le16(params);
5247         pSMB->TotalParameterCount = pSMB->ParameterCount;
5248         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5249                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5250         pSMB->SetupCount = 1;
5251         pSMB->Reserved3 = 0;
5252         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5253         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5254         inc_rfc1001_len(pSMB, byte_count);
5255         pSMB->ByteCount = cpu_to_le16(byte_count);
5256
5257         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5258                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5259         if (rc) {
5260                 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5261         } else {                /* decode response */
5262                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5263
5264                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5265                         rc = -EIO;      /* bad smb */
5266                 } else {
5267                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5268                         response_data =
5269                             (FILE_SYSTEM_UNIX_INFO
5270                              *) (((char *) &pSMBr->hdr.Protocol) +
5271                                  data_offset);
5272                         memcpy(&tcon->fsUnixInfo, response_data,
5273                                sizeof(FILE_SYSTEM_UNIX_INFO));
5274                 }
5275         }
5276         cifs_buf_release(pSMB);
5277
5278         if (rc == -EAGAIN)
5279                 goto QFSUnixRetry;
5280
5281
5282         return rc;
5283 }
5284
5285 int
5286 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5287 {
5288 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5289         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5290         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5291         int rc = 0;
5292         int bytes_returned = 0;
5293         __u16 params, param_offset, offset, byte_count;
5294
5295         cifs_dbg(FYI, "In SETFSUnixInfo\n");
5296 SETFSUnixRetry:
5297         /* BB switch to small buf init to save memory */
5298         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5299                                         (void **) &pSMB, (void **) &pSMBr);
5300         if (rc)
5301                 return rc;
5302
5303         params = 4;     /* 2 bytes zero followed by info level. */
5304         pSMB->MaxSetupCount = 0;
5305         pSMB->Reserved = 0;
5306         pSMB->Flags = 0;
5307         pSMB->Timeout = 0;
5308         pSMB->Reserved2 = 0;
5309         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5310                                 - 4;
5311         offset = param_offset + params;
5312
5313         pSMB->MaxParameterCount = cpu_to_le16(4);
5314         /* BB find exact max SMB PDU from sess structure BB */
5315         pSMB->MaxDataCount = cpu_to_le16(100);
5316         pSMB->SetupCount = 1;
5317         pSMB->Reserved3 = 0;
5318         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5319         byte_count = 1 /* pad */ + params + 12;
5320
5321         pSMB->DataCount = cpu_to_le16(12);
5322         pSMB->ParameterCount = cpu_to_le16(params);
5323         pSMB->TotalDataCount = pSMB->DataCount;
5324         pSMB->TotalParameterCount = pSMB->ParameterCount;
5325         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5326         pSMB->DataOffset = cpu_to_le16(offset);
5327
5328         /* Params. */
5329         pSMB->FileNum = 0;
5330         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5331
5332         /* Data. */
5333         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5334         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5335         pSMB->ClientUnixCap = cpu_to_le64(cap);
5336
5337         inc_rfc1001_len(pSMB, byte_count);
5338         pSMB->ByteCount = cpu_to_le16(byte_count);
5339
5340         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5341                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5342         if (rc) {
5343                 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5344         } else {                /* decode response */
5345                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5346                 if (rc)
5347                         rc = -EIO;      /* bad smb */
5348         }
5349         cifs_buf_release(pSMB);
5350
5351         if (rc == -EAGAIN)
5352                 goto SETFSUnixRetry;
5353
5354         return rc;
5355 }
5356
5357
5358
5359 int
5360 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5361                    struct kstatfs *FSData)
5362 {
5363 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5364         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5365         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5366         FILE_SYSTEM_POSIX_INFO *response_data;
5367         int rc = 0;
5368         int bytes_returned = 0;
5369         __u16 params, byte_count;
5370
5371         cifs_dbg(FYI, "In QFSPosixInfo\n");
5372 QFSPosixRetry:
5373         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5374                       (void **) &pSMBr);
5375         if (rc)
5376                 return rc;
5377
5378         params = 2;     /* level */
5379         pSMB->TotalDataCount = 0;
5380         pSMB->DataCount = 0;
5381         pSMB->DataOffset = 0;
5382         pSMB->MaxParameterCount = cpu_to_le16(2);
5383         /* BB find exact max SMB PDU from sess structure BB */
5384         pSMB->MaxDataCount = cpu_to_le16(100);
5385         pSMB->MaxSetupCount = 0;
5386         pSMB->Reserved = 0;
5387         pSMB->Flags = 0;
5388         pSMB->Timeout = 0;
5389         pSMB->Reserved2 = 0;
5390         byte_count = params + 1 /* pad */ ;
5391         pSMB->ParameterCount = cpu_to_le16(params);
5392         pSMB->TotalParameterCount = pSMB->ParameterCount;
5393         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5394                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5395         pSMB->SetupCount = 1;
5396         pSMB->Reserved3 = 0;
5397         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5398         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5399         inc_rfc1001_len(pSMB, byte_count);
5400         pSMB->ByteCount = cpu_to_le16(byte_count);
5401
5402         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5403                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5404         if (rc) {
5405                 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5406         } else {                /* decode response */
5407                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5408
5409                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5410                         rc = -EIO;      /* bad smb */
5411                 } else {
5412                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5413                         response_data =
5414                             (FILE_SYSTEM_POSIX_INFO
5415                              *) (((char *) &pSMBr->hdr.Protocol) +
5416                                  data_offset);
5417                         FSData->f_bsize =
5418                                         le32_to_cpu(response_data->BlockSize);
5419                         /*
5420                          * much prefer larger but if server doesn't report
5421                          * a valid size than 4K is a reasonable minimum
5422                          */
5423                         if (FSData->f_bsize < 512)
5424                                 FSData->f_bsize = 4096;
5425
5426                         FSData->f_blocks =
5427                                         le64_to_cpu(response_data->TotalBlocks);
5428                         FSData->f_bfree =
5429                             le64_to_cpu(response_data->BlocksAvail);
5430                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5431                                 FSData->f_bavail = FSData->f_bfree;
5432                         } else {
5433                                 FSData->f_bavail =
5434                                     le64_to_cpu(response_data->UserBlocksAvail);
5435                         }
5436                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5437                                 FSData->f_files =
5438                                      le64_to_cpu(response_data->TotalFileNodes);
5439                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5440                                 FSData->f_ffree =
5441                                       le64_to_cpu(response_data->FreeFileNodes);
5442                 }
5443         }
5444         cifs_buf_release(pSMB);
5445
5446         if (rc == -EAGAIN)
5447                 goto QFSPosixRetry;
5448
5449         return rc;
5450 }
5451
5452
5453 /*
5454  * We can not use write of zero bytes trick to set file size due to need for
5455  * large file support. Also note that this SetPathInfo is preferred to
5456  * SetFileInfo based method in next routine which is only needed to work around
5457  * a sharing violation bugin Samba which this routine can run into.
5458  */
5459 int
5460 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5461               const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5462               bool set_allocation)
5463 {
5464         struct smb_com_transaction2_spi_req *pSMB = NULL;
5465         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5466         struct file_end_of_file_info *parm_data;
5467         int name_len;
5468         int rc = 0;
5469         int bytes_returned = 0;
5470         int remap = cifs_remap(cifs_sb);
5471
5472         __u16 params, byte_count, data_count, param_offset, offset;
5473
5474         cifs_dbg(FYI, "In SetEOF\n");
5475 SetEOFRetry:
5476         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5477                       (void **) &pSMBr);
5478         if (rc)
5479                 return rc;
5480
5481         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5482                 name_len =
5483                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5484                                        PATH_MAX, cifs_sb->local_nls, remap);
5485                 name_len++;     /* trailing null */
5486                 name_len *= 2;
5487         } else {
5488                 name_len = copy_path_name(pSMB->FileName, file_name);
5489         }
5490         params = 6 + name_len;
5491         data_count = sizeof(struct file_end_of_file_info);
5492         pSMB->MaxParameterCount = cpu_to_le16(2);
5493         pSMB->MaxDataCount = cpu_to_le16(4100);
5494         pSMB->MaxSetupCount = 0;
5495         pSMB->Reserved = 0;
5496         pSMB->Flags = 0;
5497         pSMB->Timeout = 0;
5498         pSMB->Reserved2 = 0;
5499         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5500                                 InformationLevel) - 4;
5501         offset = param_offset + params;
5502         if (set_allocation) {
5503                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5504                         pSMB->InformationLevel =
5505                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5506                 else
5507                         pSMB->InformationLevel =
5508                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5509         } else /* Set File Size */  {
5510             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5511                     pSMB->InformationLevel =
5512                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5513             else
5514                     pSMB->InformationLevel =
5515                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5516         }
5517
5518         parm_data =
5519             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5520                                        offset);
5521         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5522         pSMB->DataOffset = cpu_to_le16(offset);
5523         pSMB->SetupCount = 1;
5524         pSMB->Reserved3 = 0;
5525         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5526         byte_count = 3 /* pad */  + params + data_count;
5527         pSMB->DataCount = cpu_to_le16(data_count);
5528         pSMB->TotalDataCount = pSMB->DataCount;
5529         pSMB->ParameterCount = cpu_to_le16(params);
5530         pSMB->TotalParameterCount = pSMB->ParameterCount;
5531         pSMB->Reserved4 = 0;
5532         inc_rfc1001_len(pSMB, byte_count);
5533         parm_data->FileSize = cpu_to_le64(size);
5534         pSMB->ByteCount = cpu_to_le16(byte_count);
5535         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5536                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5537         if (rc)
5538                 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5539
5540         cifs_buf_release(pSMB);
5541
5542         if (rc == -EAGAIN)
5543                 goto SetEOFRetry;
5544
5545         return rc;
5546 }
5547
5548 int
5549 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5550                    struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5551 {
5552         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5553         struct file_end_of_file_info *parm_data;
5554         int rc = 0;
5555         __u16 params, param_offset, offset, byte_count, count;
5556
5557         cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5558                  (long long)size);
5559         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5560
5561         if (rc)
5562                 return rc;
5563
5564         pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5565         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5566
5567         params = 6;
5568         pSMB->MaxSetupCount = 0;
5569         pSMB->Reserved = 0;
5570         pSMB->Flags = 0;
5571         pSMB->Timeout = 0;
5572         pSMB->Reserved2 = 0;
5573         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5574         offset = param_offset + params;
5575
5576         count = sizeof(struct file_end_of_file_info);
5577         pSMB->MaxParameterCount = cpu_to_le16(2);
5578         /* BB find exact max SMB PDU from sess structure BB */
5579         pSMB->MaxDataCount = cpu_to_le16(1000);
5580         pSMB->SetupCount = 1;
5581         pSMB->Reserved3 = 0;
5582         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5583         byte_count = 3 /* pad */  + params + count;
5584         pSMB->DataCount = cpu_to_le16(count);
5585         pSMB->ParameterCount = cpu_to_le16(params);
5586         pSMB->TotalDataCount = pSMB->DataCount;
5587         pSMB->TotalParameterCount = pSMB->ParameterCount;
5588         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5589         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5590         parm_data =
5591                 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5592         pSMB->DataOffset = cpu_to_le16(offset);
5593         parm_data->FileSize = cpu_to_le64(size);
5594         pSMB->Fid = cfile->fid.netfid;
5595         if (set_allocation) {
5596                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5597                         pSMB->InformationLevel =
5598                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5599                 else
5600                         pSMB->InformationLevel =
5601                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5602         } else /* Set File Size */  {
5603             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5604                     pSMB->InformationLevel =
5605                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5606             else
5607                     pSMB->InformationLevel =
5608                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5609         }
5610         pSMB->Reserved4 = 0;
5611         inc_rfc1001_len(pSMB, byte_count);
5612         pSMB->ByteCount = cpu_to_le16(byte_count);
5613         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5614         cifs_small_buf_release(pSMB);
5615         if (rc) {
5616                 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5617                          rc);
5618         }
5619
5620         /* Note: On -EAGAIN error only caller can retry on handle based calls
5621                 since file handle passed in no longer valid */
5622
5623         return rc;
5624 }
5625
5626 /* Some legacy servers such as NT4 require that the file times be set on
5627    an open handle, rather than by pathname - this is awkward due to
5628    potential access conflicts on the open, but it is unavoidable for these
5629    old servers since the only other choice is to go from 100 nanosecond DCE
5630    time and resort to the original setpathinfo level which takes the ancient
5631    DOS time format with 2 second granularity */
5632 int
5633 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5634                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5635 {
5636         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5637         char *data_offset;
5638         int rc = 0;
5639         __u16 params, param_offset, offset, byte_count, count;
5640
5641         cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5642         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5643
5644         if (rc)
5645                 return rc;
5646
5647         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5648         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5649
5650         params = 6;
5651         pSMB->MaxSetupCount = 0;
5652         pSMB->Reserved = 0;
5653         pSMB->Flags = 0;
5654         pSMB->Timeout = 0;
5655         pSMB->Reserved2 = 0;
5656         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5657         offset = param_offset + params;
5658
5659         data_offset = (char *)pSMB +
5660                         offsetof(struct smb_hdr, Protocol) + offset;
5661
5662         count = sizeof(FILE_BASIC_INFO);
5663         pSMB->MaxParameterCount = cpu_to_le16(2);
5664         /* BB find max SMB PDU from sess */
5665         pSMB->MaxDataCount = cpu_to_le16(1000);
5666         pSMB->SetupCount = 1;
5667         pSMB->Reserved3 = 0;
5668         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5669         byte_count = 3 /* pad */  + params + count;
5670         pSMB->DataCount = cpu_to_le16(count);
5671         pSMB->ParameterCount = cpu_to_le16(params);
5672         pSMB->TotalDataCount = pSMB->DataCount;
5673         pSMB->TotalParameterCount = pSMB->ParameterCount;
5674         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5675         pSMB->DataOffset = cpu_to_le16(offset);
5676         pSMB->Fid = fid;
5677         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5678                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5679         else
5680                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5681         pSMB->Reserved4 = 0;
5682         inc_rfc1001_len(pSMB, byte_count);
5683         pSMB->ByteCount = cpu_to_le16(byte_count);
5684         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5685         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5686         cifs_small_buf_release(pSMB);
5687         if (rc)
5688                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5689                          rc);
5690
5691         /* Note: On -EAGAIN error only caller can retry on handle based calls
5692                 since file handle passed in no longer valid */
5693
5694         return rc;
5695 }
5696
5697 int
5698 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5699                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5700 {
5701         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5702         char *data_offset;
5703         int rc = 0;
5704         __u16 params, param_offset, offset, byte_count, count;
5705
5706         cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5707         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5708
5709         if (rc)
5710                 return rc;
5711
5712         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5713         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5714
5715         params = 6;
5716         pSMB->MaxSetupCount = 0;
5717         pSMB->Reserved = 0;
5718         pSMB->Flags = 0;
5719         pSMB->Timeout = 0;
5720         pSMB->Reserved2 = 0;
5721         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5722         offset = param_offset + params;
5723
5724         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5725         data_offset = (char *)(pSMB) + offset + 4;
5726
5727         count = 1;
5728         pSMB->MaxParameterCount = cpu_to_le16(2);
5729         /* BB find max SMB PDU from sess */
5730         pSMB->MaxDataCount = cpu_to_le16(1000);
5731         pSMB->SetupCount = 1;
5732         pSMB->Reserved3 = 0;
5733         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5734         byte_count = 3 /* pad */  + params + count;
5735         pSMB->DataCount = cpu_to_le16(count);
5736         pSMB->ParameterCount = cpu_to_le16(params);
5737         pSMB->TotalDataCount = pSMB->DataCount;
5738         pSMB->TotalParameterCount = pSMB->ParameterCount;
5739         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5740         pSMB->DataOffset = cpu_to_le16(offset);
5741         pSMB->Fid = fid;
5742         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5743         pSMB->Reserved4 = 0;
5744         inc_rfc1001_len(pSMB, byte_count);
5745         pSMB->ByteCount = cpu_to_le16(byte_count);
5746         *data_offset = delete_file ? 1 : 0;
5747         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5748         cifs_small_buf_release(pSMB);
5749         if (rc)
5750                 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5751
5752         return rc;
5753 }
5754
5755 static int
5756 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5757                      const char *fileName, const FILE_BASIC_INFO *data,
5758                      const struct nls_table *nls_codepage,
5759                      struct cifs_sb_info *cifs_sb)
5760 {
5761         int oplock = 0;
5762         struct cifs_open_parms oparms;
5763         struct cifs_fid fid;
5764         int rc;
5765
5766         oparms.tcon = tcon;
5767         oparms.cifs_sb = cifs_sb;
5768         oparms.desired_access = GENERIC_WRITE;
5769         oparms.create_options = cifs_create_options(cifs_sb, 0);
5770         oparms.disposition = FILE_OPEN;
5771         oparms.path = fileName;
5772         oparms.fid = &fid;
5773         oparms.reconnect = false;
5774
5775         rc = CIFS_open(xid, &oparms, &oplock, NULL);
5776         if (rc)
5777                 goto out;
5778
5779         rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5780         CIFSSMBClose(xid, tcon, fid.netfid);
5781 out:
5782
5783         return rc;
5784 }
5785
5786 int
5787 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5788                    const char *fileName, const FILE_BASIC_INFO *data,
5789                    const struct nls_table *nls_codepage,
5790                      struct cifs_sb_info *cifs_sb)
5791 {
5792         TRANSACTION2_SPI_REQ *pSMB = NULL;
5793         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5794         int name_len;
5795         int rc = 0;
5796         int bytes_returned = 0;
5797         char *data_offset;
5798         __u16 params, param_offset, offset, byte_count, count;
5799         int remap = cifs_remap(cifs_sb);
5800
5801         cifs_dbg(FYI, "In SetTimes\n");
5802
5803 SetTimesRetry:
5804         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5805                       (void **) &pSMBr);
5806         if (rc)
5807                 return rc;
5808
5809         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5810                 name_len =
5811                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5812                                        PATH_MAX, nls_codepage, remap);
5813                 name_len++;     /* trailing null */
5814                 name_len *= 2;
5815         } else {
5816                 name_len = copy_path_name(pSMB->FileName, fileName);
5817         }
5818
5819         params = 6 + name_len;
5820         count = sizeof(FILE_BASIC_INFO);
5821         pSMB->MaxParameterCount = cpu_to_le16(2);
5822         /* BB find max SMB PDU from sess structure BB */
5823         pSMB->MaxDataCount = cpu_to_le16(1000);
5824         pSMB->MaxSetupCount = 0;
5825         pSMB->Reserved = 0;
5826         pSMB->Flags = 0;
5827         pSMB->Timeout = 0;
5828         pSMB->Reserved2 = 0;
5829         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5830                                 InformationLevel) - 4;
5831         offset = param_offset + params;
5832         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5833         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5834         pSMB->DataOffset = cpu_to_le16(offset);
5835         pSMB->SetupCount = 1;
5836         pSMB->Reserved3 = 0;
5837         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5838         byte_count = 3 /* pad */  + params + count;
5839
5840         pSMB->DataCount = cpu_to_le16(count);
5841         pSMB->ParameterCount = cpu_to_le16(params);
5842         pSMB->TotalDataCount = pSMB->DataCount;
5843         pSMB->TotalParameterCount = pSMB->ParameterCount;
5844         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5845                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5846         else
5847                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5848         pSMB->Reserved4 = 0;
5849         inc_rfc1001_len(pSMB, byte_count);
5850         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5851         pSMB->ByteCount = cpu_to_le16(byte_count);
5852         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5853                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5854         if (rc)
5855                 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5856
5857         cifs_buf_release(pSMB);
5858
5859         if (rc == -EAGAIN)
5860                 goto SetTimesRetry;
5861
5862         if (rc == -EOPNOTSUPP)
5863                 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5864                                             nls_codepage, cifs_sb);
5865
5866         return rc;
5867 }
5868
5869 static void
5870 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5871                         const struct cifs_unix_set_info_args *args)
5872 {
5873         u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5874         u64 mode = args->mode;
5875
5876         if (uid_valid(args->uid))
5877                 uid = from_kuid(&init_user_ns, args->uid);
5878         if (gid_valid(args->gid))
5879                 gid = from_kgid(&init_user_ns, args->gid);
5880
5881         /*
5882          * Samba server ignores set of file size to zero due to bugs in some
5883          * older clients, but we should be precise - we use SetFileSize to
5884          * set file size and do not want to truncate file size to zero
5885          * accidentally as happened on one Samba server beta by putting
5886          * zero instead of -1 here
5887          */
5888         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5889         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5890         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5891         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5892         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5893         data_offset->Uid = cpu_to_le64(uid);
5894         data_offset->Gid = cpu_to_le64(gid);
5895         /* better to leave device as zero when it is  */
5896         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5897         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5898         data_offset->Permissions = cpu_to_le64(mode);
5899
5900         if (S_ISREG(mode))
5901                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5902         else if (S_ISDIR(mode))
5903                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5904         else if (S_ISLNK(mode))
5905                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5906         else if (S_ISCHR(mode))
5907                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5908         else if (S_ISBLK(mode))
5909                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5910         else if (S_ISFIFO(mode))
5911                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5912         else if (S_ISSOCK(mode))
5913                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5914 }
5915
5916 int
5917 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5918                        const struct cifs_unix_set_info_args *args,
5919                        u16 fid, u32 pid_of_opener)
5920 {
5921         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5922         char *data_offset;
5923         int rc = 0;
5924         u16 params, param_offset, offset, byte_count, count;
5925
5926         cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5927         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5928
5929         if (rc)
5930                 return rc;
5931
5932         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5933         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5934
5935         params = 6;
5936         pSMB->MaxSetupCount = 0;
5937         pSMB->Reserved = 0;
5938         pSMB->Flags = 0;
5939         pSMB->Timeout = 0;
5940         pSMB->Reserved2 = 0;
5941         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5942         offset = param_offset + params;
5943
5944         data_offset = (char *)pSMB +
5945                         offsetof(struct smb_hdr, Protocol) + offset;
5946
5947         count = sizeof(FILE_UNIX_BASIC_INFO);
5948
5949         pSMB->MaxParameterCount = cpu_to_le16(2);
5950         /* BB find max SMB PDU from sess */
5951         pSMB->MaxDataCount = cpu_to_le16(1000);
5952         pSMB->SetupCount = 1;
5953         pSMB->Reserved3 = 0;
5954         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5955         byte_count = 3 /* pad */  + params + count;
5956         pSMB->DataCount = cpu_to_le16(count);
5957         pSMB->ParameterCount = cpu_to_le16(params);
5958         pSMB->TotalDataCount = pSMB->DataCount;
5959         pSMB->TotalParameterCount = pSMB->ParameterCount;
5960         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5961         pSMB->DataOffset = cpu_to_le16(offset);
5962         pSMB->Fid = fid;
5963         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5964         pSMB->Reserved4 = 0;
5965         inc_rfc1001_len(pSMB, byte_count);
5966         pSMB->ByteCount = cpu_to_le16(byte_count);
5967
5968         cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5969
5970         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5971         cifs_small_buf_release(pSMB);
5972         if (rc)
5973                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5974                          rc);
5975
5976         /* Note: On -EAGAIN error only caller can retry on handle based calls
5977                 since file handle passed in no longer valid */
5978
5979         return rc;
5980 }
5981
5982 int
5983 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5984                        const char *file_name,
5985                        const struct cifs_unix_set_info_args *args,
5986                        const struct nls_table *nls_codepage, int remap)
5987 {
5988         TRANSACTION2_SPI_REQ *pSMB = NULL;
5989         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5990         int name_len;
5991         int rc = 0;
5992         int bytes_returned = 0;
5993         FILE_UNIX_BASIC_INFO *data_offset;
5994         __u16 params, param_offset, offset, count, byte_count;
5995
5996         cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5997 setPermsRetry:
5998         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5999                       (void **) &pSMBr);
6000         if (rc)
6001                 return rc;
6002
6003         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6004                 name_len =
6005                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6006                                        PATH_MAX, nls_codepage, remap);
6007                 name_len++;     /* trailing null */
6008                 name_len *= 2;
6009         } else {
6010                 name_len = copy_path_name(pSMB->FileName, file_name);
6011         }
6012
6013         params = 6 + name_len;
6014         count = sizeof(FILE_UNIX_BASIC_INFO);
6015         pSMB->MaxParameterCount = cpu_to_le16(2);
6016         /* BB find max SMB PDU from sess structure BB */
6017         pSMB->MaxDataCount = cpu_to_le16(1000);
6018         pSMB->MaxSetupCount = 0;
6019         pSMB->Reserved = 0;
6020         pSMB->Flags = 0;
6021         pSMB->Timeout = 0;
6022         pSMB->Reserved2 = 0;
6023         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6024                                 InformationLevel) - 4;
6025         offset = param_offset + params;
6026         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
6027         data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
6028         memset(data_offset, 0, count);
6029         pSMB->DataOffset = cpu_to_le16(offset);
6030         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6031         pSMB->SetupCount = 1;
6032         pSMB->Reserved3 = 0;
6033         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6034         byte_count = 3 /* pad */  + params + count;
6035         pSMB->ParameterCount = cpu_to_le16(params);
6036         pSMB->DataCount = cpu_to_le16(count);
6037         pSMB->TotalParameterCount = pSMB->ParameterCount;
6038         pSMB->TotalDataCount = pSMB->DataCount;
6039         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6040         pSMB->Reserved4 = 0;
6041         inc_rfc1001_len(pSMB, byte_count);
6042
6043         cifs_fill_unix_set_info(data_offset, args);
6044
6045         pSMB->ByteCount = cpu_to_le16(byte_count);
6046         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6047                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6048         if (rc)
6049                 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6050
6051         cifs_buf_release(pSMB);
6052         if (rc == -EAGAIN)
6053                 goto setPermsRetry;
6054         return rc;
6055 }
6056
6057 #ifdef CONFIG_CIFS_XATTR
6058 /*
6059  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6060  * function used by listxattr and getxattr type calls. When ea_name is set,
6061  * it looks for that attribute name and stuffs that value into the EAData
6062  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6063  * buffer. In both cases, the return value is either the length of the
6064  * resulting data or a negative error code. If EAData is a NULL pointer then
6065  * the data isn't copied to it, but the length is returned.
6066  */
6067 ssize_t
6068 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6069                 const unsigned char *searchName, const unsigned char *ea_name,
6070                 char *EAData, size_t buf_size,
6071                 struct cifs_sb_info *cifs_sb)
6072 {
6073                 /* BB assumes one setup word */
6074         TRANSACTION2_QPI_REQ *pSMB = NULL;
6075         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6076         int remap = cifs_remap(cifs_sb);
6077         struct nls_table *nls_codepage = cifs_sb->local_nls;
6078         int rc = 0;
6079         int bytes_returned;
6080         int list_len;
6081         struct fealist *ea_response_data;
6082         struct fea *temp_fea;
6083         char *temp_ptr;
6084         char *end_of_smb;
6085         __u16 params, byte_count, data_offset;
6086         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6087
6088         cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6089 QAllEAsRetry:
6090         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6091                       (void **) &pSMBr);
6092         if (rc)
6093                 return rc;
6094
6095         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6096                 list_len =
6097                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6098                                        PATH_MAX, nls_codepage, remap);
6099                 list_len++;     /* trailing null */
6100                 list_len *= 2;
6101         } else {
6102                 list_len = copy_path_name(pSMB->FileName, searchName);
6103         }
6104
6105         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6106         pSMB->TotalDataCount = 0;
6107         pSMB->MaxParameterCount = cpu_to_le16(2);
6108         /* BB find exact max SMB PDU from sess structure BB */
6109         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6110         pSMB->MaxSetupCount = 0;
6111         pSMB->Reserved = 0;
6112         pSMB->Flags = 0;
6113         pSMB->Timeout = 0;
6114         pSMB->Reserved2 = 0;
6115         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6116         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6117         pSMB->DataCount = 0;
6118         pSMB->DataOffset = 0;
6119         pSMB->SetupCount = 1;
6120         pSMB->Reserved3 = 0;
6121         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6122         byte_count = params + 1 /* pad */ ;
6123         pSMB->TotalParameterCount = cpu_to_le16(params);
6124         pSMB->ParameterCount = pSMB->TotalParameterCount;
6125         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6126         pSMB->Reserved4 = 0;
6127         inc_rfc1001_len(pSMB, byte_count);
6128         pSMB->ByteCount = cpu_to_le16(byte_count);
6129
6130         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6131                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6132         if (rc) {
6133                 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6134                 goto QAllEAsOut;
6135         }
6136
6137
6138         /* BB also check enough total bytes returned */
6139         /* BB we need to improve the validity checking
6140         of these trans2 responses */
6141
6142         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6143         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6144                 rc = -EIO;      /* bad smb */
6145                 goto QAllEAsOut;
6146         }
6147
6148         /* check that length of list is not more than bcc */
6149         /* check that each entry does not go beyond length
6150            of list */
6151         /* check that each element of each entry does not
6152            go beyond end of list */
6153         /* validate_trans2_offsets() */
6154         /* BB check if start of smb + data_offset > &bcc+ bcc */
6155
6156         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6157         ea_response_data = (struct fealist *)
6158                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6159
6160         list_len = le32_to_cpu(ea_response_data->list_len);
6161         cifs_dbg(FYI, "ea length %d\n", list_len);
6162         if (list_len <= 8) {
6163                 cifs_dbg(FYI, "empty EA list returned from server\n");
6164                 /* didn't find the named attribute */
6165                 if (ea_name)
6166                         rc = -ENODATA;
6167                 goto QAllEAsOut;
6168         }
6169
6170         /* make sure list_len doesn't go past end of SMB */
6171         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6172         if ((char *)ea_response_data + list_len > end_of_smb) {
6173                 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6174                 rc = -EIO;
6175                 goto QAllEAsOut;
6176         }
6177
6178         /* account for ea list len */
6179         list_len -= 4;
6180         temp_fea = ea_response_data->list;
6181         temp_ptr = (char *)temp_fea;
6182         while (list_len > 0) {
6183                 unsigned int name_len;
6184                 __u16 value_len;
6185
6186                 list_len -= 4;
6187                 temp_ptr += 4;
6188                 /* make sure we can read name_len and value_len */
6189                 if (list_len < 0) {
6190                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6191                         rc = -EIO;
6192                         goto QAllEAsOut;
6193                 }
6194
6195                 name_len = temp_fea->name_len;
6196                 value_len = le16_to_cpu(temp_fea->value_len);
6197                 list_len -= name_len + 1 + value_len;
6198                 if (list_len < 0) {
6199                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6200                         rc = -EIO;
6201                         goto QAllEAsOut;
6202                 }
6203
6204                 if (ea_name) {
6205                         if (ea_name_len == name_len &&
6206                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6207                                 temp_ptr += name_len + 1;
6208                                 rc = value_len;
6209                                 if (buf_size == 0)
6210                                         goto QAllEAsOut;
6211                                 if ((size_t)value_len > buf_size) {
6212                                         rc = -ERANGE;
6213                                         goto QAllEAsOut;
6214                                 }
6215                                 memcpy(EAData, temp_ptr, value_len);
6216                                 goto QAllEAsOut;
6217                         }
6218                 } else {
6219                         /* account for prefix user. and trailing null */
6220                         rc += (5 + 1 + name_len);
6221                         if (rc < (int) buf_size) {
6222                                 memcpy(EAData, "user.", 5);
6223                                 EAData += 5;
6224                                 memcpy(EAData, temp_ptr, name_len);
6225                                 EAData += name_len;
6226                                 /* null terminate name */
6227                                 *EAData = 0;
6228                                 ++EAData;
6229                         } else if (buf_size == 0) {
6230                                 /* skip copy - calc size only */
6231                         } else {
6232                                 /* stop before overrun buffer */
6233                                 rc = -ERANGE;
6234                                 break;
6235                         }
6236                 }
6237                 temp_ptr += name_len + 1 + value_len;
6238                 temp_fea = (struct fea *)temp_ptr;
6239         }
6240
6241         /* didn't find the named attribute */
6242         if (ea_name)
6243                 rc = -ENODATA;
6244
6245 QAllEAsOut:
6246         cifs_buf_release(pSMB);
6247         if (rc == -EAGAIN)
6248                 goto QAllEAsRetry;
6249
6250         return (ssize_t)rc;
6251 }
6252
6253 int
6254 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6255              const char *fileName, const char *ea_name, const void *ea_value,
6256              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6257              struct cifs_sb_info *cifs_sb)
6258 {
6259         struct smb_com_transaction2_spi_req *pSMB = NULL;
6260         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6261         struct fealist *parm_data;
6262         int name_len;
6263         int rc = 0;
6264         int bytes_returned = 0;
6265         __u16 params, param_offset, byte_count, offset, count;
6266         int remap = cifs_remap(cifs_sb);
6267
6268         cifs_dbg(FYI, "In SetEA\n");
6269 SetEARetry:
6270         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6271                       (void **) &pSMBr);
6272         if (rc)
6273                 return rc;
6274
6275         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6276                 name_len =
6277                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6278                                        PATH_MAX, nls_codepage, remap);
6279                 name_len++;     /* trailing null */
6280                 name_len *= 2;
6281         } else {
6282                 name_len = copy_path_name(pSMB->FileName, fileName);
6283         }
6284
6285         params = 6 + name_len;
6286
6287         /* done calculating parms using name_len of file name,
6288         now use name_len to calculate length of ea name
6289         we are going to create in the inode xattrs */
6290         if (ea_name == NULL)
6291                 name_len = 0;
6292         else
6293                 name_len = strnlen(ea_name, 255);
6294
6295         count = sizeof(*parm_data) + ea_value_len + name_len;
6296         pSMB->MaxParameterCount = cpu_to_le16(2);
6297         /* BB find max SMB PDU from sess */
6298         pSMB->MaxDataCount = cpu_to_le16(1000);
6299         pSMB->MaxSetupCount = 0;
6300         pSMB->Reserved = 0;
6301         pSMB->Flags = 0;
6302         pSMB->Timeout = 0;
6303         pSMB->Reserved2 = 0;
6304         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6305                                 InformationLevel) - 4;
6306         offset = param_offset + params;
6307         pSMB->InformationLevel =
6308                 cpu_to_le16(SMB_SET_FILE_EA);
6309
6310         parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6311         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6312         pSMB->DataOffset = cpu_to_le16(offset);
6313         pSMB->SetupCount = 1;
6314         pSMB->Reserved3 = 0;
6315         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6316         byte_count = 3 /* pad */  + params + count;
6317         pSMB->DataCount = cpu_to_le16(count);
6318         parm_data->list_len = cpu_to_le32(count);
6319         parm_data->list[0].EA_flags = 0;
6320         /* we checked above that name len is less than 255 */
6321         parm_data->list[0].name_len = (__u8)name_len;
6322         /* EA names are always ASCII */
6323         if (ea_name)
6324                 strncpy(parm_data->list[0].name, ea_name, name_len);
6325         parm_data->list[0].name[name_len] = 0;
6326         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6327         /* caller ensures that ea_value_len is less than 64K but
6328         we need to ensure that it fits within the smb */
6329
6330         /*BB add length check to see if it would fit in
6331              negotiated SMB buffer size BB */
6332         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6333         if (ea_value_len)
6334                 memcpy(parm_data->list[0].name+name_len+1,
6335                        ea_value, ea_value_len);
6336
6337         pSMB->TotalDataCount = pSMB->DataCount;
6338         pSMB->ParameterCount = cpu_to_le16(params);
6339         pSMB->TotalParameterCount = pSMB->ParameterCount;
6340         pSMB->Reserved4 = 0;
6341         inc_rfc1001_len(pSMB, byte_count);
6342         pSMB->ByteCount = cpu_to_le16(byte_count);
6343         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6344                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6345         if (rc)
6346                 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6347
6348         cifs_buf_release(pSMB);
6349
6350         if (rc == -EAGAIN)
6351                 goto SetEARetry;
6352
6353         return rc;
6354 }
6355 #endif