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