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