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