Linux 6.7-rc7
[linux-modified.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 commonly used attributes */
1248                 memcpy(&buf->common_attributes,
1249                        &rsp->common_attributes,
1250                        sizeof(buf->common_attributes));
1251                 /* the file_info buf is endian converted by caller */
1252                 buf->AllocationSize = rsp->AllocationSize;
1253                 buf->EndOfFile = rsp->EndOfFile;
1254                 buf->NumberOfLinks = cpu_to_le32(1);
1255                 buf->DeletePending = 0;
1256         }
1257
1258         cifs_buf_release(req);
1259         return rc;
1260 }
1261
1262 static void
1263 cifs_readv_callback(struct mid_q_entry *mid)
1264 {
1265         struct cifs_readdata *rdata = mid->callback_data;
1266         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1267         struct TCP_Server_Info *server = tcon->ses->server;
1268         struct smb_rqst rqst = { .rq_iov = rdata->iov,
1269                                  .rq_nvec = 2,
1270                                  .rq_iter_size = iov_iter_count(&rdata->iter),
1271                                  .rq_iter = rdata->iter };
1272         struct cifs_credits credits = { .value = 1, .instance = 0 };
1273
1274         cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1275                  __func__, mid->mid, mid->mid_state, rdata->result,
1276                  rdata->bytes);
1277
1278         switch (mid->mid_state) {
1279         case MID_RESPONSE_RECEIVED:
1280                 /* result already set, check signature */
1281                 if (server->sign) {
1282                         int rc = 0;
1283
1284                         rc = cifs_verify_signature(&rqst, server,
1285                                                   mid->sequence_number);
1286                         if (rc)
1287                                 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1288                                          rc);
1289                 }
1290                 /* FIXME: should this be counted toward the initiating task? */
1291                 task_io_account_read(rdata->got_bytes);
1292                 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1293                 break;
1294         case MID_REQUEST_SUBMITTED:
1295         case MID_RETRY_NEEDED:
1296                 rdata->result = -EAGAIN;
1297                 if (server->sign && rdata->got_bytes)
1298                         /* reset bytes number since we can not check a sign */
1299                         rdata->got_bytes = 0;
1300                 /* FIXME: should this be counted toward the initiating task? */
1301                 task_io_account_read(rdata->got_bytes);
1302                 cifs_stats_bytes_read(tcon, rdata->got_bytes);
1303                 break;
1304         default:
1305                 rdata->result = -EIO;
1306         }
1307
1308         queue_work(cifsiod_wq, &rdata->work);
1309         release_mid(mid);
1310         add_credits(server, &credits, 0);
1311 }
1312
1313 /* cifs_async_readv - send an async write, and set up mid to handle result */
1314 int
1315 cifs_async_readv(struct cifs_readdata *rdata)
1316 {
1317         int rc;
1318         READ_REQ *smb = NULL;
1319         int wct;
1320         struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1321         struct smb_rqst rqst = { .rq_iov = rdata->iov,
1322                                  .rq_nvec = 2 };
1323
1324         cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1325                  __func__, rdata->offset, rdata->bytes);
1326
1327         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1328                 wct = 12;
1329         else {
1330                 wct = 10; /* old style read */
1331                 if ((rdata->offset >> 32) > 0)  {
1332                         /* can not handle this big offset for old */
1333                         return -EIO;
1334                 }
1335         }
1336
1337         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1338         if (rc)
1339                 return rc;
1340
1341         smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1342         smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1343
1344         smb->AndXCommand = 0xFF;        /* none */
1345         smb->Fid = rdata->cfile->fid.netfid;
1346         smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1347         if (wct == 12)
1348                 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1349         smb->Remaining = 0;
1350         smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1351         smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1352         if (wct == 12)
1353                 smb->ByteCount = 0;
1354         else {
1355                 /* old style read */
1356                 struct smb_com_readx_req *smbr =
1357                         (struct smb_com_readx_req *)smb;
1358                 smbr->ByteCount = 0;
1359         }
1360
1361         /* 4 for RFC1001 length + 1 for BCC */
1362         rdata->iov[0].iov_base = smb;
1363         rdata->iov[0].iov_len = 4;
1364         rdata->iov[1].iov_base = (char *)smb + 4;
1365         rdata->iov[1].iov_len = get_rfc1002_length(smb);
1366
1367         kref_get(&rdata->refcount);
1368         rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1369                              cifs_readv_callback, NULL, rdata, 0, NULL);
1370
1371         if (rc == 0)
1372                 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1373         else
1374                 kref_put(&rdata->refcount, cifs_readdata_release);
1375
1376         cifs_small_buf_release(smb);
1377         return rc;
1378 }
1379
1380 int
1381 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1382             unsigned int *nbytes, char **buf, int *pbuf_type)
1383 {
1384         int rc = -EACCES;
1385         READ_REQ *pSMB = NULL;
1386         READ_RSP *pSMBr = NULL;
1387         char *pReadData = NULL;
1388         int wct;
1389         int resp_buf_type = 0;
1390         struct kvec iov[1];
1391         struct kvec rsp_iov;
1392         __u32 pid = io_parms->pid;
1393         __u16 netfid = io_parms->netfid;
1394         __u64 offset = io_parms->offset;
1395         struct cifs_tcon *tcon = io_parms->tcon;
1396         unsigned int count = io_parms->length;
1397
1398         cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1399         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1400                 wct = 12;
1401         else {
1402                 wct = 10; /* old style read */
1403                 if ((offset >> 32) > 0)  {
1404                         /* can not handle this big offset for old */
1405                         return -EIO;
1406                 }
1407         }
1408
1409         *nbytes = 0;
1410         rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1411         if (rc)
1412                 return rc;
1413
1414         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1415         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1416
1417         /* tcon and ses pointer are checked in smb_init */
1418         if (tcon->ses->server == NULL)
1419                 return -ECONNABORTED;
1420
1421         pSMB->AndXCommand = 0xFF;       /* none */
1422         pSMB->Fid = netfid;
1423         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1424         if (wct == 12)
1425                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1426
1427         pSMB->Remaining = 0;
1428         pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1429         pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1430         if (wct == 12)
1431                 pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1432         else {
1433                 /* old style read */
1434                 struct smb_com_readx_req *pSMBW =
1435                         (struct smb_com_readx_req *)pSMB;
1436                 pSMBW->ByteCount = 0;
1437         }
1438
1439         iov[0].iov_base = (char *)pSMB;
1440         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1441         rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1442                           CIFS_LOG_ERROR, &rsp_iov);
1443         cifs_small_buf_release(pSMB);
1444         cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1445         pSMBr = (READ_RSP *)rsp_iov.iov_base;
1446         if (rc) {
1447                 cifs_dbg(VFS, "Send error in read = %d\n", rc);
1448         } else {
1449                 int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1450                 data_length = data_length << 16;
1451                 data_length += le16_to_cpu(pSMBr->DataLength);
1452                 *nbytes = data_length;
1453
1454                 /*check that DataLength would not go beyond end of SMB */
1455                 if ((data_length > CIFSMaxBufSize)
1456                                 || (data_length > count)) {
1457                         cifs_dbg(FYI, "bad length %d for count %d\n",
1458                                  data_length, count);
1459                         rc = -EIO;
1460                         *nbytes = 0;
1461                 } else {
1462                         pReadData = (char *) (&pSMBr->hdr.Protocol) +
1463                                         le16_to_cpu(pSMBr->DataOffset);
1464 /*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
1465                                 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1466                                 rc = -EFAULT;
1467                         }*/ /* can not use copy_to_user when using page cache*/
1468                         if (*buf)
1469                                 memcpy(*buf, pReadData, data_length);
1470                 }
1471         }
1472
1473         if (*buf) {
1474                 free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1475         } else if (resp_buf_type != CIFS_NO_BUFFER) {
1476                 /* return buffer to caller to free */
1477                 *buf = rsp_iov.iov_base;
1478                 if (resp_buf_type == CIFS_SMALL_BUFFER)
1479                         *pbuf_type = CIFS_SMALL_BUFFER;
1480                 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1481                         *pbuf_type = CIFS_LARGE_BUFFER;
1482         } /* else no valid buffer on return - leave as null */
1483
1484         /* Note: On -EAGAIN error only caller can retry on handle based calls
1485                 since file handle passed in no longer valid */
1486         return rc;
1487 }
1488
1489
1490 int
1491 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1492              unsigned int *nbytes, const char *buf)
1493 {
1494         int rc = -EACCES;
1495         WRITE_REQ *pSMB = NULL;
1496         WRITE_RSP *pSMBr = NULL;
1497         int bytes_returned, wct;
1498         __u32 bytes_sent;
1499         __u16 byte_count;
1500         __u32 pid = io_parms->pid;
1501         __u16 netfid = io_parms->netfid;
1502         __u64 offset = io_parms->offset;
1503         struct cifs_tcon *tcon = io_parms->tcon;
1504         unsigned int count = io_parms->length;
1505
1506         *nbytes = 0;
1507
1508         /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1509         if (tcon->ses == NULL)
1510                 return -ECONNABORTED;
1511
1512         if (tcon->ses->capabilities & CAP_LARGE_FILES)
1513                 wct = 14;
1514         else {
1515                 wct = 12;
1516                 if ((offset >> 32) > 0) {
1517                         /* can not handle big offset for old srv */
1518                         return -EIO;
1519                 }
1520         }
1521
1522         rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1523                       (void **) &pSMBr);
1524         if (rc)
1525                 return rc;
1526
1527         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1528         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1529
1530         /* tcon and ses pointer are checked in smb_init */
1531         if (tcon->ses->server == NULL)
1532                 return -ECONNABORTED;
1533
1534         pSMB->AndXCommand = 0xFF;       /* none */
1535         pSMB->Fid = netfid;
1536         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1537         if (wct == 14)
1538                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1539
1540         pSMB->Reserved = 0xFFFFFFFF;
1541         pSMB->WriteMode = 0;
1542         pSMB->Remaining = 0;
1543
1544         /* Can increase buffer size if buffer is big enough in some cases ie we
1545         can send more if LARGE_WRITE_X capability returned by the server and if
1546         our buffer is big enough or if we convert to iovecs on socket writes
1547         and eliminate the copy to the CIFS buffer */
1548         if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1549                 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1550         } else {
1551                 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1552                          & ~0xFF;
1553         }
1554
1555         if (bytes_sent > count)
1556                 bytes_sent = count;
1557         pSMB->DataOffset =
1558                 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1559         if (buf)
1560                 memcpy(pSMB->Data, buf, bytes_sent);
1561         else if (count != 0) {
1562                 /* No buffer */
1563                 cifs_buf_release(pSMB);
1564                 return -EINVAL;
1565         } /* else setting file size with write of zero bytes */
1566         if (wct == 14)
1567                 byte_count = bytes_sent + 1; /* pad */
1568         else /* wct == 12 */
1569                 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1570
1571         pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1572         pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1573         inc_rfc1001_len(pSMB, byte_count);
1574
1575         if (wct == 14)
1576                 pSMB->ByteCount = cpu_to_le16(byte_count);
1577         else { /* old style write has byte count 4 bytes earlier
1578                   so 4 bytes pad  */
1579                 struct smb_com_writex_req *pSMBW =
1580                         (struct smb_com_writex_req *)pSMB;
1581                 pSMBW->ByteCount = cpu_to_le16(byte_count);
1582         }
1583
1584         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1585                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1586         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1587         if (rc) {
1588                 cifs_dbg(FYI, "Send error in write = %d\n", rc);
1589         } else {
1590                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1591                 *nbytes = (*nbytes) << 16;
1592                 *nbytes += le16_to_cpu(pSMBr->Count);
1593
1594                 /*
1595                  * Mask off high 16 bits when bytes written as returned by the
1596                  * server is greater than bytes requested by the client. Some
1597                  * OS/2 servers are known to set incorrect CountHigh values.
1598                  */
1599                 if (*nbytes > count)
1600                         *nbytes &= 0xFFFF;
1601         }
1602
1603         cifs_buf_release(pSMB);
1604
1605         /* Note: On -EAGAIN error only caller can retry on handle based calls
1606                 since file handle passed in no longer valid */
1607
1608         return rc;
1609 }
1610
1611 /*
1612  * Check the mid_state and signature on received buffer (if any), and queue the
1613  * workqueue completion task.
1614  */
1615 static void
1616 cifs_writev_callback(struct mid_q_entry *mid)
1617 {
1618         struct cifs_writedata *wdata = mid->callback_data;
1619         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1620         unsigned int written;
1621         WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1622         struct cifs_credits credits = { .value = 1, .instance = 0 };
1623
1624         switch (mid->mid_state) {
1625         case MID_RESPONSE_RECEIVED:
1626                 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1627                 if (wdata->result != 0)
1628                         break;
1629
1630                 written = le16_to_cpu(smb->CountHigh);
1631                 written <<= 16;
1632                 written += le16_to_cpu(smb->Count);
1633                 /*
1634                  * Mask off high 16 bits when bytes written as returned
1635                  * by the server is greater than bytes requested by the
1636                  * client. OS/2 servers are known to set incorrect
1637                  * CountHigh values.
1638                  */
1639                 if (written > wdata->bytes)
1640                         written &= 0xFFFF;
1641
1642                 if (written < wdata->bytes)
1643                         wdata->result = -ENOSPC;
1644                 else
1645                         wdata->bytes = written;
1646                 break;
1647         case MID_REQUEST_SUBMITTED:
1648         case MID_RETRY_NEEDED:
1649                 wdata->result = -EAGAIN;
1650                 break;
1651         default:
1652                 wdata->result = -EIO;
1653                 break;
1654         }
1655
1656         queue_work(cifsiod_wq, &wdata->work);
1657         release_mid(mid);
1658         add_credits(tcon->ses->server, &credits, 0);
1659 }
1660
1661 /* cifs_async_writev - send an async write, and set up mid to handle result */
1662 int
1663 cifs_async_writev(struct cifs_writedata *wdata,
1664                   void (*release)(struct kref *kref))
1665 {
1666         int rc = -EACCES;
1667         WRITE_REQ *smb = NULL;
1668         int wct;
1669         struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1670         struct kvec iov[2];
1671         struct smb_rqst rqst = { };
1672
1673         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1674                 wct = 14;
1675         } else {
1676                 wct = 12;
1677                 if (wdata->offset >> 32 > 0) {
1678                         /* can not handle big offset for old srv */
1679                         return -EIO;
1680                 }
1681         }
1682
1683         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1684         if (rc)
1685                 goto async_writev_out;
1686
1687         smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
1688         smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
1689
1690         smb->AndXCommand = 0xFF;        /* none */
1691         smb->Fid = wdata->cfile->fid.netfid;
1692         smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
1693         if (wct == 14)
1694                 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
1695         smb->Reserved = 0xFFFFFFFF;
1696         smb->WriteMode = 0;
1697         smb->Remaining = 0;
1698
1699         smb->DataOffset =
1700             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1701
1702         /* 4 for RFC1001 length + 1 for BCC */
1703         iov[0].iov_len = 4;
1704         iov[0].iov_base = smb;
1705         iov[1].iov_len = get_rfc1002_length(smb) + 1;
1706         iov[1].iov_base = (char *)smb + 4;
1707
1708         rqst.rq_iov = iov;
1709         rqst.rq_nvec = 2;
1710         rqst.rq_iter = wdata->iter;
1711         rqst.rq_iter_size = iov_iter_count(&wdata->iter);
1712
1713         cifs_dbg(FYI, "async write at %llu %u bytes\n",
1714                  wdata->offset, wdata->bytes);
1715
1716         smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
1717         smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
1718
1719         if (wct == 14) {
1720                 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
1721                 put_bcc(wdata->bytes + 1, &smb->hdr);
1722         } else {
1723                 /* wct == 12 */
1724                 struct smb_com_writex_req *smbw =
1725                                 (struct smb_com_writex_req *)smb;
1726                 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
1727                 put_bcc(wdata->bytes + 5, &smbw->hdr);
1728                 iov[1].iov_len += 4; /* pad bigger by four bytes */
1729         }
1730
1731         kref_get(&wdata->refcount);
1732         rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1733                              cifs_writev_callback, NULL, wdata, 0, NULL);
1734
1735         if (rc == 0)
1736                 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1737         else
1738                 kref_put(&wdata->refcount, release);
1739
1740 async_writev_out:
1741         cifs_small_buf_release(smb);
1742         return rc;
1743 }
1744
1745 int
1746 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
1747               unsigned int *nbytes, struct kvec *iov, int n_vec)
1748 {
1749         int rc;
1750         WRITE_REQ *pSMB = NULL;
1751         int wct;
1752         int smb_hdr_len;
1753         int resp_buf_type = 0;
1754         __u32 pid = io_parms->pid;
1755         __u16 netfid = io_parms->netfid;
1756         __u64 offset = io_parms->offset;
1757         struct cifs_tcon *tcon = io_parms->tcon;
1758         unsigned int count = io_parms->length;
1759         struct kvec rsp_iov;
1760
1761         *nbytes = 0;
1762
1763         cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
1764
1765         if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1766                 wct = 14;
1767         } else {
1768                 wct = 12;
1769                 if ((offset >> 32) > 0) {
1770                         /* can not handle big offset for old srv */
1771                         return -EIO;
1772                 }
1773         }
1774         rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1775         if (rc)
1776                 return rc;
1777
1778         pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1779         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1780
1781         /* tcon and ses pointer are checked in smb_init */
1782         if (tcon->ses->server == NULL)
1783                 return -ECONNABORTED;
1784
1785         pSMB->AndXCommand = 0xFF;       /* none */
1786         pSMB->Fid = netfid;
1787         pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1788         if (wct == 14)
1789                 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1790         pSMB->Reserved = 0xFFFFFFFF;
1791         pSMB->WriteMode = 0;
1792         pSMB->Remaining = 0;
1793
1794         pSMB->DataOffset =
1795             cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1796
1797         pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1798         pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1799         /* header + 1 byte pad */
1800         smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1801         if (wct == 14)
1802                 inc_rfc1001_len(pSMB, count + 1);
1803         else /* wct == 12 */
1804                 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1805         if (wct == 14)
1806                 pSMB->ByteCount = cpu_to_le16(count + 1);
1807         else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1808                 struct smb_com_writex_req *pSMBW =
1809                                 (struct smb_com_writex_req *)pSMB;
1810                 pSMBW->ByteCount = cpu_to_le16(count + 5);
1811         }
1812         iov[0].iov_base = pSMB;
1813         if (wct == 14)
1814                 iov[0].iov_len = smb_hdr_len + 4;
1815         else /* wct == 12 pad bigger by four bytes */
1816                 iov[0].iov_len = smb_hdr_len + 8;
1817
1818         rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
1819                           &rsp_iov);
1820         cifs_small_buf_release(pSMB);
1821         cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1822         if (rc) {
1823                 cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
1824         } else if (resp_buf_type == 0) {
1825                 /* presumably this can not happen, but best to be safe */
1826                 rc = -EIO;
1827         } else {
1828                 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
1829                 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1830                 *nbytes = (*nbytes) << 16;
1831                 *nbytes += le16_to_cpu(pSMBr->Count);
1832
1833                 /*
1834                  * Mask off high 16 bits when bytes written as returned by the
1835                  * server is greater than bytes requested by the client. OS/2
1836                  * servers are known to set incorrect CountHigh values.
1837                  */
1838                 if (*nbytes > count)
1839                         *nbytes &= 0xFFFF;
1840         }
1841
1842         free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1843
1844         /* Note: On -EAGAIN error only caller can retry on handle based calls
1845                 since file handle passed in no longer valid */
1846
1847         return rc;
1848 }
1849
1850 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
1851                const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
1852                const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
1853 {
1854         int rc = 0;
1855         LOCK_REQ *pSMB = NULL;
1856         struct kvec iov[2];
1857         struct kvec rsp_iov;
1858         int resp_buf_type;
1859         __u16 count;
1860
1861         cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
1862                  num_lock, num_unlock);
1863
1864         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1865         if (rc)
1866                 return rc;
1867
1868         pSMB->Timeout = 0;
1869         pSMB->NumberOfLocks = cpu_to_le16(num_lock);
1870         pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
1871         pSMB->LockType = lock_type;
1872         pSMB->AndXCommand = 0xFF; /* none */
1873         pSMB->Fid = netfid; /* netfid stays le */
1874
1875         count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1876         inc_rfc1001_len(pSMB, count);
1877         pSMB->ByteCount = cpu_to_le16(count);
1878
1879         iov[0].iov_base = (char *)pSMB;
1880         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
1881                          (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1882         iov[1].iov_base = (char *)buf;
1883         iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
1884
1885         cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1886         rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
1887                           CIFS_NO_RSP_BUF, &rsp_iov);
1888         cifs_small_buf_release(pSMB);
1889         if (rc)
1890                 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
1891
1892         return rc;
1893 }
1894
1895 int
1896 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
1897             const __u16 smb_file_id, const __u32 netpid, const __u64 len,
1898             const __u64 offset, const __u32 numUnlock,
1899             const __u32 numLock, const __u8 lockType,
1900             const bool waitFlag, const __u8 oplock_level)
1901 {
1902         int rc = 0;
1903         LOCK_REQ *pSMB = NULL;
1904 /*      LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
1905         int bytes_returned;
1906         int flags = 0;
1907         __u16 count;
1908
1909         cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
1910                  (int)waitFlag, numLock);
1911         rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1912
1913         if (rc)
1914                 return rc;
1915
1916         if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1917                 /* no response expected */
1918                 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
1919                 pSMB->Timeout = 0;
1920         } else if (waitFlag) {
1921                 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1922                 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1923         } else {
1924                 pSMB->Timeout = 0;
1925         }
1926
1927         pSMB->NumberOfLocks = cpu_to_le16(numLock);
1928         pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1929         pSMB->LockType = lockType;
1930         pSMB->OplockLevel = oplock_level;
1931         pSMB->AndXCommand = 0xFF;       /* none */
1932         pSMB->Fid = smb_file_id; /* netfid stays le */
1933
1934         if ((numLock != 0) || (numUnlock != 0)) {
1935                 pSMB->Locks[0].Pid = cpu_to_le16(netpid);
1936                 /* BB where to store pid high? */
1937                 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
1938                 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
1939                 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
1940                 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
1941                 count = sizeof(LOCKING_ANDX_RANGE);
1942         } else {
1943                 /* oplock break */
1944                 count = 0;
1945         }
1946         inc_rfc1001_len(pSMB, count);
1947         pSMB->ByteCount = cpu_to_le16(count);
1948
1949         if (waitFlag)
1950                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1951                         (struct smb_hdr *) pSMB, &bytes_returned);
1952         else
1953                 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
1954         cifs_small_buf_release(pSMB);
1955         cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
1956         if (rc)
1957                 cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
1958
1959         /* Note: On -EAGAIN error only caller can retry on handle based calls
1960         since file handle passed in no longer valid */
1961         return rc;
1962 }
1963
1964 int
1965 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
1966                 const __u16 smb_file_id, const __u32 netpid,
1967                 const loff_t start_offset, const __u64 len,
1968                 struct file_lock *pLockData, const __u16 lock_type,
1969                 const bool waitFlag)
1970 {
1971         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
1972         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1973         struct cifs_posix_lock *parm_data;
1974         int rc = 0;
1975         int timeout = 0;
1976         int bytes_returned = 0;
1977         int resp_buf_type = 0;
1978         __u16 params, param_offset, offset, byte_count, count;
1979         struct kvec iov[1];
1980         struct kvec rsp_iov;
1981
1982         cifs_dbg(FYI, "Posix Lock\n");
1983
1984         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1985
1986         if (rc)
1987                 return rc;
1988
1989         pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1990
1991         params = 6;
1992         pSMB->MaxSetupCount = 0;
1993         pSMB->Reserved = 0;
1994         pSMB->Flags = 0;
1995         pSMB->Reserved2 = 0;
1996         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1997         offset = param_offset + params;
1998
1999         count = sizeof(struct cifs_posix_lock);
2000         pSMB->MaxParameterCount = cpu_to_le16(2);
2001         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2002         pSMB->SetupCount = 1;
2003         pSMB->Reserved3 = 0;
2004         if (pLockData)
2005                 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2006         else
2007                 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2008         byte_count = 3 /* pad */  + params + count;
2009         pSMB->DataCount = cpu_to_le16(count);
2010         pSMB->ParameterCount = cpu_to_le16(params);
2011         pSMB->TotalDataCount = pSMB->DataCount;
2012         pSMB->TotalParameterCount = pSMB->ParameterCount;
2013         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2014         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2015         parm_data = (struct cifs_posix_lock *)
2016                         (((char *)pSMB) + offset + 4);
2017
2018         parm_data->lock_type = cpu_to_le16(lock_type);
2019         if (waitFlag) {
2020                 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2021                 parm_data->lock_flags = cpu_to_le16(1);
2022                 pSMB->Timeout = cpu_to_le32(-1);
2023         } else
2024                 pSMB->Timeout = 0;
2025
2026         parm_data->pid = cpu_to_le32(netpid);
2027         parm_data->start = cpu_to_le64(start_offset);
2028         parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2029
2030         pSMB->DataOffset = cpu_to_le16(offset);
2031         pSMB->Fid = smb_file_id;
2032         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2033         pSMB->Reserved4 = 0;
2034         inc_rfc1001_len(pSMB, byte_count);
2035         pSMB->ByteCount = cpu_to_le16(byte_count);
2036         if (waitFlag) {
2037                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2038                         (struct smb_hdr *) pSMBr, &bytes_returned);
2039         } else {
2040                 iov[0].iov_base = (char *)pSMB;
2041                 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2042                 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2043                                 &resp_buf_type, timeout, &rsp_iov);
2044                 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2045         }
2046         cifs_small_buf_release(pSMB);
2047
2048         if (rc) {
2049                 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2050         } else if (pLockData) {
2051                 /* lock structure can be returned on get */
2052                 __u16 data_offset;
2053                 __u16 data_count;
2054                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2055
2056                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2057                         rc = -EIO;      /* bad smb */
2058                         goto plk_err_exit;
2059                 }
2060                 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2061                 data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2062                 if (data_count < sizeof(struct cifs_posix_lock)) {
2063                         rc = -EIO;
2064                         goto plk_err_exit;
2065                 }
2066                 parm_data = (struct cifs_posix_lock *)
2067                         ((char *)&pSMBr->hdr.Protocol + data_offset);
2068                 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2069                         pLockData->fl_type = F_UNLCK;
2070                 else {
2071                         if (parm_data->lock_type ==
2072                                         cpu_to_le16(CIFS_RDLCK))
2073                                 pLockData->fl_type = F_RDLCK;
2074                         else if (parm_data->lock_type ==
2075                                         cpu_to_le16(CIFS_WRLCK))
2076                                 pLockData->fl_type = F_WRLCK;
2077
2078                         pLockData->fl_start = le64_to_cpu(parm_data->start);
2079                         pLockData->fl_end = pLockData->fl_start +
2080                                 (le64_to_cpu(parm_data->length) ?
2081                                  le64_to_cpu(parm_data->length) - 1 : 0);
2082                         pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2083                 }
2084         }
2085
2086 plk_err_exit:
2087         free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2088
2089         /* Note: On -EAGAIN error only caller can retry on handle based calls
2090            since file handle passed in no longer valid */
2091
2092         return rc;
2093 }
2094
2095
2096 int
2097 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2098 {
2099         int rc = 0;
2100         CLOSE_REQ *pSMB = NULL;
2101         cifs_dbg(FYI, "In CIFSSMBClose\n");
2102
2103 /* do not retry on dead session on close */
2104         rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2105         if (rc == -EAGAIN)
2106                 return 0;
2107         if (rc)
2108                 return rc;
2109
2110         pSMB->FileID = (__u16) smb_file_id;
2111         pSMB->LastWriteTime = 0xFFFFFFFF;
2112         pSMB->ByteCount = 0;
2113         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2114         cifs_small_buf_release(pSMB);
2115         cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2116         if (rc) {
2117                 if (rc != -EINTR) {
2118                         /* EINTR is expected when user ctl-c to kill app */
2119                         cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2120                 }
2121         }
2122
2123         /* Since session is dead, file will be closed on server already */
2124         if (rc == -EAGAIN)
2125                 rc = 0;
2126
2127         return rc;
2128 }
2129
2130 int
2131 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2132 {
2133         int rc = 0;
2134         FLUSH_REQ *pSMB = NULL;
2135         cifs_dbg(FYI, "In CIFSSMBFlush\n");
2136
2137         rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2138         if (rc)
2139                 return rc;
2140
2141         pSMB->FileID = (__u16) smb_file_id;
2142         pSMB->ByteCount = 0;
2143         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2144         cifs_small_buf_release(pSMB);
2145         cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2146         if (rc)
2147                 cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2148
2149         return rc;
2150 }
2151
2152 int
2153 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2154               const char *from_name, const char *to_name,
2155               struct cifs_sb_info *cifs_sb)
2156 {
2157         int rc = 0;
2158         RENAME_REQ *pSMB = NULL;
2159         RENAME_RSP *pSMBr = NULL;
2160         int bytes_returned;
2161         int name_len, name_len2;
2162         __u16 count;
2163         int remap = cifs_remap(cifs_sb);
2164
2165         cifs_dbg(FYI, "In CIFSSMBRename\n");
2166 renameRetry:
2167         rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2168                       (void **) &pSMBr);
2169         if (rc)
2170                 return rc;
2171
2172         pSMB->BufferFormat = 0x04;
2173         pSMB->SearchAttributes =
2174             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2175                         ATTR_DIRECTORY);
2176
2177         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2178                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2179                                               from_name, PATH_MAX,
2180                                               cifs_sb->local_nls, remap);
2181                 name_len++;     /* trailing null */
2182                 name_len *= 2;
2183                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2184         /* protocol requires ASCII signature byte on Unicode string */
2185                 pSMB->OldFileName[name_len + 1] = 0x00;
2186                 name_len2 =
2187                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2188                                        to_name, PATH_MAX, cifs_sb->local_nls,
2189                                        remap);
2190                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2191                 name_len2 *= 2; /* convert to bytes */
2192         } else {
2193                 name_len = copy_path_name(pSMB->OldFileName, from_name);
2194                 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2195                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2196                 name_len2++;    /* signature byte */
2197         }
2198
2199         count = 1 /* 1st signature byte */  + name_len + name_len2;
2200         inc_rfc1001_len(pSMB, count);
2201         pSMB->ByteCount = cpu_to_le16(count);
2202
2203         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2204                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2205         cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2206         if (rc)
2207                 cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2208
2209         cifs_buf_release(pSMB);
2210
2211         if (rc == -EAGAIN)
2212                 goto renameRetry;
2213
2214         return rc;
2215 }
2216
2217 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2218                 int netfid, const char *target_name,
2219                 const struct nls_table *nls_codepage, int remap)
2220 {
2221         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2222         struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2223         struct set_file_rename *rename_info;
2224         char *data_offset;
2225         char dummy_string[30];
2226         int rc = 0;
2227         int bytes_returned = 0;
2228         int len_of_str;
2229         __u16 params, param_offset, offset, count, byte_count;
2230
2231         cifs_dbg(FYI, "Rename to File by handle\n");
2232         rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2233                         (void **) &pSMBr);
2234         if (rc)
2235                 return rc;
2236
2237         params = 6;
2238         pSMB->MaxSetupCount = 0;
2239         pSMB->Reserved = 0;
2240         pSMB->Flags = 0;
2241         pSMB->Timeout = 0;
2242         pSMB->Reserved2 = 0;
2243         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2244         offset = param_offset + params;
2245
2246         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2247         data_offset = (char *)(pSMB) + offset + 4;
2248         rename_info = (struct set_file_rename *) data_offset;
2249         pSMB->MaxParameterCount = cpu_to_le16(2);
2250         pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2251         pSMB->SetupCount = 1;
2252         pSMB->Reserved3 = 0;
2253         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2254         byte_count = 3 /* pad */  + params;
2255         pSMB->ParameterCount = cpu_to_le16(params);
2256         pSMB->TotalParameterCount = pSMB->ParameterCount;
2257         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2258         pSMB->DataOffset = cpu_to_le16(offset);
2259         /* construct random name ".cifs_tmp<inodenum><mid>" */
2260         rename_info->overwrite = cpu_to_le32(1);
2261         rename_info->root_fid  = 0;
2262         /* unicode only call */
2263         if (target_name == NULL) {
2264                 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2265                 len_of_str =
2266                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2267                                         dummy_string, 24, nls_codepage, remap);
2268         } else {
2269                 len_of_str =
2270                         cifsConvertToUTF16((__le16 *)rename_info->target_name,
2271                                         target_name, PATH_MAX, nls_codepage,
2272                                         remap);
2273         }
2274         rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2275         count = sizeof(struct set_file_rename) + (2 * len_of_str);
2276         byte_count += count;
2277         pSMB->DataCount = cpu_to_le16(count);
2278         pSMB->TotalDataCount = pSMB->DataCount;
2279         pSMB->Fid = netfid;
2280         pSMB->InformationLevel =
2281                 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2282         pSMB->Reserved4 = 0;
2283         inc_rfc1001_len(pSMB, byte_count);
2284         pSMB->ByteCount = cpu_to_le16(byte_count);
2285         rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2286                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2287         cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2288         if (rc)
2289                 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2290                          rc);
2291
2292         cifs_buf_release(pSMB);
2293
2294         /* Note: On -EAGAIN error only caller can retry on handle based calls
2295                 since file handle passed in no longer valid */
2296
2297         return rc;
2298 }
2299
2300 int
2301 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2302             const char *fromName, const __u16 target_tid, const char *toName,
2303             const int flags, const struct nls_table *nls_codepage, int remap)
2304 {
2305         int rc = 0;
2306         COPY_REQ *pSMB = NULL;
2307         COPY_RSP *pSMBr = NULL;
2308         int bytes_returned;
2309         int name_len, name_len2;
2310         __u16 count;
2311
2312         cifs_dbg(FYI, "In CIFSSMBCopy\n");
2313 copyRetry:
2314         rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2315                         (void **) &pSMBr);
2316         if (rc)
2317                 return rc;
2318
2319         pSMB->BufferFormat = 0x04;
2320         pSMB->Tid2 = target_tid;
2321
2322         pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2323
2324         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2325                 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2326                                               fromName, PATH_MAX, nls_codepage,
2327                                               remap);
2328                 name_len++;     /* trailing null */
2329                 name_len *= 2;
2330                 pSMB->OldFileName[name_len] = 0x04;     /* pad */
2331                 /* protocol requires ASCII signature byte on Unicode string */
2332                 pSMB->OldFileName[name_len + 1] = 0x00;
2333                 name_len2 =
2334                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2335                                        toName, PATH_MAX, nls_codepage, remap);
2336                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2337                 name_len2 *= 2; /* convert to bytes */
2338         } else {
2339                 name_len = copy_path_name(pSMB->OldFileName, fromName);
2340                 pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2341                 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2342                 name_len2++;    /* signature byte */
2343         }
2344
2345         count = 1 /* 1st signature byte */  + name_len + name_len2;
2346         inc_rfc1001_len(pSMB, count);
2347         pSMB->ByteCount = cpu_to_le16(count);
2348
2349         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2350                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2351         if (rc) {
2352                 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2353                          rc, le16_to_cpu(pSMBr->CopyCount));
2354         }
2355         cifs_buf_release(pSMB);
2356
2357         if (rc == -EAGAIN)
2358                 goto copyRetry;
2359
2360         return rc;
2361 }
2362
2363 int
2364 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2365                       const char *fromName, const char *toName,
2366                       const struct nls_table *nls_codepage, int remap)
2367 {
2368         TRANSACTION2_SPI_REQ *pSMB = NULL;
2369         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2370         char *data_offset;
2371         int name_len;
2372         int name_len_target;
2373         int rc = 0;
2374         int bytes_returned = 0;
2375         __u16 params, param_offset, offset, byte_count;
2376
2377         cifs_dbg(FYI, "In Symlink Unix style\n");
2378 createSymLinkRetry:
2379         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2380                       (void **) &pSMBr);
2381         if (rc)
2382                 return rc;
2383
2384         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2385                 name_len =
2386                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2387                                 /* find define for this maxpathcomponent */
2388                                         PATH_MAX, nls_codepage, remap);
2389                 name_len++;     /* trailing null */
2390                 name_len *= 2;
2391
2392         } else {
2393                 name_len = copy_path_name(pSMB->FileName, fromName);
2394         }
2395         params = 6 + name_len;
2396         pSMB->MaxSetupCount = 0;
2397         pSMB->Reserved = 0;
2398         pSMB->Flags = 0;
2399         pSMB->Timeout = 0;
2400         pSMB->Reserved2 = 0;
2401         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2402                                 InformationLevel) - 4;
2403         offset = param_offset + params;
2404
2405         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2406         data_offset = (char *)pSMB + offset + 4;
2407         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2408                 name_len_target =
2409                     cifsConvertToUTF16((__le16 *) data_offset, toName,
2410                                 /* find define for this maxpathcomponent */
2411                                         PATH_MAX, nls_codepage, remap);
2412                 name_len_target++;      /* trailing null */
2413                 name_len_target *= 2;
2414         } else {
2415                 name_len_target = copy_path_name(data_offset, toName);
2416         }
2417
2418         pSMB->MaxParameterCount = cpu_to_le16(2);
2419         /* BB find exact max on data count below from sess */
2420         pSMB->MaxDataCount = cpu_to_le16(1000);
2421         pSMB->SetupCount = 1;
2422         pSMB->Reserved3 = 0;
2423         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2424         byte_count = 3 /* pad */  + params + name_len_target;
2425         pSMB->DataCount = cpu_to_le16(name_len_target);
2426         pSMB->ParameterCount = cpu_to_le16(params);
2427         pSMB->TotalDataCount = pSMB->DataCount;
2428         pSMB->TotalParameterCount = pSMB->ParameterCount;
2429         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2430         pSMB->DataOffset = cpu_to_le16(offset);
2431         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2432         pSMB->Reserved4 = 0;
2433         inc_rfc1001_len(pSMB, byte_count);
2434         pSMB->ByteCount = cpu_to_le16(byte_count);
2435         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2436                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2437         cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2438         if (rc)
2439                 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2440                          rc);
2441
2442         cifs_buf_release(pSMB);
2443
2444         if (rc == -EAGAIN)
2445                 goto createSymLinkRetry;
2446
2447         return rc;
2448 }
2449
2450 int
2451 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2452                        const char *fromName, const char *toName,
2453                        const struct nls_table *nls_codepage, int remap)
2454 {
2455         TRANSACTION2_SPI_REQ *pSMB = NULL;
2456         TRANSACTION2_SPI_RSP *pSMBr = NULL;
2457         char *data_offset;
2458         int name_len;
2459         int name_len_target;
2460         int rc = 0;
2461         int bytes_returned = 0;
2462         __u16 params, param_offset, offset, byte_count;
2463
2464         cifs_dbg(FYI, "In Create Hard link Unix style\n");
2465 createHardLinkRetry:
2466         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2467                       (void **) &pSMBr);
2468         if (rc)
2469                 return rc;
2470
2471         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2472                 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2473                                               PATH_MAX, nls_codepage, remap);
2474                 name_len++;     /* trailing null */
2475                 name_len *= 2;
2476
2477         } else {
2478                 name_len = copy_path_name(pSMB->FileName, toName);
2479         }
2480         params = 6 + name_len;
2481         pSMB->MaxSetupCount = 0;
2482         pSMB->Reserved = 0;
2483         pSMB->Flags = 0;
2484         pSMB->Timeout = 0;
2485         pSMB->Reserved2 = 0;
2486         param_offset = offsetof(struct smb_com_transaction2_spi_req,
2487                                 InformationLevel) - 4;
2488         offset = param_offset + params;
2489
2490         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2491         data_offset = (char *)pSMB + offset + 4;
2492         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2493                 name_len_target =
2494                     cifsConvertToUTF16((__le16 *) data_offset, fromName,
2495                                        PATH_MAX, nls_codepage, remap);
2496                 name_len_target++;      /* trailing null */
2497                 name_len_target *= 2;
2498         } else {
2499                 name_len_target = copy_path_name(data_offset, fromName);
2500         }
2501
2502         pSMB->MaxParameterCount = cpu_to_le16(2);
2503         /* BB find exact max on data count below from sess*/
2504         pSMB->MaxDataCount = cpu_to_le16(1000);
2505         pSMB->SetupCount = 1;
2506         pSMB->Reserved3 = 0;
2507         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2508         byte_count = 3 /* pad */  + params + name_len_target;
2509         pSMB->ParameterCount = cpu_to_le16(params);
2510         pSMB->TotalParameterCount = pSMB->ParameterCount;
2511         pSMB->DataCount = cpu_to_le16(name_len_target);
2512         pSMB->TotalDataCount = pSMB->DataCount;
2513         pSMB->ParameterOffset = cpu_to_le16(param_offset);
2514         pSMB->DataOffset = cpu_to_le16(offset);
2515         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2516         pSMB->Reserved4 = 0;
2517         inc_rfc1001_len(pSMB, byte_count);
2518         pSMB->ByteCount = cpu_to_le16(byte_count);
2519         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2520                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2521         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2522         if (rc)
2523                 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2524                          rc);
2525
2526         cifs_buf_release(pSMB);
2527         if (rc == -EAGAIN)
2528                 goto createHardLinkRetry;
2529
2530         return rc;
2531 }
2532
2533 int
2534 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2535                    const char *from_name, const char *to_name,
2536                    struct cifs_sb_info *cifs_sb)
2537 {
2538         int rc = 0;
2539         NT_RENAME_REQ *pSMB = NULL;
2540         RENAME_RSP *pSMBr = NULL;
2541         int bytes_returned;
2542         int name_len, name_len2;
2543         __u16 count;
2544         int remap = cifs_remap(cifs_sb);
2545
2546         cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2547 winCreateHardLinkRetry:
2548
2549         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2550                       (void **) &pSMBr);
2551         if (rc)
2552                 return rc;
2553
2554         pSMB->SearchAttributes =
2555             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2556                         ATTR_DIRECTORY);
2557         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2558         pSMB->ClusterCount = 0;
2559
2560         pSMB->BufferFormat = 0x04;
2561
2562         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2563                 name_len =
2564                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2565                                        PATH_MAX, cifs_sb->local_nls, remap);
2566                 name_len++;     /* trailing null */
2567                 name_len *= 2;
2568
2569                 /* protocol specifies ASCII buffer format (0x04) for unicode */
2570                 pSMB->OldFileName[name_len] = 0x04;
2571                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2572                 name_len2 =
2573                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2574                                        to_name, PATH_MAX, cifs_sb->local_nls,
2575                                        remap);
2576                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2577                 name_len2 *= 2; /* convert to bytes */
2578         } else {
2579                 name_len = copy_path_name(pSMB->OldFileName, from_name);
2580                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
2581                 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2582                 name_len2++;    /* signature byte */
2583         }
2584
2585         count = 1 /* string type byte */  + name_len + name_len2;
2586         inc_rfc1001_len(pSMB, count);
2587         pSMB->ByteCount = cpu_to_le16(count);
2588
2589         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2590                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2591         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2592         if (rc)
2593                 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2594
2595         cifs_buf_release(pSMB);
2596         if (rc == -EAGAIN)
2597                 goto winCreateHardLinkRetry;
2598
2599         return rc;
2600 }
2601
2602 int
2603 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2604                         const unsigned char *searchName, char **symlinkinfo,
2605                         const struct nls_table *nls_codepage, int remap)
2606 {
2607 /* SMB_QUERY_FILE_UNIX_LINK */
2608         TRANSACTION2_QPI_REQ *pSMB = NULL;
2609         TRANSACTION2_QPI_RSP *pSMBr = NULL;
2610         int rc = 0;
2611         int bytes_returned;
2612         int name_len;
2613         __u16 params, byte_count;
2614         char *data_start;
2615
2616         cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2617
2618 querySymLinkRetry:
2619         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2620                       (void **) &pSMBr);
2621         if (rc)
2622                 return rc;
2623
2624         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2625                 name_len =
2626                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
2627                                            searchName, PATH_MAX, nls_codepage,
2628                                            remap);
2629                 name_len++;     /* trailing null */
2630                 name_len *= 2;
2631         } else {
2632                 name_len = copy_path_name(pSMB->FileName, searchName);
2633         }
2634
2635         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
2636         pSMB->TotalDataCount = 0;
2637         pSMB->MaxParameterCount = cpu_to_le16(2);
2638         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2639         pSMB->MaxSetupCount = 0;
2640         pSMB->Reserved = 0;
2641         pSMB->Flags = 0;
2642         pSMB->Timeout = 0;
2643         pSMB->Reserved2 = 0;
2644         pSMB->ParameterOffset = cpu_to_le16(offsetof(
2645         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2646         pSMB->DataCount = 0;
2647         pSMB->DataOffset = 0;
2648         pSMB->SetupCount = 1;
2649         pSMB->Reserved3 = 0;
2650         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2651         byte_count = params + 1 /* pad */ ;
2652         pSMB->TotalParameterCount = cpu_to_le16(params);
2653         pSMB->ParameterCount = pSMB->TotalParameterCount;
2654         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2655         pSMB->Reserved4 = 0;
2656         inc_rfc1001_len(pSMB, byte_count);
2657         pSMB->ByteCount = cpu_to_le16(byte_count);
2658
2659         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2660                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2661         if (rc) {
2662                 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2663         } else {
2664                 /* decode response */
2665
2666                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2667                 /* BB also check enough total bytes returned */
2668                 if (rc || get_bcc(&pSMBr->hdr) < 2)
2669                         rc = -EIO;
2670                 else {
2671                         bool is_unicode;
2672                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2673
2674                         data_start = ((char *) &pSMBr->hdr.Protocol) +
2675                                            le16_to_cpu(pSMBr->t2.DataOffset);
2676
2677                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2678                                 is_unicode = true;
2679                         else
2680                                 is_unicode = false;
2681
2682                         /* BB FIXME investigate remapping reserved chars here */
2683                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
2684                                         count, is_unicode, nls_codepage);
2685                         if (!*symlinkinfo)
2686                                 rc = -ENOMEM;
2687                 }
2688         }
2689         cifs_buf_release(pSMB);
2690         if (rc == -EAGAIN)
2691                 goto querySymLinkRetry;
2692         return rc;
2693 }
2694
2695 int cifs_query_reparse_point(const unsigned int xid,
2696                              struct cifs_tcon *tcon,
2697                              struct cifs_sb_info *cifs_sb,
2698                              const char *full_path,
2699                              u32 *tag, struct kvec *rsp,
2700                              int *rsp_buftype)
2701 {
2702         struct cifs_open_parms oparms;
2703         TRANSACT_IOCTL_REQ *io_req = NULL;
2704         TRANSACT_IOCTL_RSP *io_rsp = NULL;
2705         struct cifs_fid fid;
2706         __u32 data_offset, data_count;
2707         __u8 *start, *end;
2708         int io_rsp_len;
2709         int oplock = 0;
2710         int rc;
2711
2712         cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
2713
2714         if (cap_unix(tcon->ses))
2715                 return -EOPNOTSUPP;
2716
2717         oparms = (struct cifs_open_parms) {
2718                 .tcon = tcon,
2719                 .cifs_sb = cifs_sb,
2720                 .desired_access = FILE_READ_ATTRIBUTES,
2721                 .create_options = cifs_create_options(cifs_sb,
2722                                                       OPEN_REPARSE_POINT),
2723                 .disposition = FILE_OPEN,
2724                 .path = full_path,
2725                 .fid = &fid,
2726         };
2727
2728         rc = CIFS_open(xid, &oparms, &oplock, NULL);
2729         if (rc)
2730                 return rc;
2731
2732         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
2733                       (void **)&io_req, (void **)&io_rsp);
2734         if (rc)
2735                 goto error;
2736
2737         io_req->TotalParameterCount = 0;
2738         io_req->TotalDataCount = 0;
2739         io_req->MaxParameterCount = cpu_to_le32(2);
2740         /* BB find exact data count max from sess structure BB */
2741         io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2742         io_req->MaxSetupCount = 4;
2743         io_req->Reserved = 0;
2744         io_req->ParameterOffset = 0;
2745         io_req->DataCount = 0;
2746         io_req->DataOffset = 0;
2747         io_req->SetupCount = 4;
2748         io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2749         io_req->ParameterCount = io_req->TotalParameterCount;
2750         io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2751         io_req->IsFsctl = 1;
2752         io_req->IsRootFlag = 0;
2753         io_req->Fid = fid.netfid;
2754         io_req->ByteCount = 0;
2755
2756         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req,
2757                          (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
2758         if (rc)
2759                 goto error;
2760
2761         data_offset = le32_to_cpu(io_rsp->DataOffset);
2762         data_count = le32_to_cpu(io_rsp->DataCount);
2763         if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
2764             !data_count || data_count > 2048) {
2765                 rc = -EIO;
2766                 goto error;
2767         }
2768
2769         end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
2770         start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
2771         if (start >= end) {
2772                 rc = -EIO;
2773                 goto error;
2774         }
2775
2776         *tag = le32_to_cpu(((struct reparse_data_buffer *)start)->ReparseTag);
2777         rsp->iov_base = io_rsp;
2778         rsp->iov_len = io_rsp_len;
2779         *rsp_buftype = CIFS_LARGE_BUFFER;
2780         CIFSSMBClose(xid, tcon, fid.netfid);
2781         return 0;
2782
2783 error:
2784         cifs_buf_release(io_req);
2785         CIFSSMBClose(xid, tcon, fid.netfid);
2786         return rc;
2787 }
2788
2789 int
2790 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2791                     __u16 fid)
2792 {
2793         int rc = 0;
2794         int bytes_returned;
2795         struct smb_com_transaction_compr_ioctl_req *pSMB;
2796         struct smb_com_transaction_ioctl_rsp *pSMBr;
2797
2798         cifs_dbg(FYI, "Set compression for %u\n", fid);
2799         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2800                       (void **) &pSMBr);
2801         if (rc)
2802                 return rc;
2803
2804         pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2805
2806         pSMB->TotalParameterCount = 0;
2807         pSMB->TotalDataCount = cpu_to_le32(2);
2808         pSMB->MaxParameterCount = 0;
2809         pSMB->MaxDataCount = 0;
2810         pSMB->MaxSetupCount = 4;
2811         pSMB->Reserved = 0;
2812         pSMB->ParameterOffset = 0;
2813         pSMB->DataCount = cpu_to_le32(2);
2814         pSMB->DataOffset =
2815                 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2816                                 compression_state) - 4);  /* 84 */
2817         pSMB->SetupCount = 4;
2818         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2819         pSMB->ParameterCount = 0;
2820         pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2821         pSMB->IsFsctl = 1; /* FSCTL */
2822         pSMB->IsRootFlag = 0;
2823         pSMB->Fid = fid; /* file handle always le */
2824         /* 3 byte pad, followed by 2 byte compress state */
2825         pSMB->ByteCount = cpu_to_le16(5);
2826         inc_rfc1001_len(pSMB, 5);
2827
2828         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2829                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2830         if (rc)
2831                 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2832
2833         cifs_buf_release(pSMB);
2834
2835         /*
2836          * Note: On -EAGAIN error only caller can retry on handle based calls
2837          * since file handle passed in no longer valid.
2838          */
2839         return rc;
2840 }
2841
2842
2843 #ifdef CONFIG_CIFS_POSIX
2844
2845 #ifdef CONFIG_FS_POSIX_ACL
2846 /**
2847  * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
2848  * @ace: POSIX ACL entry to store converted ACL into
2849  * @cifs_ace: ACL in cifs format
2850  *
2851  * Convert an Access Control Entry from wire format to local POSIX xattr
2852  * format.
2853  *
2854  * Note that the @cifs_uid member is used to store both {g,u}id_t.
2855  */
2856 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
2857                                 struct cifs_posix_ace *cifs_ace)
2858 {
2859         /* u8 cifs fields do not need le conversion */
2860         ace->e_perm = cifs_ace->cifs_e_perm;
2861         ace->e_tag = cifs_ace->cifs_e_tag;
2862
2863         switch (ace->e_tag) {
2864         case ACL_USER:
2865                 ace->e_uid = make_kuid(&init_user_ns,
2866                                        le64_to_cpu(cifs_ace->cifs_uid));
2867                 break;
2868         case ACL_GROUP:
2869                 ace->e_gid = make_kgid(&init_user_ns,
2870                                        le64_to_cpu(cifs_ace->cifs_uid));
2871                 break;
2872         }
2873         return;
2874 }
2875
2876 /**
2877  * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
2878  * @acl: ACLs returned in POSIX ACL format
2879  * @src: ACLs in cifs format
2880  * @acl_type: type of POSIX ACL requested
2881  * @size_of_data_area: size of SMB we got
2882  *
2883  * This function converts ACLs from cifs format to POSIX ACL format.
2884  * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
2885  * their uapi format is returned.
2886  */
2887 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
2888                              const int acl_type, const int size_of_data_area)
2889 {
2890         int size =  0;
2891         __u16 count;
2892         struct cifs_posix_ace *pACE;
2893         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2894         struct posix_acl *kacl = NULL;
2895         struct posix_acl_entry *pa, *pe;
2896
2897         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2898                 return -EOPNOTSUPP;
2899
2900         if (acl_type == ACL_TYPE_ACCESS) {
2901                 count = le16_to_cpu(cifs_acl->access_entry_count);
2902                 pACE = &cifs_acl->ace_array[0];
2903                 size = sizeof(struct cifs_posix_acl);
2904                 size += sizeof(struct cifs_posix_ace) * count;
2905                 /* check if we would go beyond end of SMB */
2906                 if (size_of_data_area < size) {
2907                         cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2908                                  size_of_data_area, size);
2909                         return -EINVAL;
2910                 }
2911         } else if (acl_type == ACL_TYPE_DEFAULT) {
2912                 count = le16_to_cpu(cifs_acl->access_entry_count);
2913                 size = sizeof(struct cifs_posix_acl);
2914                 size += sizeof(struct cifs_posix_ace) * count;
2915                 /* skip past access ACEs to get to default ACEs */
2916                 pACE = &cifs_acl->ace_array[count];
2917                 count = le16_to_cpu(cifs_acl->default_entry_count);
2918                 size += sizeof(struct cifs_posix_ace) * count;
2919                 /* check if we would go beyond end of SMB */
2920                 if (size_of_data_area < size)
2921                         return -EINVAL;
2922         } else {
2923                 /* illegal type */
2924                 return -EINVAL;
2925         }
2926
2927         /* Allocate number of POSIX ACLs to store in VFS format. */
2928         kacl = posix_acl_alloc(count, GFP_NOFS);
2929         if (!kacl)
2930                 return -ENOMEM;
2931
2932         FOREACH_ACL_ENTRY(pa, kacl, pe) {
2933                 cifs_init_posix_acl(pa, pACE);
2934                 pACE++;
2935         }
2936
2937         *acl = kacl;
2938         return 0;
2939 }
2940
2941 /**
2942  * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
2943  * @cifs_ace: the cifs ACL entry to store into
2944  * @local_ace: the POSIX ACL entry to convert
2945  */
2946 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
2947                           const struct posix_acl_entry *local_ace)
2948 {
2949         cifs_ace->cifs_e_perm = local_ace->e_perm;
2950         cifs_ace->cifs_e_tag =  local_ace->e_tag;
2951
2952         switch (local_ace->e_tag) {
2953         case ACL_USER:
2954                 cifs_ace->cifs_uid =
2955                         cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
2956                 break;
2957         case ACL_GROUP:
2958                 cifs_ace->cifs_uid =
2959                         cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
2960                 break;
2961         default:
2962                 cifs_ace->cifs_uid = cpu_to_le64(-1);
2963         }
2964 }
2965
2966 /**
2967  * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
2968  * @parm_data: ACLs in cifs format to conver to
2969  * @acl: ACLs in POSIX ACL format to convert from
2970  * @acl_type: the type of POSIX ACLs stored in @acl
2971  *
2972  * Return: the number cifs ACL entries after conversion
2973  */
2974 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
2975                                const int acl_type)
2976 {
2977         __u16 rc = 0;
2978         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2979         const struct posix_acl_entry *pa, *pe;
2980         int count;
2981         int i = 0;
2982
2983         if ((acl == NULL) || (cifs_acl == NULL))
2984                 return 0;
2985
2986         count = acl->a_count;
2987         cifs_dbg(FYI, "setting acl with %d entries\n", count);
2988
2989         /*
2990          * Note that the uapi POSIX ACL version is verified by the VFS and is
2991          * independent of the cifs ACL version. Changing the POSIX ACL version
2992          * is a uapi change and if it's changed we will pass down the POSIX ACL
2993          * version in struct posix_acl from the VFS. For now there's really
2994          * only one that all filesystems know how to deal with.
2995          */
2996         cifs_acl->version = cpu_to_le16(1);
2997         if (acl_type == ACL_TYPE_ACCESS) {
2998                 cifs_acl->access_entry_count = cpu_to_le16(count);
2999                 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3000         } else if (acl_type == ACL_TYPE_DEFAULT) {
3001                 cifs_acl->default_entry_count = cpu_to_le16(count);
3002                 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3003         } else {
3004                 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3005                 return 0;
3006         }
3007         FOREACH_ACL_ENTRY(pa, acl, pe) {
3008                 cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3009         }
3010         if (rc == 0) {
3011                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3012                 rc += sizeof(struct cifs_posix_acl);
3013                 /* BB add check to make sure ACL does not overflow SMB */
3014         }
3015         return rc;
3016 }
3017
3018 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3019                     const unsigned char *searchName, struct posix_acl **acl,
3020                     const int acl_type, const struct nls_table *nls_codepage,
3021                     int remap)
3022 {
3023 /* SMB_QUERY_POSIX_ACL */
3024         TRANSACTION2_QPI_REQ *pSMB = NULL;
3025         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3026         int rc = 0;
3027         int bytes_returned;
3028         int name_len;
3029         __u16 params, byte_count;
3030
3031         cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3032
3033 queryAclRetry:
3034         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3035                 (void **) &pSMBr);
3036         if (rc)
3037                 return rc;
3038
3039         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3040                 name_len =
3041                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3042                                            searchName, PATH_MAX, nls_codepage,
3043                                            remap);
3044                 name_len++;     /* trailing null */
3045                 name_len *= 2;
3046                 pSMB->FileName[name_len] = 0;
3047                 pSMB->FileName[name_len+1] = 0;
3048         } else {
3049                 name_len = copy_path_name(pSMB->FileName, searchName);
3050         }
3051
3052         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3053         pSMB->TotalDataCount = 0;
3054         pSMB->MaxParameterCount = cpu_to_le16(2);
3055         /* BB find exact max data count below from sess structure BB */
3056         pSMB->MaxDataCount = cpu_to_le16(4000);
3057         pSMB->MaxSetupCount = 0;
3058         pSMB->Reserved = 0;
3059         pSMB->Flags = 0;
3060         pSMB->Timeout = 0;
3061         pSMB->Reserved2 = 0;
3062         pSMB->ParameterOffset = cpu_to_le16(
3063                 offsetof(struct smb_com_transaction2_qpi_req,
3064                          InformationLevel) - 4);
3065         pSMB->DataCount = 0;
3066         pSMB->DataOffset = 0;
3067         pSMB->SetupCount = 1;
3068         pSMB->Reserved3 = 0;
3069         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3070         byte_count = params + 1 /* pad */ ;
3071         pSMB->TotalParameterCount = cpu_to_le16(params);
3072         pSMB->ParameterCount = pSMB->TotalParameterCount;
3073         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3074         pSMB->Reserved4 = 0;
3075         inc_rfc1001_len(pSMB, byte_count);
3076         pSMB->ByteCount = cpu_to_le16(byte_count);
3077
3078         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3079                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3080         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3081         if (rc) {
3082                 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3083         } else {
3084                 /* decode response */
3085
3086                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3087                 /* BB also check enough total bytes returned */
3088                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3089                         rc = -EIO;      /* bad smb */
3090                 else {
3091                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3092                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3093                         rc = cifs_to_posix_acl(acl,
3094                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3095                                 acl_type, count);
3096                 }
3097         }
3098         cifs_buf_release(pSMB);
3099         /*
3100          * The else branch after SendReceive() doesn't return EAGAIN so if we
3101          * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3102          * here and don't leak POSIX ACLs.
3103          */
3104         if (rc == -EAGAIN)
3105                 goto queryAclRetry;
3106         return rc;
3107 }
3108
3109 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3110                     const unsigned char *fileName, const struct posix_acl *acl,
3111                     const int acl_type, const struct nls_table *nls_codepage,
3112                     int remap)
3113 {
3114         struct smb_com_transaction2_spi_req *pSMB = NULL;
3115         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3116         char *parm_data;
3117         int name_len;
3118         int rc = 0;
3119         int bytes_returned = 0;
3120         __u16 params, byte_count, data_count, param_offset, offset;
3121
3122         cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3123 setAclRetry:
3124         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3125                       (void **) &pSMBr);
3126         if (rc)
3127                 return rc;
3128         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3129                 name_len =
3130                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3131                                            PATH_MAX, nls_codepage, remap);
3132                 name_len++;     /* trailing null */
3133                 name_len *= 2;
3134         } else {
3135                 name_len = copy_path_name(pSMB->FileName, fileName);
3136         }
3137         params = 6 + name_len;
3138         pSMB->MaxParameterCount = cpu_to_le16(2);
3139         /* BB find max SMB size from sess */
3140         pSMB->MaxDataCount = cpu_to_le16(1000);
3141         pSMB->MaxSetupCount = 0;
3142         pSMB->Reserved = 0;
3143         pSMB->Flags = 0;
3144         pSMB->Timeout = 0;
3145         pSMB->Reserved2 = 0;
3146         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3147                                 InformationLevel) - 4;
3148         offset = param_offset + params;
3149         parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset;
3150         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3151
3152         /* convert to on the wire format for POSIX ACL */
3153         data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3154
3155         if (data_count == 0) {
3156                 rc = -EOPNOTSUPP;
3157                 goto setACLerrorExit;
3158         }
3159         pSMB->DataOffset = cpu_to_le16(offset);
3160         pSMB->SetupCount = 1;
3161         pSMB->Reserved3 = 0;
3162         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3163         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3164         byte_count = 3 /* pad */  + params + data_count;
3165         pSMB->DataCount = cpu_to_le16(data_count);
3166         pSMB->TotalDataCount = pSMB->DataCount;
3167         pSMB->ParameterCount = cpu_to_le16(params);
3168         pSMB->TotalParameterCount = pSMB->ParameterCount;
3169         pSMB->Reserved4 = 0;
3170         inc_rfc1001_len(pSMB, byte_count);
3171         pSMB->ByteCount = cpu_to_le16(byte_count);
3172         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3173                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3174         if (rc)
3175                 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3176
3177 setACLerrorExit:
3178         cifs_buf_release(pSMB);
3179         if (rc == -EAGAIN)
3180                 goto setAclRetry;
3181         return rc;
3182 }
3183 #else
3184 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3185                     const unsigned char *searchName, struct posix_acl **acl,
3186                     const int acl_type, const struct nls_table *nls_codepage,
3187                     int remap)
3188 {
3189         return -EOPNOTSUPP;
3190 }
3191
3192 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3193                     const unsigned char *fileName, const struct posix_acl *acl,
3194                     const int acl_type, const struct nls_table *nls_codepage,
3195                     int remap)
3196 {
3197         return -EOPNOTSUPP;
3198 }
3199 #endif /* CONFIG_FS_POSIX_ACL */
3200
3201 int
3202 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3203                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3204 {
3205         int rc = 0;
3206         struct smb_t2_qfi_req *pSMB = NULL;
3207         struct smb_t2_qfi_rsp *pSMBr = NULL;
3208         int bytes_returned;
3209         __u16 params, byte_count;
3210
3211         cifs_dbg(FYI, "In GetExtAttr\n");
3212         if (tcon == NULL)
3213                 return -ENODEV;
3214
3215 GetExtAttrRetry:
3216         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3217                       (void **) &pSMBr);
3218         if (rc)
3219                 return rc;
3220
3221         params = 2 /* level */ + 2 /* fid */;
3222         pSMB->t2.TotalDataCount = 0;
3223         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3224         /* BB find exact max data count below from sess structure BB */
3225         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3226         pSMB->t2.MaxSetupCount = 0;
3227         pSMB->t2.Reserved = 0;
3228         pSMB->t2.Flags = 0;
3229         pSMB->t2.Timeout = 0;
3230         pSMB->t2.Reserved2 = 0;
3231         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3232                                                Fid) - 4);
3233         pSMB->t2.DataCount = 0;
3234         pSMB->t2.DataOffset = 0;
3235         pSMB->t2.SetupCount = 1;
3236         pSMB->t2.Reserved3 = 0;
3237         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3238         byte_count = params + 1 /* pad */ ;
3239         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3240         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3241         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3242         pSMB->Pad = 0;
3243         pSMB->Fid = netfid;
3244         inc_rfc1001_len(pSMB, byte_count);
3245         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3246
3247         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3248                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3249         if (rc) {
3250                 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3251         } else {
3252                 /* decode response */
3253                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3254                 /* BB also check enough total bytes returned */
3255                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3256                         /* If rc should we check for EOPNOSUPP and
3257                            disable the srvino flag? or in caller? */
3258                         rc = -EIO;      /* bad smb */
3259                 else {
3260                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3261                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3262                         struct file_chattr_info *pfinfo;
3263
3264                         if (count != 16) {
3265                                 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3266                                 rc = -EIO;
3267                                 goto GetExtAttrOut;
3268                         }
3269                         pfinfo = (struct file_chattr_info *)
3270                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3271                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3272                         *pMask = le64_to_cpu(pfinfo->mask);
3273                 }
3274         }
3275 GetExtAttrOut:
3276         cifs_buf_release(pSMB);
3277         if (rc == -EAGAIN)
3278                 goto GetExtAttrRetry;
3279         return rc;
3280 }
3281
3282 #endif /* CONFIG_POSIX */
3283
3284 /*
3285  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3286  * all NT TRANSACTS that we init here have total parm and data under about 400
3287  * bytes (to fit in small cifs buffer size), which is the case so far, it
3288  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3289  * returned setup area) and MaxParameterCount (returned parms size) must be set
3290  * by caller
3291  */
3292 static int
3293 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3294                    const int parm_len, struct cifs_tcon *tcon,
3295                    void **ret_buf)
3296 {
3297         int rc;
3298         __u32 temp_offset;
3299         struct smb_com_ntransact_req *pSMB;
3300
3301         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3302                                 (void **)&pSMB);
3303         if (rc)
3304                 return rc;
3305         *ret_buf = (void *)pSMB;
3306         pSMB->Reserved = 0;
3307         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3308         pSMB->TotalDataCount  = 0;
3309         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3310         pSMB->ParameterCount = pSMB->TotalParameterCount;
3311         pSMB->DataCount  = pSMB->TotalDataCount;
3312         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3313                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3314         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3315         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3316         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3317         pSMB->SubCommand = cpu_to_le16(sub_command);
3318         return 0;
3319 }
3320
3321 static int
3322 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3323                    __u32 *pparmlen, __u32 *pdatalen)
3324 {
3325         char *end_of_smb;
3326         __u32 data_count, data_offset, parm_count, parm_offset;
3327         struct smb_com_ntransact_rsp *pSMBr;
3328         u16 bcc;
3329
3330         *pdatalen = 0;
3331         *pparmlen = 0;
3332
3333         if (buf == NULL)
3334                 return -EINVAL;
3335
3336         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3337
3338         bcc = get_bcc(&pSMBr->hdr);
3339         end_of_smb = 2 /* sizeof byte count */ + bcc +
3340                         (char *)&pSMBr->ByteCount;
3341
3342         data_offset = le32_to_cpu(pSMBr->DataOffset);
3343         data_count = le32_to_cpu(pSMBr->DataCount);
3344         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3345         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3346
3347         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3348         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3349
3350         /* should we also check that parm and data areas do not overlap? */
3351         if (*ppparm > end_of_smb) {
3352                 cifs_dbg(FYI, "parms start after end of smb\n");
3353                 return -EINVAL;
3354         } else if (parm_count + *ppparm > end_of_smb) {
3355                 cifs_dbg(FYI, "parm end after end of smb\n");
3356                 return -EINVAL;
3357         } else if (*ppdata > end_of_smb) {
3358                 cifs_dbg(FYI, "data starts after end of smb\n");
3359                 return -EINVAL;
3360         } else if (data_count + *ppdata > end_of_smb) {
3361                 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3362                          *ppdata, data_count, (data_count + *ppdata),
3363                          end_of_smb, pSMBr);
3364                 return -EINVAL;
3365         } else if (parm_count + data_count > bcc) {
3366                 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3367                 return -EINVAL;
3368         }
3369         *pdatalen = data_count;
3370         *pparmlen = parm_count;
3371         return 0;
3372 }
3373
3374 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3375 int
3376 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3377                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3378 {
3379         int rc = 0;
3380         int buf_type = 0;
3381         QUERY_SEC_DESC_REQ *pSMB;
3382         struct kvec iov[1];
3383         struct kvec rsp_iov;
3384
3385         cifs_dbg(FYI, "GetCifsACL\n");
3386
3387         *pbuflen = 0;
3388         *acl_inf = NULL;
3389
3390         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3391                         8 /* parm len */, tcon, (void **) &pSMB);
3392         if (rc)
3393                 return rc;
3394
3395         pSMB->MaxParameterCount = cpu_to_le32(4);
3396         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3397         pSMB->MaxSetupCount = 0;
3398         pSMB->Fid = fid; /* file handle always le */
3399         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3400                                      CIFS_ACL_DACL);
3401         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3402         inc_rfc1001_len(pSMB, 11);
3403         iov[0].iov_base = (char *)pSMB;
3404         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3405
3406         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3407                           0, &rsp_iov);
3408         cifs_small_buf_release(pSMB);
3409         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3410         if (rc) {
3411                 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3412         } else {                /* decode response */
3413                 __le32 *parm;
3414                 __u32 parm_len;
3415                 __u32 acl_len;
3416                 struct smb_com_ntransact_rsp *pSMBr;
3417                 char *pdata;
3418
3419 /* validate_nttransact */
3420                 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3421                                         &pdata, &parm_len, pbuflen);
3422                 if (rc)
3423                         goto qsec_out;
3424                 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3425
3426                 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3427                          pSMBr, parm, *acl_inf);
3428
3429                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3430                         rc = -EIO;      /* bad smb */
3431                         *pbuflen = 0;
3432                         goto qsec_out;
3433                 }
3434
3435 /* BB check that data area is minimum length and as big as acl_len */
3436
3437                 acl_len = le32_to_cpu(*parm);
3438                 if (acl_len != *pbuflen) {
3439                         cifs_dbg(VFS, "acl length %d does not match %d\n",
3440                                  acl_len, *pbuflen);
3441                         if (*pbuflen > acl_len)
3442                                 *pbuflen = acl_len;
3443                 }
3444
3445                 /* check if buffer is big enough for the acl
3446                    header followed by the smallest SID */
3447                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3448                     (*pbuflen >= 64 * 1024)) {
3449                         cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3450                         rc = -EINVAL;
3451                         *pbuflen = 0;
3452                 } else {
3453                         *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3454                         if (*acl_inf == NULL) {
3455                                 *pbuflen = 0;
3456                                 rc = -ENOMEM;
3457                         }
3458                 }
3459         }
3460 qsec_out:
3461         free_rsp_buf(buf_type, rsp_iov.iov_base);
3462         return rc;
3463 }
3464
3465 int
3466 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3467                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3468 {
3469         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3470         int rc = 0;
3471         int bytes_returned = 0;
3472         SET_SEC_DESC_REQ *pSMB = NULL;
3473         void *pSMBr;
3474
3475 setCifsAclRetry:
3476         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3477         if (rc)
3478                 return rc;
3479
3480         pSMB->MaxSetupCount = 0;
3481         pSMB->Reserved = 0;
3482
3483         param_count = 8;
3484         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3485         data_count = acllen;
3486         data_offset = param_offset + param_count;
3487         byte_count = 3 /* pad */  + param_count;
3488
3489         pSMB->DataCount = cpu_to_le32(data_count);
3490         pSMB->TotalDataCount = pSMB->DataCount;
3491         pSMB->MaxParameterCount = cpu_to_le32(4);
3492         pSMB->MaxDataCount = cpu_to_le32(16384);
3493         pSMB->ParameterCount = cpu_to_le32(param_count);
3494         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3495         pSMB->TotalParameterCount = pSMB->ParameterCount;
3496         pSMB->DataOffset = cpu_to_le32(data_offset);
3497         pSMB->SetupCount = 0;
3498         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3499         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3500
3501         pSMB->Fid = fid; /* file handle always le */
3502         pSMB->Reserved2 = 0;
3503         pSMB->AclFlags = cpu_to_le32(aclflag);
3504
3505         if (pntsd && acllen) {
3506                 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3507                                 data_offset, pntsd, acllen);
3508                 inc_rfc1001_len(pSMB, byte_count + data_count);
3509         } else
3510                 inc_rfc1001_len(pSMB, byte_count);
3511
3512         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3513                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3514
3515         cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3516                  bytes_returned, rc);
3517         if (rc)
3518                 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3519         cifs_buf_release(pSMB);
3520
3521         if (rc == -EAGAIN)
3522                 goto setCifsAclRetry;
3523
3524         return (rc);
3525 }
3526
3527
3528 /* Legacy Query Path Information call for lookup to old servers such
3529    as Win9x/WinME */
3530 int
3531 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3532                     const char *search_name, FILE_ALL_INFO *data,
3533                     const struct nls_table *nls_codepage, int remap)
3534 {
3535         QUERY_INFORMATION_REQ *pSMB;
3536         QUERY_INFORMATION_RSP *pSMBr;
3537         int rc = 0;
3538         int bytes_returned;
3539         int name_len;
3540
3541         cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3542 QInfRetry:
3543         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3544                       (void **) &pSMBr);
3545         if (rc)
3546                 return rc;
3547
3548         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3549                 name_len =
3550                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3551                                            search_name, PATH_MAX, nls_codepage,
3552                                            remap);
3553                 name_len++;     /* trailing null */
3554                 name_len *= 2;
3555         } else {
3556                 name_len = copy_path_name(pSMB->FileName, search_name);
3557         }
3558         pSMB->BufferFormat = 0x04;
3559         name_len++; /* account for buffer type byte */
3560         inc_rfc1001_len(pSMB, (__u16)name_len);
3561         pSMB->ByteCount = cpu_to_le16(name_len);
3562
3563         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3564                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3565         if (rc) {
3566                 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3567         } else if (data) {
3568                 struct timespec64 ts;
3569                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3570
3571                 /* decode response */
3572                 /* BB FIXME - add time zone adjustment BB */
3573                 memset(data, 0, sizeof(FILE_ALL_INFO));
3574                 ts.tv_nsec = 0;
3575                 ts.tv_sec = time;
3576                 /* decode time fields */
3577                 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3578                 data->LastWriteTime = data->ChangeTime;
3579                 data->LastAccessTime = 0;
3580                 data->AllocationSize =
3581                         cpu_to_le64(le32_to_cpu(pSMBr->size));
3582                 data->EndOfFile = data->AllocationSize;
3583                 data->Attributes =
3584                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
3585         } else
3586                 rc = -EIO; /* bad buffer passed in */
3587
3588         cifs_buf_release(pSMB);
3589
3590         if (rc == -EAGAIN)
3591                 goto QInfRetry;
3592
3593         return rc;
3594 }
3595
3596 int
3597 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3598                  u16 netfid, FILE_ALL_INFO *pFindData)
3599 {
3600         struct smb_t2_qfi_req *pSMB = NULL;
3601         struct smb_t2_qfi_rsp *pSMBr = NULL;
3602         int rc = 0;
3603         int bytes_returned;
3604         __u16 params, byte_count;
3605
3606 QFileInfoRetry:
3607         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3608                       (void **) &pSMBr);
3609         if (rc)
3610                 return rc;
3611
3612         params = 2 /* level */ + 2 /* fid */;
3613         pSMB->t2.TotalDataCount = 0;
3614         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3615         /* BB find exact max data count below from sess structure BB */
3616         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3617         pSMB->t2.MaxSetupCount = 0;
3618         pSMB->t2.Reserved = 0;
3619         pSMB->t2.Flags = 0;
3620         pSMB->t2.Timeout = 0;
3621         pSMB->t2.Reserved2 = 0;
3622         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3623                                                Fid) - 4);
3624         pSMB->t2.DataCount = 0;
3625         pSMB->t2.DataOffset = 0;
3626         pSMB->t2.SetupCount = 1;
3627         pSMB->t2.Reserved3 = 0;
3628         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3629         byte_count = params + 1 /* pad */ ;
3630         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3631         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3632         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3633         pSMB->Pad = 0;
3634         pSMB->Fid = netfid;
3635         inc_rfc1001_len(pSMB, byte_count);
3636         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3637
3638         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3639                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3640         if (rc) {
3641                 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3642         } else {                /* decode response */
3643                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3644
3645                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3646                         rc = -EIO;
3647                 else if (get_bcc(&pSMBr->hdr) < 40)
3648                         rc = -EIO;      /* bad smb */
3649                 else if (pFindData) {
3650                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3651                         memcpy((char *) pFindData,
3652                                (char *) &pSMBr->hdr.Protocol +
3653                                data_offset, sizeof(FILE_ALL_INFO));
3654                 } else
3655                     rc = -ENOMEM;
3656         }
3657         cifs_buf_release(pSMB);
3658         if (rc == -EAGAIN)
3659                 goto QFileInfoRetry;
3660
3661         return rc;
3662 }
3663
3664 int
3665 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3666                  const char *search_name, FILE_ALL_INFO *data,
3667                  int legacy /* old style infolevel */,
3668                  const struct nls_table *nls_codepage, int remap)
3669 {
3670         /* level 263 SMB_QUERY_FILE_ALL_INFO */
3671         TRANSACTION2_QPI_REQ *pSMB = NULL;
3672         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3673         int rc = 0;
3674         int bytes_returned;
3675         int name_len;
3676         __u16 params, byte_count;
3677
3678         /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3679 QPathInfoRetry:
3680         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3681                       (void **) &pSMBr);
3682         if (rc)
3683                 return rc;
3684
3685         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3686                 name_len =
3687                     cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3688                                        PATH_MAX, nls_codepage, remap);
3689                 name_len++;     /* trailing null */
3690                 name_len *= 2;
3691         } else {
3692                 name_len = copy_path_name(pSMB->FileName, search_name);
3693         }
3694
3695         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3696         pSMB->TotalDataCount = 0;
3697         pSMB->MaxParameterCount = cpu_to_le16(2);
3698         /* BB find exact max SMB PDU from sess structure BB */
3699         pSMB->MaxDataCount = cpu_to_le16(4000);
3700         pSMB->MaxSetupCount = 0;
3701         pSMB->Reserved = 0;
3702         pSMB->Flags = 0;
3703         pSMB->Timeout = 0;
3704         pSMB->Reserved2 = 0;
3705         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3706         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3707         pSMB->DataCount = 0;
3708         pSMB->DataOffset = 0;
3709         pSMB->SetupCount = 1;
3710         pSMB->Reserved3 = 0;
3711         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3712         byte_count = params + 1 /* pad */ ;
3713         pSMB->TotalParameterCount = cpu_to_le16(params);
3714         pSMB->ParameterCount = pSMB->TotalParameterCount;
3715         if (legacy)
3716                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3717         else
3718                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3719         pSMB->Reserved4 = 0;
3720         inc_rfc1001_len(pSMB, byte_count);
3721         pSMB->ByteCount = cpu_to_le16(byte_count);
3722
3723         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3724                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3725         if (rc) {
3726                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3727         } else {                /* decode response */
3728                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3729
3730                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3731                         rc = -EIO;
3732                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3733                         rc = -EIO;      /* bad smb */
3734                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3735                         rc = -EIO;  /* 24 or 26 expected but we do not read
3736                                         last field */
3737                 else if (data) {
3738                         int size;
3739                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3740
3741                         /*
3742                          * On legacy responses we do not read the last field,
3743                          * EAsize, fortunately since it varies by subdialect and
3744                          * also note it differs on Set vs Get, ie two bytes or 4
3745                          * bytes depending but we don't care here.
3746                          */
3747                         if (legacy)
3748                                 size = sizeof(FILE_INFO_STANDARD);
3749                         else
3750                                 size = sizeof(FILE_ALL_INFO);
3751                         memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3752                                data_offset, size);
3753                 } else
3754                     rc = -ENOMEM;
3755         }
3756         cifs_buf_release(pSMB);
3757         if (rc == -EAGAIN)
3758                 goto QPathInfoRetry;
3759
3760         return rc;
3761 }
3762
3763 int
3764 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3765                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3766 {
3767         struct smb_t2_qfi_req *pSMB = NULL;
3768         struct smb_t2_qfi_rsp *pSMBr = NULL;
3769         int rc = 0;
3770         int bytes_returned;
3771         __u16 params, byte_count;
3772
3773 UnixQFileInfoRetry:
3774         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3775                       (void **) &pSMBr);
3776         if (rc)
3777                 return rc;
3778
3779         params = 2 /* level */ + 2 /* fid */;
3780         pSMB->t2.TotalDataCount = 0;
3781         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3782         /* BB find exact max data count below from sess structure BB */
3783         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3784         pSMB->t2.MaxSetupCount = 0;
3785         pSMB->t2.Reserved = 0;
3786         pSMB->t2.Flags = 0;
3787         pSMB->t2.Timeout = 0;
3788         pSMB->t2.Reserved2 = 0;
3789         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3790                                                Fid) - 4);
3791         pSMB->t2.DataCount = 0;
3792         pSMB->t2.DataOffset = 0;
3793         pSMB->t2.SetupCount = 1;
3794         pSMB->t2.Reserved3 = 0;
3795         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3796         byte_count = params + 1 /* pad */ ;
3797         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3798         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3799         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3800         pSMB->Pad = 0;
3801         pSMB->Fid = netfid;
3802         inc_rfc1001_len(pSMB, byte_count);
3803         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3804
3805         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3806                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3807         if (rc) {
3808                 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3809         } else {                /* decode response */
3810                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3811
3812                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3813                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3814                         rc = -EIO;      /* bad smb */
3815                 } else {
3816                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3817                         memcpy((char *) pFindData,
3818                                (char *) &pSMBr->hdr.Protocol +
3819                                data_offset,
3820                                sizeof(FILE_UNIX_BASIC_INFO));
3821                 }
3822         }
3823
3824         cifs_buf_release(pSMB);
3825         if (rc == -EAGAIN)
3826                 goto UnixQFileInfoRetry;
3827
3828         return rc;
3829 }
3830
3831 int
3832 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3833                      const unsigned char *searchName,
3834                      FILE_UNIX_BASIC_INFO *pFindData,
3835                      const struct nls_table *nls_codepage, int remap)
3836 {
3837 /* SMB_QUERY_FILE_UNIX_BASIC */
3838         TRANSACTION2_QPI_REQ *pSMB = NULL;
3839         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3840         int rc = 0;
3841         int bytes_returned = 0;
3842         int name_len;
3843         __u16 params, byte_count;
3844
3845         cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3846 UnixQPathInfoRetry:
3847         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3848                       (void **) &pSMBr);
3849         if (rc)
3850                 return rc;
3851
3852         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3853                 name_len =
3854                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3855                                        PATH_MAX, nls_codepage, remap);
3856                 name_len++;     /* trailing null */
3857                 name_len *= 2;
3858         } else {
3859                 name_len = copy_path_name(pSMB->FileName, searchName);
3860         }
3861
3862         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3863         pSMB->TotalDataCount = 0;
3864         pSMB->MaxParameterCount = cpu_to_le16(2);
3865         /* BB find exact max SMB PDU from sess structure BB */
3866         pSMB->MaxDataCount = cpu_to_le16(4000);
3867         pSMB->MaxSetupCount = 0;
3868         pSMB->Reserved = 0;
3869         pSMB->Flags = 0;
3870         pSMB->Timeout = 0;
3871         pSMB->Reserved2 = 0;
3872         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3873         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3874         pSMB->DataCount = 0;
3875         pSMB->DataOffset = 0;
3876         pSMB->SetupCount = 1;
3877         pSMB->Reserved3 = 0;
3878         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3879         byte_count = params + 1 /* pad */ ;
3880         pSMB->TotalParameterCount = cpu_to_le16(params);
3881         pSMB->ParameterCount = pSMB->TotalParameterCount;
3882         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3883         pSMB->Reserved4 = 0;
3884         inc_rfc1001_len(pSMB, byte_count);
3885         pSMB->ByteCount = cpu_to_le16(byte_count);
3886
3887         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3888                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3889         if (rc) {
3890                 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3891         } else {                /* decode response */
3892                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3893
3894                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3895                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3896                         rc = -EIO;      /* bad smb */
3897                 } else {
3898                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3899                         memcpy((char *) pFindData,
3900                                (char *) &pSMBr->hdr.Protocol +
3901                                data_offset,
3902                                sizeof(FILE_UNIX_BASIC_INFO));
3903                 }
3904         }
3905         cifs_buf_release(pSMB);
3906         if (rc == -EAGAIN)
3907                 goto UnixQPathInfoRetry;
3908
3909         return rc;
3910 }
3911
3912 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3913 int
3914 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3915               const char *searchName, struct cifs_sb_info *cifs_sb,
3916               __u16 *pnetfid, __u16 search_flags,
3917               struct cifs_search_info *psrch_inf, bool msearch)
3918 {
3919 /* level 257 SMB_ */
3920         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3921         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3922         T2_FFIRST_RSP_PARMS *parms;
3923         struct nls_table *nls_codepage;
3924         unsigned int lnoff;
3925         __u16 params, byte_count;
3926         int bytes_returned = 0;
3927         int name_len, remap;
3928         int rc = 0;
3929
3930         cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3931
3932 findFirstRetry:
3933         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3934                       (void **) &pSMBr);
3935         if (rc)
3936                 return rc;
3937
3938         nls_codepage = cifs_sb->local_nls;
3939         remap = cifs_remap(cifs_sb);
3940
3941         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3942                 name_len =
3943                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3944                                        PATH_MAX, nls_codepage, remap);
3945                 /* We can not add the asterik earlier in case
3946                 it got remapped to 0xF03A as if it were part of the
3947                 directory name instead of a wildcard */
3948                 name_len *= 2;
3949                 if (msearch) {
3950                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3951                         pSMB->FileName[name_len+1] = 0;
3952                         pSMB->FileName[name_len+2] = '*';
3953                         pSMB->FileName[name_len+3] = 0;
3954                         name_len += 4; /* now the trailing null */
3955                         /* null terminate just in case */
3956                         pSMB->FileName[name_len] = 0;
3957                         pSMB->FileName[name_len+1] = 0;
3958                         name_len += 2;
3959                 }
3960         } else {
3961                 name_len = copy_path_name(pSMB->FileName, searchName);
3962                 if (msearch) {
3963                         if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3964                                 name_len = PATH_MAX-2;
3965                         /* overwrite nul byte */
3966                         pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3967                         pSMB->FileName[name_len] = '*';
3968                         pSMB->FileName[name_len+1] = 0;
3969                         name_len += 2;
3970                 }
3971         }
3972
3973         params = 12 + name_len /* includes null */ ;
3974         pSMB->TotalDataCount = 0;       /* no EAs */
3975         pSMB->MaxParameterCount = cpu_to_le16(10);
3976         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
3977         pSMB->MaxSetupCount = 0;
3978         pSMB->Reserved = 0;
3979         pSMB->Flags = 0;
3980         pSMB->Timeout = 0;
3981         pSMB->Reserved2 = 0;
3982         byte_count = params + 1 /* pad */ ;
3983         pSMB->TotalParameterCount = cpu_to_le16(params);
3984         pSMB->ParameterCount = pSMB->TotalParameterCount;
3985         pSMB->ParameterOffset = cpu_to_le16(
3986               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3987                 - 4);
3988         pSMB->DataCount = 0;
3989         pSMB->DataOffset = 0;
3990         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
3991         pSMB->Reserved3 = 0;
3992         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
3993         pSMB->SearchAttributes =
3994             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3995                         ATTR_DIRECTORY);
3996         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
3997         pSMB->SearchFlags = cpu_to_le16(search_flags);
3998         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3999
4000         /* BB what should we set StorageType to? Does it matter? BB */
4001         pSMB->SearchStorageType = 0;
4002         inc_rfc1001_len(pSMB, byte_count);
4003         pSMB->ByteCount = cpu_to_le16(byte_count);
4004
4005         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4006                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4007         cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4008
4009         if (rc) {
4010                 /*
4011                  * BB: add logic to retry regular search if Unix search rejected
4012                  * unexpectedly by server.
4013                  */
4014                 /* BB: add code to handle unsupported level rc */
4015                 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4016                 cifs_buf_release(pSMB);
4017                 /*
4018                  * BB: eventually could optimize out free and realloc of buf for
4019                  * this case.
4020                  */
4021                 if (rc == -EAGAIN)
4022                         goto findFirstRetry;
4023                 return rc;
4024         }
4025         /* decode response */
4026         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4027         if (rc) {
4028                 cifs_buf_release(pSMB);
4029                 return rc;
4030         }
4031
4032         psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4033         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4034         psrch_inf->smallBuf = false;
4035         psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol +
4036                 le16_to_cpu(pSMBr->t2.DataOffset);
4037
4038         parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol +
4039                                         le16_to_cpu(pSMBr->t2.ParameterOffset));
4040         psrch_inf->endOfSearch = !!parms->EndofSearch;
4041
4042         psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4043         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4044                 psrch_inf->entries_in_buffer;
4045         lnoff = le16_to_cpu(parms->LastNameOffset);
4046         if (CIFSMaxBufSize < lnoff) {
4047                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4048                 psrch_inf->last_entry = NULL;
4049         } else {
4050                 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff;
4051                 if (pnetfid)
4052                         *pnetfid = parms->SearchHandle;
4053         }
4054         return 0;
4055 }
4056
4057 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4058                  __u16 searchHandle, __u16 search_flags,
4059                  struct cifs_search_info *psrch_inf)
4060 {
4061         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4062         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4063         T2_FNEXT_RSP_PARMS *parms;
4064         unsigned int name_len;
4065         unsigned int lnoff;
4066         __u16 params, byte_count;
4067         char *response_data;
4068         int bytes_returned;
4069         int rc = 0;
4070
4071         cifs_dbg(FYI, "In FindNext\n");
4072
4073         if (psrch_inf->endOfSearch)
4074                 return -ENOENT;
4075
4076         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4077                 (void **) &pSMBr);
4078         if (rc)
4079                 return rc;
4080
4081         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4082         byte_count = 0;
4083         pSMB->TotalDataCount = 0;       /* no EAs */
4084         pSMB->MaxParameterCount = cpu_to_le16(8);
4085         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4086         pSMB->MaxSetupCount = 0;
4087         pSMB->Reserved = 0;
4088         pSMB->Flags = 0;
4089         pSMB->Timeout = 0;
4090         pSMB->Reserved2 = 0;
4091         pSMB->ParameterOffset =  cpu_to_le16(
4092               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4093         pSMB->DataCount = 0;
4094         pSMB->DataOffset = 0;
4095         pSMB->SetupCount = 1;
4096         pSMB->Reserved3 = 0;
4097         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4098         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4099         pSMB->SearchCount =
4100                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4101         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4102         pSMB->ResumeKey = psrch_inf->resume_key;
4103         pSMB->SearchFlags = cpu_to_le16(search_flags);
4104
4105         name_len = psrch_inf->resume_name_len;
4106         params += name_len;
4107         if (name_len < PATH_MAX) {
4108                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4109                 byte_count += name_len;
4110                 /* 14 byte parm len above enough for 2 byte null terminator */
4111                 pSMB->ResumeFileName[name_len] = 0;
4112                 pSMB->ResumeFileName[name_len+1] = 0;
4113         } else {
4114                 cifs_buf_release(pSMB);
4115                 return -EINVAL;
4116         }
4117         byte_count = params + 1 /* pad */ ;
4118         pSMB->TotalParameterCount = cpu_to_le16(params);
4119         pSMB->ParameterCount = pSMB->TotalParameterCount;
4120         inc_rfc1001_len(pSMB, byte_count);
4121         pSMB->ByteCount = cpu_to_le16(byte_count);
4122
4123         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4124                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4125         cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4126
4127         if (rc) {
4128                 cifs_buf_release(pSMB);
4129                 if (rc == -EBADF) {
4130                         psrch_inf->endOfSearch = true;
4131                         rc = 0; /* search probably was closed at end of search*/
4132                 } else {
4133                         cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4134                 }
4135                 return rc;
4136         }
4137
4138         /* decode response */
4139         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4140         if (rc) {
4141                 cifs_buf_release(pSMB);
4142                 return rc;
4143         }
4144         /* BB fixme add lock for file (srch_info) struct here */
4145         psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4146         response_data = (char *)&pSMBr->hdr.Protocol +
4147                 le16_to_cpu(pSMBr->t2.ParameterOffset);
4148         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4149         response_data = (char *)&pSMBr->hdr.Protocol +
4150                 le16_to_cpu(pSMBr->t2.DataOffset);
4151
4152         if (psrch_inf->smallBuf)
4153                 cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
4154         else
4155                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4156
4157         psrch_inf->srch_entries_start = response_data;
4158         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4159         psrch_inf->smallBuf = false;
4160         psrch_inf->endOfSearch = !!parms->EndofSearch;
4161         psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4162         psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer;
4163         lnoff = le16_to_cpu(parms->LastNameOffset);
4164         if (CIFSMaxBufSize < lnoff) {
4165                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4166                 psrch_inf->last_entry = NULL;
4167         } else {
4168                 psrch_inf->last_entry =
4169                         psrch_inf->srch_entries_start + lnoff;
4170         }
4171         /* BB fixme add unlock here */
4172
4173         /*
4174          * BB: On error, should we leave previous search buf
4175          * (and count and last entry fields) intact or free the previous one?
4176          *
4177          * Note: On -EAGAIN error only caller can retry on handle based calls
4178          * since file handle passed in no longer valid.
4179          */
4180         return 0;
4181 }
4182
4183 int
4184 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4185               const __u16 searchHandle)
4186 {
4187         int rc = 0;
4188         FINDCLOSE_REQ *pSMB = NULL;
4189
4190         cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4191         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4192
4193         /* no sense returning error if session restarted
4194                 as file handle has been closed */
4195         if (rc == -EAGAIN)
4196                 return 0;
4197         if (rc)
4198                 return rc;
4199
4200         pSMB->FileID = searchHandle;
4201         pSMB->ByteCount = 0;
4202         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4203         cifs_small_buf_release(pSMB);
4204         if (rc)
4205                 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4206
4207         cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4208
4209         /* Since session is dead, search handle closed on server already */
4210         if (rc == -EAGAIN)
4211                 rc = 0;
4212
4213         return rc;
4214 }
4215
4216 int
4217 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4218                       const char *search_name, __u64 *inode_number,
4219                       const struct nls_table *nls_codepage, int remap)
4220 {
4221         int rc = 0;
4222         TRANSACTION2_QPI_REQ *pSMB = NULL;
4223         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4224         int name_len, bytes_returned;
4225         __u16 params, byte_count;
4226
4227         cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4228         if (tcon == NULL)
4229                 return -ENODEV;
4230
4231 GetInodeNumberRetry:
4232         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4233                       (void **) &pSMBr);
4234         if (rc)
4235                 return rc;
4236
4237         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4238                 name_len =
4239                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4240                                            search_name, PATH_MAX, nls_codepage,
4241                                            remap);
4242                 name_len++;     /* trailing null */
4243                 name_len *= 2;
4244         } else {
4245                 name_len = copy_path_name(pSMB->FileName, search_name);
4246         }
4247
4248         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4249         pSMB->TotalDataCount = 0;
4250         pSMB->MaxParameterCount = cpu_to_le16(2);
4251         /* BB find exact max data count below from sess structure BB */
4252         pSMB->MaxDataCount = cpu_to_le16(4000);
4253         pSMB->MaxSetupCount = 0;
4254         pSMB->Reserved = 0;
4255         pSMB->Flags = 0;
4256         pSMB->Timeout = 0;
4257         pSMB->Reserved2 = 0;
4258         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4259                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4260         pSMB->DataCount = 0;
4261         pSMB->DataOffset = 0;
4262         pSMB->SetupCount = 1;
4263         pSMB->Reserved3 = 0;
4264         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4265         byte_count = params + 1 /* pad */ ;
4266         pSMB->TotalParameterCount = cpu_to_le16(params);
4267         pSMB->ParameterCount = pSMB->TotalParameterCount;
4268         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4269         pSMB->Reserved4 = 0;
4270         inc_rfc1001_len(pSMB, byte_count);
4271         pSMB->ByteCount = cpu_to_le16(byte_count);
4272
4273         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4274                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4275         if (rc) {
4276                 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4277         } else {
4278                 /* decode response */
4279                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4280                 /* BB also check enough total bytes returned */
4281                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4282                         /* If rc should we check for EOPNOSUPP and
4283                         disable the srvino flag? or in caller? */
4284                         rc = -EIO;      /* bad smb */
4285                 else {
4286                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4287                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4288                         struct file_internal_info *pfinfo;
4289                         /* BB Do we need a cast or hash here ? */
4290                         if (count < 8) {
4291                                 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4292                                 rc = -EIO;
4293                                 goto GetInodeNumOut;
4294                         }
4295                         pfinfo = (struct file_internal_info *)
4296                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4297                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4298                 }
4299         }
4300 GetInodeNumOut:
4301         cifs_buf_release(pSMB);
4302         if (rc == -EAGAIN)
4303                 goto GetInodeNumberRetry;
4304         return rc;
4305 }
4306
4307 int
4308 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4309                 const char *search_name, struct dfs_info3_param **target_nodes,
4310                 unsigned int *num_of_nodes,
4311                 const struct nls_table *nls_codepage, int remap)
4312 {
4313 /* TRANS2_GET_DFS_REFERRAL */
4314         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4315         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4316         int rc = 0;
4317         int bytes_returned;
4318         int name_len;
4319         __u16 params, byte_count;
4320         *num_of_nodes = 0;
4321         *target_nodes = NULL;
4322
4323         cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4324         if (ses == NULL || ses->tcon_ipc == NULL)
4325                 return -ENODEV;
4326
4327 getDFSRetry:
4328         /*
4329          * Use smb_init_no_reconnect() instead of smb_init() as
4330          * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4331          * causing an infinite recursion.
4332          */
4333         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4334                                    (void **)&pSMB, (void **)&pSMBr);
4335         if (rc)
4336                 return rc;
4337
4338         /* server pointer checked in called function,
4339         but should never be null here anyway */
4340         pSMB->hdr.Mid = get_next_mid(ses->server);
4341         pSMB->hdr.Tid = ses->tcon_ipc->tid;
4342         pSMB->hdr.Uid = ses->Suid;
4343         if (ses->capabilities & CAP_STATUS32)
4344                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4345         if (ses->capabilities & CAP_DFS)
4346                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4347
4348         if (ses->capabilities & CAP_UNICODE) {
4349                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4350                 name_len =
4351                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4352                                        search_name, PATH_MAX, nls_codepage,
4353                                        remap);
4354                 name_len++;     /* trailing null */
4355                 name_len *= 2;
4356         } else {        /* BB improve the check for buffer overruns BB */
4357                 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4358         }
4359
4360         if (ses->server->sign)
4361                 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4362
4363         pSMB->hdr.Uid = ses->Suid;
4364
4365         params = 2 /* level */  + name_len /*includes null */ ;
4366         pSMB->TotalDataCount = 0;
4367         pSMB->DataCount = 0;
4368         pSMB->DataOffset = 0;
4369         pSMB->MaxParameterCount = 0;
4370         /* BB find exact max SMB PDU from sess structure BB */
4371         pSMB->MaxDataCount = cpu_to_le16(4000);
4372         pSMB->MaxSetupCount = 0;
4373         pSMB->Reserved = 0;
4374         pSMB->Flags = 0;
4375         pSMB->Timeout = 0;
4376         pSMB->Reserved2 = 0;
4377         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4378           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4379         pSMB->SetupCount = 1;
4380         pSMB->Reserved3 = 0;
4381         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4382         byte_count = params + 3 /* pad */ ;
4383         pSMB->ParameterCount = cpu_to_le16(params);
4384         pSMB->TotalParameterCount = pSMB->ParameterCount;
4385         pSMB->MaxReferralLevel = cpu_to_le16(3);
4386         inc_rfc1001_len(pSMB, byte_count);
4387         pSMB->ByteCount = cpu_to_le16(byte_count);
4388
4389         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4390                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4391         if (rc) {
4392                 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4393                 goto GetDFSRefExit;
4394         }
4395         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4396
4397         /* BB Also check if enough total bytes returned? */
4398         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4399                 rc = -EIO;      /* bad smb */
4400                 goto GetDFSRefExit;
4401         }
4402
4403         cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4404                  get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4405
4406         /* parse returned result into more usable form */
4407         rc = parse_dfs_referrals(&pSMBr->dfs_data,
4408                                  le16_to_cpu(pSMBr->t2.DataCount),
4409                                  num_of_nodes, target_nodes, nls_codepage,
4410                                  remap, search_name,
4411                                  (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4412
4413 GetDFSRefExit:
4414         cifs_buf_release(pSMB);
4415
4416         if (rc == -EAGAIN)
4417                 goto getDFSRetry;
4418
4419         return rc;
4420 }
4421
4422 /* Query File System Info such as free space to old servers such as Win 9x */
4423 int
4424 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4425               struct kstatfs *FSData)
4426 {
4427 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4428         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4429         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4430         FILE_SYSTEM_ALLOC_INFO *response_data;
4431         int rc = 0;
4432         int bytes_returned = 0;
4433         __u16 params, byte_count;
4434
4435         cifs_dbg(FYI, "OldQFSInfo\n");
4436 oldQFSInfoRetry:
4437         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4438                 (void **) &pSMBr);
4439         if (rc)
4440                 return rc;
4441
4442         params = 2;     /* level */
4443         pSMB->TotalDataCount = 0;
4444         pSMB->MaxParameterCount = cpu_to_le16(2);
4445         pSMB->MaxDataCount = cpu_to_le16(1000);
4446         pSMB->MaxSetupCount = 0;
4447         pSMB->Reserved = 0;
4448         pSMB->Flags = 0;
4449         pSMB->Timeout = 0;
4450         pSMB->Reserved2 = 0;
4451         byte_count = params + 1 /* pad */ ;
4452         pSMB->TotalParameterCount = cpu_to_le16(params);
4453         pSMB->ParameterCount = pSMB->TotalParameterCount;
4454         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4455         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4456         pSMB->DataCount = 0;
4457         pSMB->DataOffset = 0;
4458         pSMB->SetupCount = 1;
4459         pSMB->Reserved3 = 0;
4460         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4461         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4462         inc_rfc1001_len(pSMB, byte_count);
4463         pSMB->ByteCount = cpu_to_le16(byte_count);
4464
4465         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4466                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4467         if (rc) {
4468                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4469         } else {                /* decode response */
4470                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4471
4472                 if (rc || get_bcc(&pSMBr->hdr) < 18)
4473                         rc = -EIO;      /* bad smb */
4474                 else {
4475                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4476                         cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
4477                                  get_bcc(&pSMBr->hdr), data_offset);
4478
4479                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
4480                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4481                         FSData->f_bsize =
4482                                 le16_to_cpu(response_data->BytesPerSector) *
4483                                 le32_to_cpu(response_data->
4484                                         SectorsPerAllocationUnit);
4485                         /*
4486                          * much prefer larger but if server doesn't report
4487                          * a valid size than 4K is a reasonable minimum
4488                          */
4489                         if (FSData->f_bsize < 512)
4490                                 FSData->f_bsize = 4096;
4491
4492                         FSData->f_blocks =
4493                                le32_to_cpu(response_data->TotalAllocationUnits);
4494                         FSData->f_bfree = FSData->f_bavail =
4495                                 le32_to_cpu(response_data->FreeAllocationUnits);
4496                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4497                                  (unsigned long long)FSData->f_blocks,
4498                                  (unsigned long long)FSData->f_bfree,
4499                                  FSData->f_bsize);
4500                 }
4501         }
4502         cifs_buf_release(pSMB);
4503
4504         if (rc == -EAGAIN)
4505                 goto oldQFSInfoRetry;
4506
4507         return rc;
4508 }
4509
4510 int
4511 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4512                struct kstatfs *FSData)
4513 {
4514 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4515         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4516         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4517         FILE_SYSTEM_INFO *response_data;
4518         int rc = 0;
4519         int bytes_returned = 0;
4520         __u16 params, byte_count;
4521
4522         cifs_dbg(FYI, "In QFSInfo\n");
4523 QFSInfoRetry:
4524         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4525                       (void **) &pSMBr);
4526         if (rc)
4527                 return rc;
4528
4529         params = 2;     /* level */
4530         pSMB->TotalDataCount = 0;
4531         pSMB->MaxParameterCount = cpu_to_le16(2);
4532         pSMB->MaxDataCount = cpu_to_le16(1000);
4533         pSMB->MaxSetupCount = 0;
4534         pSMB->Reserved = 0;
4535         pSMB->Flags = 0;
4536         pSMB->Timeout = 0;
4537         pSMB->Reserved2 = 0;
4538         byte_count = params + 1 /* pad */ ;
4539         pSMB->TotalParameterCount = cpu_to_le16(params);
4540         pSMB->ParameterCount = pSMB->TotalParameterCount;
4541         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4542                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4543         pSMB->DataCount = 0;
4544         pSMB->DataOffset = 0;
4545         pSMB->SetupCount = 1;
4546         pSMB->Reserved3 = 0;
4547         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4548         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4549         inc_rfc1001_len(pSMB, byte_count);
4550         pSMB->ByteCount = cpu_to_le16(byte_count);
4551
4552         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4553                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4554         if (rc) {
4555                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4556         } else {                /* decode response */
4557                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4558
4559                 if (rc || get_bcc(&pSMBr->hdr) < 24)
4560                         rc = -EIO;      /* bad smb */
4561                 else {
4562                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4563
4564                         response_data =
4565                             (FILE_SYSTEM_INFO
4566                              *) (((char *) &pSMBr->hdr.Protocol) +
4567                                  data_offset);
4568                         FSData->f_bsize =
4569                             le32_to_cpu(response_data->BytesPerSector) *
4570                             le32_to_cpu(response_data->
4571                                         SectorsPerAllocationUnit);
4572                         /*
4573                          * much prefer larger but if server doesn't report
4574                          * a valid size than 4K is a reasonable minimum
4575                          */
4576                         if (FSData->f_bsize < 512)
4577                                 FSData->f_bsize = 4096;
4578
4579                         FSData->f_blocks =
4580                             le64_to_cpu(response_data->TotalAllocationUnits);
4581                         FSData->f_bfree = FSData->f_bavail =
4582                             le64_to_cpu(response_data->FreeAllocationUnits);
4583                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4584                                  (unsigned long long)FSData->f_blocks,
4585                                  (unsigned long long)FSData->f_bfree,
4586                                  FSData->f_bsize);
4587                 }
4588         }
4589         cifs_buf_release(pSMB);
4590
4591         if (rc == -EAGAIN)
4592                 goto QFSInfoRetry;
4593
4594         return rc;
4595 }
4596
4597 int
4598 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4599 {
4600 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
4601         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4602         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4603         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4604         int rc = 0;
4605         int bytes_returned = 0;
4606         __u16 params, byte_count;
4607
4608         cifs_dbg(FYI, "In QFSAttributeInfo\n");
4609 QFSAttributeRetry:
4610         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4611                       (void **) &pSMBr);
4612         if (rc)
4613                 return rc;
4614
4615         params = 2;     /* level */
4616         pSMB->TotalDataCount = 0;
4617         pSMB->MaxParameterCount = cpu_to_le16(2);
4618         /* BB find exact max SMB PDU from sess structure BB */
4619         pSMB->MaxDataCount = cpu_to_le16(1000);
4620         pSMB->MaxSetupCount = 0;
4621         pSMB->Reserved = 0;
4622         pSMB->Flags = 0;
4623         pSMB->Timeout = 0;
4624         pSMB->Reserved2 = 0;
4625         byte_count = params + 1 /* pad */ ;
4626         pSMB->TotalParameterCount = cpu_to_le16(params);
4627         pSMB->ParameterCount = pSMB->TotalParameterCount;
4628         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4629                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4630         pSMB->DataCount = 0;
4631         pSMB->DataOffset = 0;
4632         pSMB->SetupCount = 1;
4633         pSMB->Reserved3 = 0;
4634         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4635         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4636         inc_rfc1001_len(pSMB, byte_count);
4637         pSMB->ByteCount = cpu_to_le16(byte_count);
4638
4639         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4640                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4641         if (rc) {
4642                 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4643         } else {                /* decode response */
4644                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4645
4646                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4647                         /* BB also check if enough bytes returned */
4648                         rc = -EIO;      /* bad smb */
4649                 } else {
4650                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4651                         response_data =
4652                             (FILE_SYSTEM_ATTRIBUTE_INFO
4653                              *) (((char *) &pSMBr->hdr.Protocol) +
4654                                  data_offset);
4655                         memcpy(&tcon->fsAttrInfo, response_data,
4656                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4657                 }
4658         }
4659         cifs_buf_release(pSMB);
4660
4661         if (rc == -EAGAIN)
4662                 goto QFSAttributeRetry;
4663
4664         return rc;
4665 }
4666
4667 int
4668 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4669 {
4670 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4671         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4672         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4673         FILE_SYSTEM_DEVICE_INFO *response_data;
4674         int rc = 0;
4675         int bytes_returned = 0;
4676         __u16 params, byte_count;
4677
4678         cifs_dbg(FYI, "In QFSDeviceInfo\n");
4679 QFSDeviceRetry:
4680         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4681                       (void **) &pSMBr);
4682         if (rc)
4683                 return rc;
4684
4685         params = 2;     /* level */
4686         pSMB->TotalDataCount = 0;
4687         pSMB->MaxParameterCount = cpu_to_le16(2);
4688         /* BB find exact max SMB PDU from sess structure BB */
4689         pSMB->MaxDataCount = cpu_to_le16(1000);
4690         pSMB->MaxSetupCount = 0;
4691         pSMB->Reserved = 0;
4692         pSMB->Flags = 0;
4693         pSMB->Timeout = 0;
4694         pSMB->Reserved2 = 0;
4695         byte_count = params + 1 /* pad */ ;
4696         pSMB->TotalParameterCount = cpu_to_le16(params);
4697         pSMB->ParameterCount = pSMB->TotalParameterCount;
4698         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4699                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4700
4701         pSMB->DataCount = 0;
4702         pSMB->DataOffset = 0;
4703         pSMB->SetupCount = 1;
4704         pSMB->Reserved3 = 0;
4705         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4706         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4707         inc_rfc1001_len(pSMB, byte_count);
4708         pSMB->ByteCount = cpu_to_le16(byte_count);
4709
4710         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4711                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4712         if (rc) {
4713                 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4714         } else {                /* decode response */
4715                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4716
4717                 if (rc || get_bcc(&pSMBr->hdr) <
4718                           sizeof(FILE_SYSTEM_DEVICE_INFO))
4719                         rc = -EIO;      /* bad smb */
4720                 else {
4721                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4722                         response_data =
4723                             (FILE_SYSTEM_DEVICE_INFO *)
4724                                 (((char *) &pSMBr->hdr.Protocol) +
4725                                  data_offset);
4726                         memcpy(&tcon->fsDevInfo, response_data,
4727                                sizeof(FILE_SYSTEM_DEVICE_INFO));
4728                 }
4729         }
4730         cifs_buf_release(pSMB);
4731
4732         if (rc == -EAGAIN)
4733                 goto QFSDeviceRetry;
4734
4735         return rc;
4736 }
4737
4738 int
4739 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4740 {
4741 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
4742         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4743         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4744         FILE_SYSTEM_UNIX_INFO *response_data;
4745         int rc = 0;
4746         int bytes_returned = 0;
4747         __u16 params, byte_count;
4748
4749         cifs_dbg(FYI, "In QFSUnixInfo\n");
4750 QFSUnixRetry:
4751         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4752                                    (void **) &pSMB, (void **) &pSMBr);
4753         if (rc)
4754                 return rc;
4755
4756         params = 2;     /* level */
4757         pSMB->TotalDataCount = 0;
4758         pSMB->DataCount = 0;
4759         pSMB->DataOffset = 0;
4760         pSMB->MaxParameterCount = cpu_to_le16(2);
4761         /* BB find exact max SMB PDU from sess structure BB */
4762         pSMB->MaxDataCount = cpu_to_le16(100);
4763         pSMB->MaxSetupCount = 0;
4764         pSMB->Reserved = 0;
4765         pSMB->Flags = 0;
4766         pSMB->Timeout = 0;
4767         pSMB->Reserved2 = 0;
4768         byte_count = params + 1 /* pad */ ;
4769         pSMB->ParameterCount = cpu_to_le16(params);
4770         pSMB->TotalParameterCount = pSMB->ParameterCount;
4771         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4772                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4773         pSMB->SetupCount = 1;
4774         pSMB->Reserved3 = 0;
4775         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4776         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4777         inc_rfc1001_len(pSMB, byte_count);
4778         pSMB->ByteCount = cpu_to_le16(byte_count);
4779
4780         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4781                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4782         if (rc) {
4783                 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4784         } else {                /* decode response */
4785                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4786
4787                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4788                         rc = -EIO;      /* bad smb */
4789                 } else {
4790                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4791                         response_data =
4792                             (FILE_SYSTEM_UNIX_INFO
4793                              *) (((char *) &pSMBr->hdr.Protocol) +
4794                                  data_offset);
4795                         memcpy(&tcon->fsUnixInfo, response_data,
4796                                sizeof(FILE_SYSTEM_UNIX_INFO));
4797                 }
4798         }
4799         cifs_buf_release(pSMB);
4800
4801         if (rc == -EAGAIN)
4802                 goto QFSUnixRetry;
4803
4804
4805         return rc;
4806 }
4807
4808 int
4809 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4810 {
4811 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
4812         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4813         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4814         int rc = 0;
4815         int bytes_returned = 0;
4816         __u16 params, param_offset, offset, byte_count;
4817
4818         cifs_dbg(FYI, "In SETFSUnixInfo\n");
4819 SETFSUnixRetry:
4820         /* BB switch to small buf init to save memory */
4821         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4822                                         (void **) &pSMB, (void **) &pSMBr);
4823         if (rc)
4824                 return rc;
4825
4826         params = 4;     /* 2 bytes zero followed by info level. */
4827         pSMB->MaxSetupCount = 0;
4828         pSMB->Reserved = 0;
4829         pSMB->Flags = 0;
4830         pSMB->Timeout = 0;
4831         pSMB->Reserved2 = 0;
4832         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4833                                 - 4;
4834         offset = param_offset + params;
4835
4836         pSMB->MaxParameterCount = cpu_to_le16(4);
4837         /* BB find exact max SMB PDU from sess structure BB */
4838         pSMB->MaxDataCount = cpu_to_le16(100);
4839         pSMB->SetupCount = 1;
4840         pSMB->Reserved3 = 0;
4841         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4842         byte_count = 1 /* pad */ + params + 12;
4843
4844         pSMB->DataCount = cpu_to_le16(12);
4845         pSMB->ParameterCount = cpu_to_le16(params);
4846         pSMB->TotalDataCount = pSMB->DataCount;
4847         pSMB->TotalParameterCount = pSMB->ParameterCount;
4848         pSMB->ParameterOffset = cpu_to_le16(param_offset);
4849         pSMB->DataOffset = cpu_to_le16(offset);
4850
4851         /* Params. */
4852         pSMB->FileNum = 0;
4853         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4854
4855         /* Data. */
4856         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4857         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4858         pSMB->ClientUnixCap = cpu_to_le64(cap);
4859
4860         inc_rfc1001_len(pSMB, byte_count);
4861         pSMB->ByteCount = cpu_to_le16(byte_count);
4862
4863         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4864                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4865         if (rc) {
4866                 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4867         } else {                /* decode response */
4868                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4869                 if (rc)
4870                         rc = -EIO;      /* bad smb */
4871         }
4872         cifs_buf_release(pSMB);
4873
4874         if (rc == -EAGAIN)
4875                 goto SETFSUnixRetry;
4876
4877         return rc;
4878 }
4879
4880
4881
4882 int
4883 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4884                    struct kstatfs *FSData)
4885 {
4886 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
4887         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4888         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4889         FILE_SYSTEM_POSIX_INFO *response_data;
4890         int rc = 0;
4891         int bytes_returned = 0;
4892         __u16 params, byte_count;
4893
4894         cifs_dbg(FYI, "In QFSPosixInfo\n");
4895 QFSPosixRetry:
4896         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4897                       (void **) &pSMBr);
4898         if (rc)
4899                 return rc;
4900
4901         params = 2;     /* level */
4902         pSMB->TotalDataCount = 0;
4903         pSMB->DataCount = 0;
4904         pSMB->DataOffset = 0;
4905         pSMB->MaxParameterCount = cpu_to_le16(2);
4906         /* BB find exact max SMB PDU from sess structure BB */
4907         pSMB->MaxDataCount = cpu_to_le16(100);
4908         pSMB->MaxSetupCount = 0;
4909         pSMB->Reserved = 0;
4910         pSMB->Flags = 0;
4911         pSMB->Timeout = 0;
4912         pSMB->Reserved2 = 0;
4913         byte_count = params + 1 /* pad */ ;
4914         pSMB->ParameterCount = cpu_to_le16(params);
4915         pSMB->TotalParameterCount = pSMB->ParameterCount;
4916         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4917                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4918         pSMB->SetupCount = 1;
4919         pSMB->Reserved3 = 0;
4920         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4921         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4922         inc_rfc1001_len(pSMB, byte_count);
4923         pSMB->ByteCount = cpu_to_le16(byte_count);
4924
4925         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4926                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4927         if (rc) {
4928                 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4929         } else {                /* decode response */
4930                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4931
4932                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4933                         rc = -EIO;      /* bad smb */
4934                 } else {
4935                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4936                         response_data =
4937                             (FILE_SYSTEM_POSIX_INFO
4938                              *) (((char *) &pSMBr->hdr.Protocol) +
4939                                  data_offset);
4940                         FSData->f_bsize =
4941                                         le32_to_cpu(response_data->BlockSize);
4942                         /*
4943                          * much prefer larger but if server doesn't report
4944                          * a valid size than 4K is a reasonable minimum
4945                          */
4946                         if (FSData->f_bsize < 512)
4947                                 FSData->f_bsize = 4096;
4948
4949                         FSData->f_blocks =
4950                                         le64_to_cpu(response_data->TotalBlocks);
4951                         FSData->f_bfree =
4952                             le64_to_cpu(response_data->BlocksAvail);
4953                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4954                                 FSData->f_bavail = FSData->f_bfree;
4955                         } else {
4956                                 FSData->f_bavail =
4957                                     le64_to_cpu(response_data->UserBlocksAvail);
4958                         }
4959                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
4960                                 FSData->f_files =
4961                                      le64_to_cpu(response_data->TotalFileNodes);
4962                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
4963                                 FSData->f_ffree =
4964                                       le64_to_cpu(response_data->FreeFileNodes);
4965                 }
4966         }
4967         cifs_buf_release(pSMB);
4968
4969         if (rc == -EAGAIN)
4970                 goto QFSPosixRetry;
4971
4972         return rc;
4973 }
4974
4975
4976 /*
4977  * We can not use write of zero bytes trick to set file size due to need for
4978  * large file support. Also note that this SetPathInfo is preferred to
4979  * SetFileInfo based method in next routine which is only needed to work around
4980  * a sharing violation bugin Samba which this routine can run into.
4981  */
4982 int
4983 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
4984               const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
4985               bool set_allocation)
4986 {
4987         struct smb_com_transaction2_spi_req *pSMB = NULL;
4988         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
4989         struct file_end_of_file_info *parm_data;
4990         int name_len;
4991         int rc = 0;
4992         int bytes_returned = 0;
4993         int remap = cifs_remap(cifs_sb);
4994
4995         __u16 params, byte_count, data_count, param_offset, offset;
4996
4997         cifs_dbg(FYI, "In SetEOF\n");
4998 SetEOFRetry:
4999         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5000                       (void **) &pSMBr);
5001         if (rc)
5002                 return rc;
5003
5004         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5005                 name_len =
5006                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5007                                        PATH_MAX, cifs_sb->local_nls, remap);
5008                 name_len++;     /* trailing null */
5009                 name_len *= 2;
5010         } else {
5011                 name_len = copy_path_name(pSMB->FileName, file_name);
5012         }
5013         params = 6 + name_len;
5014         data_count = sizeof(struct file_end_of_file_info);
5015         pSMB->MaxParameterCount = cpu_to_le16(2);
5016         pSMB->MaxDataCount = cpu_to_le16(4100);
5017         pSMB->MaxSetupCount = 0;
5018         pSMB->Reserved = 0;
5019         pSMB->Flags = 0;
5020         pSMB->Timeout = 0;
5021         pSMB->Reserved2 = 0;
5022         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5023                                 InformationLevel) - 4;
5024         offset = param_offset + params;
5025         if (set_allocation) {
5026                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5027                         pSMB->InformationLevel =
5028                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5029                 else
5030                         pSMB->InformationLevel =
5031                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5032         } else /* Set File Size */  {
5033             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5034                     pSMB->InformationLevel =
5035                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5036             else
5037                     pSMB->InformationLevel =
5038                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5039         }
5040
5041         parm_data =
5042             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5043                                        offset);
5044         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5045         pSMB->DataOffset = cpu_to_le16(offset);
5046         pSMB->SetupCount = 1;
5047         pSMB->Reserved3 = 0;
5048         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5049         byte_count = 3 /* pad */  + params + data_count;
5050         pSMB->DataCount = cpu_to_le16(data_count);
5051         pSMB->TotalDataCount = pSMB->DataCount;
5052         pSMB->ParameterCount = cpu_to_le16(params);
5053         pSMB->TotalParameterCount = pSMB->ParameterCount;
5054         pSMB->Reserved4 = 0;
5055         inc_rfc1001_len(pSMB, byte_count);
5056         parm_data->FileSize = cpu_to_le64(size);
5057         pSMB->ByteCount = cpu_to_le16(byte_count);
5058         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5059                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5060         if (rc)
5061                 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5062
5063         cifs_buf_release(pSMB);
5064
5065         if (rc == -EAGAIN)
5066                 goto SetEOFRetry;
5067
5068         return rc;
5069 }
5070
5071 int
5072 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5073                    struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5074 {
5075         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5076         struct file_end_of_file_info *parm_data;
5077         int rc = 0;
5078         __u16 params, param_offset, offset, byte_count, count;
5079
5080         cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5081                  (long long)size);
5082         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5083
5084         if (rc)
5085                 return rc;
5086
5087         pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5088         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5089
5090         params = 6;
5091         pSMB->MaxSetupCount = 0;
5092         pSMB->Reserved = 0;
5093         pSMB->Flags = 0;
5094         pSMB->Timeout = 0;
5095         pSMB->Reserved2 = 0;
5096         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5097         offset = param_offset + params;
5098
5099         count = sizeof(struct file_end_of_file_info);
5100         pSMB->MaxParameterCount = cpu_to_le16(2);
5101         /* BB find exact max SMB PDU from sess structure BB */
5102         pSMB->MaxDataCount = cpu_to_le16(1000);
5103         pSMB->SetupCount = 1;
5104         pSMB->Reserved3 = 0;
5105         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5106         byte_count = 3 /* pad */  + params + count;
5107         pSMB->DataCount = cpu_to_le16(count);
5108         pSMB->ParameterCount = cpu_to_le16(params);
5109         pSMB->TotalDataCount = pSMB->DataCount;
5110         pSMB->TotalParameterCount = pSMB->ParameterCount;
5111         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5112         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5113         parm_data =
5114                 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5115         pSMB->DataOffset = cpu_to_le16(offset);
5116         parm_data->FileSize = cpu_to_le64(size);
5117         pSMB->Fid = cfile->fid.netfid;
5118         if (set_allocation) {
5119                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5120                         pSMB->InformationLevel =
5121                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5122                 else
5123                         pSMB->InformationLevel =
5124                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5125         } else /* Set File Size */  {
5126             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5127                     pSMB->InformationLevel =
5128                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5129             else
5130                     pSMB->InformationLevel =
5131                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5132         }
5133         pSMB->Reserved4 = 0;
5134         inc_rfc1001_len(pSMB, byte_count);
5135         pSMB->ByteCount = cpu_to_le16(byte_count);
5136         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5137         cifs_small_buf_release(pSMB);
5138         if (rc) {
5139                 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5140                          rc);
5141         }
5142
5143         /* Note: On -EAGAIN error only caller can retry on handle based calls
5144                 since file handle passed in no longer valid */
5145
5146         return rc;
5147 }
5148
5149 /* Some legacy servers such as NT4 require that the file times be set on
5150    an open handle, rather than by pathname - this is awkward due to
5151    potential access conflicts on the open, but it is unavoidable for these
5152    old servers since the only other choice is to go from 100 nanosecond DCE
5153    time and resort to the original setpathinfo level which takes the ancient
5154    DOS time format with 2 second granularity */
5155 int
5156 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5157                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5158 {
5159         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5160         char *data_offset;
5161         int rc = 0;
5162         __u16 params, param_offset, offset, byte_count, count;
5163
5164         cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5165         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5166
5167         if (rc)
5168                 return rc;
5169
5170         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5171         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5172
5173         params = 6;
5174         pSMB->MaxSetupCount = 0;
5175         pSMB->Reserved = 0;
5176         pSMB->Flags = 0;
5177         pSMB->Timeout = 0;
5178         pSMB->Reserved2 = 0;
5179         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5180         offset = param_offset + params;
5181
5182         data_offset = (char *)pSMB +
5183                         offsetof(struct smb_hdr, Protocol) + offset;
5184
5185         count = sizeof(FILE_BASIC_INFO);
5186         pSMB->MaxParameterCount = cpu_to_le16(2);
5187         /* BB find max SMB PDU from sess */
5188         pSMB->MaxDataCount = cpu_to_le16(1000);
5189         pSMB->SetupCount = 1;
5190         pSMB->Reserved3 = 0;
5191         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5192         byte_count = 3 /* pad */  + params + count;
5193         pSMB->DataCount = cpu_to_le16(count);
5194         pSMB->ParameterCount = cpu_to_le16(params);
5195         pSMB->TotalDataCount = pSMB->DataCount;
5196         pSMB->TotalParameterCount = pSMB->ParameterCount;
5197         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5198         pSMB->DataOffset = cpu_to_le16(offset);
5199         pSMB->Fid = fid;
5200         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5201                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5202         else
5203                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5204         pSMB->Reserved4 = 0;
5205         inc_rfc1001_len(pSMB, byte_count);
5206         pSMB->ByteCount = cpu_to_le16(byte_count);
5207         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5208         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5209         cifs_small_buf_release(pSMB);
5210         if (rc)
5211                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5212                          rc);
5213
5214         /* Note: On -EAGAIN error only caller can retry on handle based calls
5215                 since file handle passed in no longer valid */
5216
5217         return rc;
5218 }
5219
5220 int
5221 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5222                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5223 {
5224         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5225         char *data_offset;
5226         int rc = 0;
5227         __u16 params, param_offset, offset, byte_count, count;
5228
5229         cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5230         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5231
5232         if (rc)
5233                 return rc;
5234
5235         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5236         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5237
5238         params = 6;
5239         pSMB->MaxSetupCount = 0;
5240         pSMB->Reserved = 0;
5241         pSMB->Flags = 0;
5242         pSMB->Timeout = 0;
5243         pSMB->Reserved2 = 0;
5244         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5245         offset = param_offset + params;
5246
5247         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5248         data_offset = (char *)(pSMB) + offset + 4;
5249
5250         count = 1;
5251         pSMB->MaxParameterCount = cpu_to_le16(2);
5252         /* BB find max SMB PDU from sess */
5253         pSMB->MaxDataCount = cpu_to_le16(1000);
5254         pSMB->SetupCount = 1;
5255         pSMB->Reserved3 = 0;
5256         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5257         byte_count = 3 /* pad */  + params + count;
5258         pSMB->DataCount = cpu_to_le16(count);
5259         pSMB->ParameterCount = cpu_to_le16(params);
5260         pSMB->TotalDataCount = pSMB->DataCount;
5261         pSMB->TotalParameterCount = pSMB->ParameterCount;
5262         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5263         pSMB->DataOffset = cpu_to_le16(offset);
5264         pSMB->Fid = fid;
5265         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5266         pSMB->Reserved4 = 0;
5267         inc_rfc1001_len(pSMB, byte_count);
5268         pSMB->ByteCount = cpu_to_le16(byte_count);
5269         *data_offset = delete_file ? 1 : 0;
5270         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5271         cifs_small_buf_release(pSMB);
5272         if (rc)
5273                 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5274
5275         return rc;
5276 }
5277
5278 static int
5279 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5280                      const char *fileName, const FILE_BASIC_INFO *data,
5281                      const struct nls_table *nls_codepage,
5282                      struct cifs_sb_info *cifs_sb)
5283 {
5284         int oplock = 0;
5285         struct cifs_open_parms oparms;
5286         struct cifs_fid fid;
5287         int rc;
5288
5289         oparms = (struct cifs_open_parms) {
5290                 .tcon = tcon,
5291                 .cifs_sb = cifs_sb,
5292                 .desired_access = GENERIC_WRITE,
5293                 .create_options = cifs_create_options(cifs_sb, 0),
5294                 .disposition = FILE_OPEN,
5295                 .path = fileName,
5296                 .fid = &fid,
5297         };
5298
5299         rc = CIFS_open(xid, &oparms, &oplock, NULL);
5300         if (rc)
5301                 goto out;
5302
5303         rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5304         CIFSSMBClose(xid, tcon, fid.netfid);
5305 out:
5306
5307         return rc;
5308 }
5309
5310 int
5311 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5312                    const char *fileName, const FILE_BASIC_INFO *data,
5313                    const struct nls_table *nls_codepage,
5314                      struct cifs_sb_info *cifs_sb)
5315 {
5316         TRANSACTION2_SPI_REQ *pSMB = NULL;
5317         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5318         int name_len;
5319         int rc = 0;
5320         int bytes_returned = 0;
5321         char *data_offset;
5322         __u16 params, param_offset, offset, byte_count, count;
5323         int remap = cifs_remap(cifs_sb);
5324
5325         cifs_dbg(FYI, "In SetTimes\n");
5326
5327 SetTimesRetry:
5328         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5329                       (void **) &pSMBr);
5330         if (rc)
5331                 return rc;
5332
5333         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5334                 name_len =
5335                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5336                                        PATH_MAX, nls_codepage, remap);
5337                 name_len++;     /* trailing null */
5338                 name_len *= 2;
5339         } else {
5340                 name_len = copy_path_name(pSMB->FileName, fileName);
5341         }
5342
5343         params = 6 + name_len;
5344         count = sizeof(FILE_BASIC_INFO);
5345         pSMB->MaxParameterCount = cpu_to_le16(2);
5346         /* BB find max SMB PDU from sess structure BB */
5347         pSMB->MaxDataCount = cpu_to_le16(1000);
5348         pSMB->MaxSetupCount = 0;
5349         pSMB->Reserved = 0;
5350         pSMB->Flags = 0;
5351         pSMB->Timeout = 0;
5352         pSMB->Reserved2 = 0;
5353         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5354                                 InformationLevel) - 4;
5355         offset = param_offset + params;
5356         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5357         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5358         pSMB->DataOffset = cpu_to_le16(offset);
5359         pSMB->SetupCount = 1;
5360         pSMB->Reserved3 = 0;
5361         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5362         byte_count = 3 /* pad */  + params + count;
5363
5364         pSMB->DataCount = cpu_to_le16(count);
5365         pSMB->ParameterCount = cpu_to_le16(params);
5366         pSMB->TotalDataCount = pSMB->DataCount;
5367         pSMB->TotalParameterCount = pSMB->ParameterCount;
5368         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5369                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5370         else
5371                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5372         pSMB->Reserved4 = 0;
5373         inc_rfc1001_len(pSMB, byte_count);
5374         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5375         pSMB->ByteCount = cpu_to_le16(byte_count);
5376         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5377                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5378         if (rc)
5379                 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5380
5381         cifs_buf_release(pSMB);
5382
5383         if (rc == -EAGAIN)
5384                 goto SetTimesRetry;
5385
5386         if (rc == -EOPNOTSUPP)
5387                 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5388                                             nls_codepage, cifs_sb);
5389
5390         return rc;
5391 }
5392
5393 static void
5394 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5395                         const struct cifs_unix_set_info_args *args)
5396 {
5397         u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5398         u64 mode = args->mode;
5399
5400         if (uid_valid(args->uid))
5401                 uid = from_kuid(&init_user_ns, args->uid);
5402         if (gid_valid(args->gid))
5403                 gid = from_kgid(&init_user_ns, args->gid);
5404
5405         /*
5406          * Samba server ignores set of file size to zero due to bugs in some
5407          * older clients, but we should be precise - we use SetFileSize to
5408          * set file size and do not want to truncate file size to zero
5409          * accidentally as happened on one Samba server beta by putting
5410          * zero instead of -1 here
5411          */
5412         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5413         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5414         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5415         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5416         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5417         data_offset->Uid = cpu_to_le64(uid);
5418         data_offset->Gid = cpu_to_le64(gid);
5419         /* better to leave device as zero when it is  */
5420         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5421         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5422         data_offset->Permissions = cpu_to_le64(mode);
5423
5424         if (S_ISREG(mode))
5425                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5426         else if (S_ISDIR(mode))
5427                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5428         else if (S_ISLNK(mode))
5429                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5430         else if (S_ISCHR(mode))
5431                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5432         else if (S_ISBLK(mode))
5433                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5434         else if (S_ISFIFO(mode))
5435                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5436         else if (S_ISSOCK(mode))
5437                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5438 }
5439
5440 int
5441 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5442                        const struct cifs_unix_set_info_args *args,
5443                        u16 fid, u32 pid_of_opener)
5444 {
5445         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5446         char *data_offset;
5447         int rc = 0;
5448         u16 params, param_offset, offset, byte_count, count;
5449
5450         cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5451         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5452
5453         if (rc)
5454                 return rc;
5455
5456         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5457         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5458
5459         params = 6;
5460         pSMB->MaxSetupCount = 0;
5461         pSMB->Reserved = 0;
5462         pSMB->Flags = 0;
5463         pSMB->Timeout = 0;
5464         pSMB->Reserved2 = 0;
5465         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5466         offset = param_offset + params;
5467
5468         data_offset = (char *)pSMB +
5469                         offsetof(struct smb_hdr, Protocol) + offset;
5470
5471         count = sizeof(FILE_UNIX_BASIC_INFO);
5472
5473         pSMB->MaxParameterCount = cpu_to_le16(2);
5474         /* BB find max SMB PDU from sess */
5475         pSMB->MaxDataCount = cpu_to_le16(1000);
5476         pSMB->SetupCount = 1;
5477         pSMB->Reserved3 = 0;
5478         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5479         byte_count = 3 /* pad */  + params + count;
5480         pSMB->DataCount = cpu_to_le16(count);
5481         pSMB->ParameterCount = cpu_to_le16(params);
5482         pSMB->TotalDataCount = pSMB->DataCount;
5483         pSMB->TotalParameterCount = pSMB->ParameterCount;
5484         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5485         pSMB->DataOffset = cpu_to_le16(offset);
5486         pSMB->Fid = fid;
5487         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5488         pSMB->Reserved4 = 0;
5489         inc_rfc1001_len(pSMB, byte_count);
5490         pSMB->ByteCount = cpu_to_le16(byte_count);
5491
5492         cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5493
5494         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5495         cifs_small_buf_release(pSMB);
5496         if (rc)
5497                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5498                          rc);
5499
5500         /* Note: On -EAGAIN error only caller can retry on handle based calls
5501                 since file handle passed in no longer valid */
5502
5503         return rc;
5504 }
5505
5506 int
5507 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5508                        const char *file_name,
5509                        const struct cifs_unix_set_info_args *args,
5510                        const struct nls_table *nls_codepage, int remap)
5511 {
5512         TRANSACTION2_SPI_REQ *pSMB = NULL;
5513         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5514         int name_len;
5515         int rc = 0;
5516         int bytes_returned = 0;
5517         FILE_UNIX_BASIC_INFO *data_offset;
5518         __u16 params, param_offset, offset, count, byte_count;
5519
5520         cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5521 setPermsRetry:
5522         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5523                       (void **) &pSMBr);
5524         if (rc)
5525                 return rc;
5526
5527         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5528                 name_len =
5529                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5530                                        PATH_MAX, nls_codepage, remap);
5531                 name_len++;     /* trailing null */
5532                 name_len *= 2;
5533         } else {
5534                 name_len = copy_path_name(pSMB->FileName, file_name);
5535         }
5536
5537         params = 6 + name_len;
5538         count = sizeof(FILE_UNIX_BASIC_INFO);
5539         pSMB->MaxParameterCount = cpu_to_le16(2);
5540         /* BB find max SMB PDU from sess structure BB */
5541         pSMB->MaxDataCount = cpu_to_le16(1000);
5542         pSMB->MaxSetupCount = 0;
5543         pSMB->Reserved = 0;
5544         pSMB->Flags = 0;
5545         pSMB->Timeout = 0;
5546         pSMB->Reserved2 = 0;
5547         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5548                                 InformationLevel) - 4;
5549         offset = param_offset + params;
5550         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5551         data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5552         memset(data_offset, 0, count);
5553         pSMB->DataOffset = cpu_to_le16(offset);
5554         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5555         pSMB->SetupCount = 1;
5556         pSMB->Reserved3 = 0;
5557         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5558         byte_count = 3 /* pad */  + params + count;
5559         pSMB->ParameterCount = cpu_to_le16(params);
5560         pSMB->DataCount = cpu_to_le16(count);
5561         pSMB->TotalParameterCount = pSMB->ParameterCount;
5562         pSMB->TotalDataCount = pSMB->DataCount;
5563         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5564         pSMB->Reserved4 = 0;
5565         inc_rfc1001_len(pSMB, byte_count);
5566
5567         cifs_fill_unix_set_info(data_offset, args);
5568
5569         pSMB->ByteCount = cpu_to_le16(byte_count);
5570         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5571                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5572         if (rc)
5573                 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5574
5575         cifs_buf_release(pSMB);
5576         if (rc == -EAGAIN)
5577                 goto setPermsRetry;
5578         return rc;
5579 }
5580
5581 #ifdef CONFIG_CIFS_XATTR
5582 /*
5583  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5584  * function used by listxattr and getxattr type calls. When ea_name is set,
5585  * it looks for that attribute name and stuffs that value into the EAData
5586  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5587  * buffer. In both cases, the return value is either the length of the
5588  * resulting data or a negative error code. If EAData is a NULL pointer then
5589  * the data isn't copied to it, but the length is returned.
5590  */
5591 ssize_t
5592 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5593                 const unsigned char *searchName, const unsigned char *ea_name,
5594                 char *EAData, size_t buf_size,
5595                 struct cifs_sb_info *cifs_sb)
5596 {
5597                 /* BB assumes one setup word */
5598         TRANSACTION2_QPI_REQ *pSMB = NULL;
5599         TRANSACTION2_QPI_RSP *pSMBr = NULL;
5600         int remap = cifs_remap(cifs_sb);
5601         struct nls_table *nls_codepage = cifs_sb->local_nls;
5602         int rc = 0;
5603         int bytes_returned;
5604         int list_len;
5605         struct fealist *ea_response_data;
5606         struct fea *temp_fea;
5607         char *temp_ptr;
5608         char *end_of_smb;
5609         __u16 params, byte_count, data_offset;
5610         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5611
5612         cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5613 QAllEAsRetry:
5614         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5615                       (void **) &pSMBr);
5616         if (rc)
5617                 return rc;
5618
5619         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5620                 list_len =
5621                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5622                                        PATH_MAX, nls_codepage, remap);
5623                 list_len++;     /* trailing null */
5624                 list_len *= 2;
5625         } else {
5626                 list_len = copy_path_name(pSMB->FileName, searchName);
5627         }
5628
5629         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5630         pSMB->TotalDataCount = 0;
5631         pSMB->MaxParameterCount = cpu_to_le16(2);
5632         /* BB find exact max SMB PDU from sess structure BB */
5633         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5634         pSMB->MaxSetupCount = 0;
5635         pSMB->Reserved = 0;
5636         pSMB->Flags = 0;
5637         pSMB->Timeout = 0;
5638         pSMB->Reserved2 = 0;
5639         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5640         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5641         pSMB->DataCount = 0;
5642         pSMB->DataOffset = 0;
5643         pSMB->SetupCount = 1;
5644         pSMB->Reserved3 = 0;
5645         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5646         byte_count = params + 1 /* pad */ ;
5647         pSMB->TotalParameterCount = cpu_to_le16(params);
5648         pSMB->ParameterCount = pSMB->TotalParameterCount;
5649         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5650         pSMB->Reserved4 = 0;
5651         inc_rfc1001_len(pSMB, byte_count);
5652         pSMB->ByteCount = cpu_to_le16(byte_count);
5653
5654         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5655                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5656         if (rc) {
5657                 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5658                 goto QAllEAsOut;
5659         }
5660
5661
5662         /* BB also check enough total bytes returned */
5663         /* BB we need to improve the validity checking
5664         of these trans2 responses */
5665
5666         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5667         if (rc || get_bcc(&pSMBr->hdr) < 4) {
5668                 rc = -EIO;      /* bad smb */
5669                 goto QAllEAsOut;
5670         }
5671
5672         /* check that length of list is not more than bcc */
5673         /* check that each entry does not go beyond length
5674            of list */
5675         /* check that each element of each entry does not
5676            go beyond end of list */
5677         /* validate_trans2_offsets() */
5678         /* BB check if start of smb + data_offset > &bcc+ bcc */
5679
5680         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5681         ea_response_data = (struct fealist *)
5682                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5683
5684         list_len = le32_to_cpu(ea_response_data->list_len);
5685         cifs_dbg(FYI, "ea length %d\n", list_len);
5686         if (list_len <= 8) {
5687                 cifs_dbg(FYI, "empty EA list returned from server\n");
5688                 /* didn't find the named attribute */
5689                 if (ea_name)
5690                         rc = -ENODATA;
5691                 goto QAllEAsOut;
5692         }
5693
5694         /* make sure list_len doesn't go past end of SMB */
5695         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5696         if ((char *)ea_response_data + list_len > end_of_smb) {
5697                 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5698                 rc = -EIO;
5699                 goto QAllEAsOut;
5700         }
5701
5702         /* account for ea list len */
5703         list_len -= 4;
5704         temp_fea = &ea_response_data->list;
5705         temp_ptr = (char *)temp_fea;
5706         while (list_len > 0) {
5707                 unsigned int name_len;
5708                 __u16 value_len;
5709
5710                 list_len -= 4;
5711                 temp_ptr += 4;
5712                 /* make sure we can read name_len and value_len */
5713                 if (list_len < 0) {
5714                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5715                         rc = -EIO;
5716                         goto QAllEAsOut;
5717                 }
5718
5719                 name_len = temp_fea->name_len;
5720                 value_len = le16_to_cpu(temp_fea->value_len);
5721                 list_len -= name_len + 1 + value_len;
5722                 if (list_len < 0) {
5723                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5724                         rc = -EIO;
5725                         goto QAllEAsOut;
5726                 }
5727
5728                 if (ea_name) {
5729                         if (ea_name_len == name_len &&
5730                             memcmp(ea_name, temp_ptr, name_len) == 0) {
5731                                 temp_ptr += name_len + 1;
5732                                 rc = value_len;
5733                                 if (buf_size == 0)
5734                                         goto QAllEAsOut;
5735                                 if ((size_t)value_len > buf_size) {
5736                                         rc = -ERANGE;
5737                                         goto QAllEAsOut;
5738                                 }
5739                                 memcpy(EAData, temp_ptr, value_len);
5740                                 goto QAllEAsOut;
5741                         }
5742                 } else {
5743                         /* account for prefix user. and trailing null */
5744                         rc += (5 + 1 + name_len);
5745                         if (rc < (int) buf_size) {
5746                                 memcpy(EAData, "user.", 5);
5747                                 EAData += 5;
5748                                 memcpy(EAData, temp_ptr, name_len);
5749                                 EAData += name_len;
5750                                 /* null terminate name */
5751                                 *EAData = 0;
5752                                 ++EAData;
5753                         } else if (buf_size == 0) {
5754                                 /* skip copy - calc size only */
5755                         } else {
5756                                 /* stop before overrun buffer */
5757                                 rc = -ERANGE;
5758                                 break;
5759                         }
5760                 }
5761                 temp_ptr += name_len + 1 + value_len;
5762                 temp_fea = (struct fea *)temp_ptr;
5763         }
5764
5765         /* didn't find the named attribute */
5766         if (ea_name)
5767                 rc = -ENODATA;
5768
5769 QAllEAsOut:
5770         cifs_buf_release(pSMB);
5771         if (rc == -EAGAIN)
5772                 goto QAllEAsRetry;
5773
5774         return (ssize_t)rc;
5775 }
5776
5777 int
5778 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5779              const char *fileName, const char *ea_name, const void *ea_value,
5780              const __u16 ea_value_len, const struct nls_table *nls_codepage,
5781              struct cifs_sb_info *cifs_sb)
5782 {
5783         struct smb_com_transaction2_spi_req *pSMB = NULL;
5784         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5785         struct fealist *parm_data;
5786         int name_len;
5787         int rc = 0;
5788         int bytes_returned = 0;
5789         __u16 params, param_offset, byte_count, offset, count;
5790         int remap = cifs_remap(cifs_sb);
5791
5792         cifs_dbg(FYI, "In SetEA\n");
5793 SetEARetry:
5794         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5795                       (void **) &pSMBr);
5796         if (rc)
5797                 return rc;
5798
5799         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5800                 name_len =
5801                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5802                                        PATH_MAX, nls_codepage, remap);
5803                 name_len++;     /* trailing null */
5804                 name_len *= 2;
5805         } else {
5806                 name_len = copy_path_name(pSMB->FileName, fileName);
5807         }
5808
5809         params = 6 + name_len;
5810
5811         /* done calculating parms using name_len of file name,
5812         now use name_len to calculate length of ea name
5813         we are going to create in the inode xattrs */
5814         if (ea_name == NULL)
5815                 name_len = 0;
5816         else
5817                 name_len = strnlen(ea_name, 255);
5818
5819         count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
5820         pSMB->MaxParameterCount = cpu_to_le16(2);
5821         /* BB find max SMB PDU from sess */
5822         pSMB->MaxDataCount = cpu_to_le16(1000);
5823         pSMB->MaxSetupCount = 0;
5824         pSMB->Reserved = 0;
5825         pSMB->Flags = 0;
5826         pSMB->Timeout = 0;
5827         pSMB->Reserved2 = 0;
5828         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5829                                 InformationLevel) - 4;
5830         offset = param_offset + params;
5831         pSMB->InformationLevel =
5832                 cpu_to_le16(SMB_SET_FILE_EA);
5833
5834         parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5835         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5836         pSMB->DataOffset = cpu_to_le16(offset);
5837         pSMB->SetupCount = 1;
5838         pSMB->Reserved3 = 0;
5839         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5840         byte_count = 3 /* pad */  + params + count;
5841         pSMB->DataCount = cpu_to_le16(count);
5842         parm_data->list_len = cpu_to_le32(count);
5843         parm_data->list.EA_flags = 0;
5844         /* we checked above that name len is less than 255 */
5845         parm_data->list.name_len = (__u8)name_len;
5846         /* EA names are always ASCII */
5847         if (ea_name)
5848                 strncpy(parm_data->list.name, ea_name, name_len);
5849         parm_data->list.name[name_len] = '\0';
5850         parm_data->list.value_len = cpu_to_le16(ea_value_len);
5851         /* caller ensures that ea_value_len is less than 64K but
5852         we need to ensure that it fits within the smb */
5853
5854         /*BB add length check to see if it would fit in
5855              negotiated SMB buffer size BB */
5856         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5857         if (ea_value_len)
5858                 memcpy(parm_data->list.name + name_len + 1,
5859                        ea_value, ea_value_len);
5860
5861         pSMB->TotalDataCount = pSMB->DataCount;
5862         pSMB->ParameterCount = cpu_to_le16(params);
5863         pSMB->TotalParameterCount = pSMB->ParameterCount;
5864         pSMB->Reserved4 = 0;
5865         inc_rfc1001_len(pSMB, byte_count);
5866         pSMB->ByteCount = cpu_to_le16(byte_count);
5867         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5868                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5869         if (rc)
5870                 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5871
5872         cifs_buf_release(pSMB);
5873
5874         if (rc == -EAGAIN)
5875                 goto SetEARetry;
5876
5877         return rc;
5878 }
5879 #endif