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