smb: client: replace deprecated strncpy with strscpy
[sfrench/cifs-2.6.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, struct dentry *dentry)
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->c.flc_type = F_UNLCK;
2070                 else {
2071                         if (parm_data->lock_type ==
2072                                         cpu_to_le16(CIFS_RDLCK))
2073                                 pLockData->c.flc_type = F_RDLCK;
2074                         else if (parm_data->lock_type ==
2075                                         cpu_to_le16(CIFS_WRLCK))
2076                                 pLockData->c.flc_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->c.flc_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 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2153                   struct dentry *source_dentry,
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 CIFSCreateHardLink(const unsigned int xid,
2534                        struct cifs_tcon *tcon,
2535                        struct dentry *source_dentry,
2536                        const char *from_name, const char *to_name,
2537                        struct cifs_sb_info *cifs_sb)
2538 {
2539         int rc = 0;
2540         NT_RENAME_REQ *pSMB = NULL;
2541         RENAME_RSP *pSMBr = NULL;
2542         int bytes_returned;
2543         int name_len, name_len2;
2544         __u16 count;
2545         int remap = cifs_remap(cifs_sb);
2546
2547         cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2548 winCreateHardLinkRetry:
2549
2550         rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2551                       (void **) &pSMBr);
2552         if (rc)
2553                 return rc;
2554
2555         pSMB->SearchAttributes =
2556             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2557                         ATTR_DIRECTORY);
2558         pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2559         pSMB->ClusterCount = 0;
2560
2561         pSMB->BufferFormat = 0x04;
2562
2563         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2564                 name_len =
2565                     cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2566                                        PATH_MAX, cifs_sb->local_nls, remap);
2567                 name_len++;     /* trailing null */
2568                 name_len *= 2;
2569
2570                 /* protocol specifies ASCII buffer format (0x04) for unicode */
2571                 pSMB->OldFileName[name_len] = 0x04;
2572                 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2573                 name_len2 =
2574                     cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2575                                        to_name, PATH_MAX, cifs_sb->local_nls,
2576                                        remap);
2577                 name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2578                 name_len2 *= 2; /* convert to bytes */
2579         } else {
2580                 name_len = copy_path_name(pSMB->OldFileName, from_name);
2581                 pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
2582                 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2583                 name_len2++;    /* signature byte */
2584         }
2585
2586         count = 1 /* string type byte */  + name_len + name_len2;
2587         inc_rfc1001_len(pSMB, count);
2588         pSMB->ByteCount = cpu_to_le16(count);
2589
2590         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2591                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2592         cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2593         if (rc)
2594                 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2595
2596         cifs_buf_release(pSMB);
2597         if (rc == -EAGAIN)
2598                 goto winCreateHardLinkRetry;
2599
2600         return rc;
2601 }
2602
2603 int
2604 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2605                         const unsigned char *searchName, char **symlinkinfo,
2606                         const struct nls_table *nls_codepage, int remap)
2607 {
2608 /* SMB_QUERY_FILE_UNIX_LINK */
2609         TRANSACTION2_QPI_REQ *pSMB = NULL;
2610         TRANSACTION2_QPI_RSP *pSMBr = NULL;
2611         int rc = 0;
2612         int bytes_returned;
2613         int name_len;
2614         __u16 params, byte_count;
2615         char *data_start;
2616
2617         cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2618
2619 querySymLinkRetry:
2620         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2621                       (void **) &pSMBr);
2622         if (rc)
2623                 return rc;
2624
2625         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2626                 name_len =
2627                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
2628                                            searchName, PATH_MAX, nls_codepage,
2629                                            remap);
2630                 name_len++;     /* trailing null */
2631                 name_len *= 2;
2632         } else {
2633                 name_len = copy_path_name(pSMB->FileName, searchName);
2634         }
2635
2636         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
2637         pSMB->TotalDataCount = 0;
2638         pSMB->MaxParameterCount = cpu_to_le16(2);
2639         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2640         pSMB->MaxSetupCount = 0;
2641         pSMB->Reserved = 0;
2642         pSMB->Flags = 0;
2643         pSMB->Timeout = 0;
2644         pSMB->Reserved2 = 0;
2645         pSMB->ParameterOffset = cpu_to_le16(offsetof(
2646         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2647         pSMB->DataCount = 0;
2648         pSMB->DataOffset = 0;
2649         pSMB->SetupCount = 1;
2650         pSMB->Reserved3 = 0;
2651         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2652         byte_count = params + 1 /* pad */ ;
2653         pSMB->TotalParameterCount = cpu_to_le16(params);
2654         pSMB->ParameterCount = pSMB->TotalParameterCount;
2655         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2656         pSMB->Reserved4 = 0;
2657         inc_rfc1001_len(pSMB, byte_count);
2658         pSMB->ByteCount = cpu_to_le16(byte_count);
2659
2660         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2661                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2662         if (rc) {
2663                 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2664         } else {
2665                 /* decode response */
2666
2667                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2668                 /* BB also check enough total bytes returned */
2669                 if (rc || get_bcc(&pSMBr->hdr) < 2)
2670                         rc = -EIO;
2671                 else {
2672                         bool is_unicode;
2673                         u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2674
2675                         data_start = ((char *) &pSMBr->hdr.Protocol) +
2676                                            le16_to_cpu(pSMBr->t2.DataOffset);
2677
2678                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2679                                 is_unicode = true;
2680                         else
2681                                 is_unicode = false;
2682
2683                         /* BB FIXME investigate remapping reserved chars here */
2684                         *symlinkinfo = cifs_strndup_from_utf16(data_start,
2685                                         count, is_unicode, nls_codepage);
2686                         if (!*symlinkinfo)
2687                                 rc = -ENOMEM;
2688                 }
2689         }
2690         cifs_buf_release(pSMB);
2691         if (rc == -EAGAIN)
2692                 goto querySymLinkRetry;
2693         return rc;
2694 }
2695
2696 int cifs_query_reparse_point(const unsigned int xid,
2697                              struct cifs_tcon *tcon,
2698                              struct cifs_sb_info *cifs_sb,
2699                              const char *full_path,
2700                              u32 *tag, struct kvec *rsp,
2701                              int *rsp_buftype)
2702 {
2703         struct reparse_data_buffer *buf;
2704         struct cifs_open_parms oparms;
2705         TRANSACT_IOCTL_REQ *io_req = NULL;
2706         TRANSACT_IOCTL_RSP *io_rsp = NULL;
2707         struct cifs_fid fid;
2708         __u32 data_offset, data_count, len;
2709         __u8 *start, *end;
2710         int io_rsp_len;
2711         int oplock = 0;
2712         int rc;
2713
2714         cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
2715
2716         if (cap_unix(tcon->ses))
2717                 return -EOPNOTSUPP;
2718
2719         oparms = (struct cifs_open_parms) {
2720                 .tcon = tcon,
2721                 .cifs_sb = cifs_sb,
2722                 .desired_access = FILE_READ_ATTRIBUTES,
2723                 .create_options = cifs_create_options(cifs_sb,
2724                                                       OPEN_REPARSE_POINT),
2725                 .disposition = FILE_OPEN,
2726                 .path = full_path,
2727                 .fid = &fid,
2728         };
2729
2730         rc = CIFS_open(xid, &oparms, &oplock, NULL);
2731         if (rc)
2732                 return rc;
2733
2734         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
2735                       (void **)&io_req, (void **)&io_rsp);
2736         if (rc)
2737                 goto error;
2738
2739         io_req->TotalParameterCount = 0;
2740         io_req->TotalDataCount = 0;
2741         io_req->MaxParameterCount = cpu_to_le32(2);
2742         /* BB find exact data count max from sess structure BB */
2743         io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2744         io_req->MaxSetupCount = 4;
2745         io_req->Reserved = 0;
2746         io_req->ParameterOffset = 0;
2747         io_req->DataCount = 0;
2748         io_req->DataOffset = 0;
2749         io_req->SetupCount = 4;
2750         io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2751         io_req->ParameterCount = io_req->TotalParameterCount;
2752         io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2753         io_req->IsFsctl = 1;
2754         io_req->IsRootFlag = 0;
2755         io_req->Fid = fid.netfid;
2756         io_req->ByteCount = 0;
2757
2758         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req,
2759                          (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
2760         if (rc)
2761                 goto error;
2762
2763         data_offset = le32_to_cpu(io_rsp->DataOffset);
2764         data_count = le32_to_cpu(io_rsp->DataCount);
2765         if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
2766             !data_count || data_count > 2048) {
2767                 rc = -EIO;
2768                 goto error;
2769         }
2770
2771         end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
2772         start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
2773         if (start >= end) {
2774                 rc = -EIO;
2775                 goto error;
2776         }
2777
2778         data_count = le16_to_cpu(io_rsp->ByteCount);
2779         buf = (struct reparse_data_buffer *)start;
2780         len = sizeof(*buf);
2781         if (data_count < len ||
2782             data_count < le16_to_cpu(buf->ReparseDataLength) + len) {
2783                 rc = -EIO;
2784                 goto error;
2785         }
2786
2787         *tag = le32_to_cpu(buf->ReparseTag);
2788         rsp->iov_base = io_rsp;
2789         rsp->iov_len = io_rsp_len;
2790         *rsp_buftype = CIFS_LARGE_BUFFER;
2791         CIFSSMBClose(xid, tcon, fid.netfid);
2792         return 0;
2793
2794 error:
2795         cifs_buf_release(io_req);
2796         CIFSSMBClose(xid, tcon, fid.netfid);
2797         return rc;
2798 }
2799
2800 int
2801 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2802                     __u16 fid)
2803 {
2804         int rc = 0;
2805         int bytes_returned;
2806         struct smb_com_transaction_compr_ioctl_req *pSMB;
2807         struct smb_com_transaction_ioctl_rsp *pSMBr;
2808
2809         cifs_dbg(FYI, "Set compression for %u\n", fid);
2810         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2811                       (void **) &pSMBr);
2812         if (rc)
2813                 return rc;
2814
2815         pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2816
2817         pSMB->TotalParameterCount = 0;
2818         pSMB->TotalDataCount = cpu_to_le32(2);
2819         pSMB->MaxParameterCount = 0;
2820         pSMB->MaxDataCount = 0;
2821         pSMB->MaxSetupCount = 4;
2822         pSMB->Reserved = 0;
2823         pSMB->ParameterOffset = 0;
2824         pSMB->DataCount = cpu_to_le32(2);
2825         pSMB->DataOffset =
2826                 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2827                                 compression_state) - 4);  /* 84 */
2828         pSMB->SetupCount = 4;
2829         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2830         pSMB->ParameterCount = 0;
2831         pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2832         pSMB->IsFsctl = 1; /* FSCTL */
2833         pSMB->IsRootFlag = 0;
2834         pSMB->Fid = fid; /* file handle always le */
2835         /* 3 byte pad, followed by 2 byte compress state */
2836         pSMB->ByteCount = cpu_to_le16(5);
2837         inc_rfc1001_len(pSMB, 5);
2838
2839         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2840                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2841         if (rc)
2842                 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2843
2844         cifs_buf_release(pSMB);
2845
2846         /*
2847          * Note: On -EAGAIN error only caller can retry on handle based calls
2848          * since file handle passed in no longer valid.
2849          */
2850         return rc;
2851 }
2852
2853
2854 #ifdef CONFIG_CIFS_POSIX
2855
2856 #ifdef CONFIG_FS_POSIX_ACL
2857 /**
2858  * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
2859  * @ace: POSIX ACL entry to store converted ACL into
2860  * @cifs_ace: ACL in cifs format
2861  *
2862  * Convert an Access Control Entry from wire format to local POSIX xattr
2863  * format.
2864  *
2865  * Note that the @cifs_uid member is used to store both {g,u}id_t.
2866  */
2867 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
2868                                 struct cifs_posix_ace *cifs_ace)
2869 {
2870         /* u8 cifs fields do not need le conversion */
2871         ace->e_perm = cifs_ace->cifs_e_perm;
2872         ace->e_tag = cifs_ace->cifs_e_tag;
2873
2874         switch (ace->e_tag) {
2875         case ACL_USER:
2876                 ace->e_uid = make_kuid(&init_user_ns,
2877                                        le64_to_cpu(cifs_ace->cifs_uid));
2878                 break;
2879         case ACL_GROUP:
2880                 ace->e_gid = make_kgid(&init_user_ns,
2881                                        le64_to_cpu(cifs_ace->cifs_uid));
2882                 break;
2883         }
2884         return;
2885 }
2886
2887 /**
2888  * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
2889  * @acl: ACLs returned in POSIX ACL format
2890  * @src: ACLs in cifs format
2891  * @acl_type: type of POSIX ACL requested
2892  * @size_of_data_area: size of SMB we got
2893  *
2894  * This function converts ACLs from cifs format to POSIX ACL format.
2895  * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
2896  * their uapi format is returned.
2897  */
2898 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
2899                              const int acl_type, const int size_of_data_area)
2900 {
2901         int size =  0;
2902         __u16 count;
2903         struct cifs_posix_ace *pACE;
2904         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2905         struct posix_acl *kacl = NULL;
2906         struct posix_acl_entry *pa, *pe;
2907
2908         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2909                 return -EOPNOTSUPP;
2910
2911         if (acl_type == ACL_TYPE_ACCESS) {
2912                 count = le16_to_cpu(cifs_acl->access_entry_count);
2913                 pACE = &cifs_acl->ace_array[0];
2914                 size = sizeof(struct cifs_posix_acl);
2915                 size += sizeof(struct cifs_posix_ace) * count;
2916                 /* check if we would go beyond end of SMB */
2917                 if (size_of_data_area < size) {
2918                         cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2919                                  size_of_data_area, size);
2920                         return -EINVAL;
2921                 }
2922         } else if (acl_type == ACL_TYPE_DEFAULT) {
2923                 count = le16_to_cpu(cifs_acl->access_entry_count);
2924                 size = sizeof(struct cifs_posix_acl);
2925                 size += sizeof(struct cifs_posix_ace) * count;
2926                 /* skip past access ACEs to get to default ACEs */
2927                 pACE = &cifs_acl->ace_array[count];
2928                 count = le16_to_cpu(cifs_acl->default_entry_count);
2929                 size += sizeof(struct cifs_posix_ace) * count;
2930                 /* check if we would go beyond end of SMB */
2931                 if (size_of_data_area < size)
2932                         return -EINVAL;
2933         } else {
2934                 /* illegal type */
2935                 return -EINVAL;
2936         }
2937
2938         /* Allocate number of POSIX ACLs to store in VFS format. */
2939         kacl = posix_acl_alloc(count, GFP_NOFS);
2940         if (!kacl)
2941                 return -ENOMEM;
2942
2943         FOREACH_ACL_ENTRY(pa, kacl, pe) {
2944                 cifs_init_posix_acl(pa, pACE);
2945                 pACE++;
2946         }
2947
2948         *acl = kacl;
2949         return 0;
2950 }
2951
2952 /**
2953  * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
2954  * @cifs_ace: the cifs ACL entry to store into
2955  * @local_ace: the POSIX ACL entry to convert
2956  */
2957 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
2958                           const struct posix_acl_entry *local_ace)
2959 {
2960         cifs_ace->cifs_e_perm = local_ace->e_perm;
2961         cifs_ace->cifs_e_tag =  local_ace->e_tag;
2962
2963         switch (local_ace->e_tag) {
2964         case ACL_USER:
2965                 cifs_ace->cifs_uid =
2966                         cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
2967                 break;
2968         case ACL_GROUP:
2969                 cifs_ace->cifs_uid =
2970                         cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
2971                 break;
2972         default:
2973                 cifs_ace->cifs_uid = cpu_to_le64(-1);
2974         }
2975 }
2976
2977 /**
2978  * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
2979  * @parm_data: ACLs in cifs format to conver to
2980  * @acl: ACLs in POSIX ACL format to convert from
2981  * @acl_type: the type of POSIX ACLs stored in @acl
2982  *
2983  * Return: the number cifs ACL entries after conversion
2984  */
2985 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
2986                                const int acl_type)
2987 {
2988         __u16 rc = 0;
2989         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2990         const struct posix_acl_entry *pa, *pe;
2991         int count;
2992         int i = 0;
2993
2994         if ((acl == NULL) || (cifs_acl == NULL))
2995                 return 0;
2996
2997         count = acl->a_count;
2998         cifs_dbg(FYI, "setting acl with %d entries\n", count);
2999
3000         /*
3001          * Note that the uapi POSIX ACL version is verified by the VFS and is
3002          * independent of the cifs ACL version. Changing the POSIX ACL version
3003          * is a uapi change and if it's changed we will pass down the POSIX ACL
3004          * version in struct posix_acl from the VFS. For now there's really
3005          * only one that all filesystems know how to deal with.
3006          */
3007         cifs_acl->version = cpu_to_le16(1);
3008         if (acl_type == ACL_TYPE_ACCESS) {
3009                 cifs_acl->access_entry_count = cpu_to_le16(count);
3010                 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3011         } else if (acl_type == ACL_TYPE_DEFAULT) {
3012                 cifs_acl->default_entry_count = cpu_to_le16(count);
3013                 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3014         } else {
3015                 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3016                 return 0;
3017         }
3018         FOREACH_ACL_ENTRY(pa, acl, pe) {
3019                 cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3020         }
3021         if (rc == 0) {
3022                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3023                 rc += sizeof(struct cifs_posix_acl);
3024                 /* BB add check to make sure ACL does not overflow SMB */
3025         }
3026         return rc;
3027 }
3028
3029 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3030                     const unsigned char *searchName, struct posix_acl **acl,
3031                     const int acl_type, const struct nls_table *nls_codepage,
3032                     int remap)
3033 {
3034 /* SMB_QUERY_POSIX_ACL */
3035         TRANSACTION2_QPI_REQ *pSMB = NULL;
3036         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3037         int rc = 0;
3038         int bytes_returned;
3039         int name_len;
3040         __u16 params, byte_count;
3041
3042         cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3043
3044 queryAclRetry:
3045         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3046                 (void **) &pSMBr);
3047         if (rc)
3048                 return rc;
3049
3050         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3051                 name_len =
3052                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3053                                            searchName, PATH_MAX, nls_codepage,
3054                                            remap);
3055                 name_len++;     /* trailing null */
3056                 name_len *= 2;
3057                 pSMB->FileName[name_len] = 0;
3058                 pSMB->FileName[name_len+1] = 0;
3059         } else {
3060                 name_len = copy_path_name(pSMB->FileName, searchName);
3061         }
3062
3063         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3064         pSMB->TotalDataCount = 0;
3065         pSMB->MaxParameterCount = cpu_to_le16(2);
3066         /* BB find exact max data count below from sess structure BB */
3067         pSMB->MaxDataCount = cpu_to_le16(4000);
3068         pSMB->MaxSetupCount = 0;
3069         pSMB->Reserved = 0;
3070         pSMB->Flags = 0;
3071         pSMB->Timeout = 0;
3072         pSMB->Reserved2 = 0;
3073         pSMB->ParameterOffset = cpu_to_le16(
3074                 offsetof(struct smb_com_transaction2_qpi_req,
3075                          InformationLevel) - 4);
3076         pSMB->DataCount = 0;
3077         pSMB->DataOffset = 0;
3078         pSMB->SetupCount = 1;
3079         pSMB->Reserved3 = 0;
3080         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3081         byte_count = params + 1 /* pad */ ;
3082         pSMB->TotalParameterCount = cpu_to_le16(params);
3083         pSMB->ParameterCount = pSMB->TotalParameterCount;
3084         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3085         pSMB->Reserved4 = 0;
3086         inc_rfc1001_len(pSMB, byte_count);
3087         pSMB->ByteCount = cpu_to_le16(byte_count);
3088
3089         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3090                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3091         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3092         if (rc) {
3093                 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3094         } else {
3095                 /* decode response */
3096
3097                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3098                 /* BB also check enough total bytes returned */
3099                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3100                         rc = -EIO;      /* bad smb */
3101                 else {
3102                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3103                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3104                         rc = cifs_to_posix_acl(acl,
3105                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3106                                 acl_type, count);
3107                 }
3108         }
3109         cifs_buf_release(pSMB);
3110         /*
3111          * The else branch after SendReceive() doesn't return EAGAIN so if we
3112          * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3113          * here and don't leak POSIX ACLs.
3114          */
3115         if (rc == -EAGAIN)
3116                 goto queryAclRetry;
3117         return rc;
3118 }
3119
3120 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3121                     const unsigned char *fileName, const struct posix_acl *acl,
3122                     const int acl_type, const struct nls_table *nls_codepage,
3123                     int remap)
3124 {
3125         struct smb_com_transaction2_spi_req *pSMB = NULL;
3126         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3127         char *parm_data;
3128         int name_len;
3129         int rc = 0;
3130         int bytes_returned = 0;
3131         __u16 params, byte_count, data_count, param_offset, offset;
3132
3133         cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3134 setAclRetry:
3135         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3136                       (void **) &pSMBr);
3137         if (rc)
3138                 return rc;
3139         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3140                 name_len =
3141                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3142                                            PATH_MAX, nls_codepage, remap);
3143                 name_len++;     /* trailing null */
3144                 name_len *= 2;
3145         } else {
3146                 name_len = copy_path_name(pSMB->FileName, fileName);
3147         }
3148         params = 6 + name_len;
3149         pSMB->MaxParameterCount = cpu_to_le16(2);
3150         /* BB find max SMB size from sess */
3151         pSMB->MaxDataCount = cpu_to_le16(1000);
3152         pSMB->MaxSetupCount = 0;
3153         pSMB->Reserved = 0;
3154         pSMB->Flags = 0;
3155         pSMB->Timeout = 0;
3156         pSMB->Reserved2 = 0;
3157         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3158                                 InformationLevel) - 4;
3159         offset = param_offset + params;
3160         parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset;
3161         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3162
3163         /* convert to on the wire format for POSIX ACL */
3164         data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3165
3166         if (data_count == 0) {
3167                 rc = -EOPNOTSUPP;
3168                 goto setACLerrorExit;
3169         }
3170         pSMB->DataOffset = cpu_to_le16(offset);
3171         pSMB->SetupCount = 1;
3172         pSMB->Reserved3 = 0;
3173         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3174         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3175         byte_count = 3 /* pad */  + params + data_count;
3176         pSMB->DataCount = cpu_to_le16(data_count);
3177         pSMB->TotalDataCount = pSMB->DataCount;
3178         pSMB->ParameterCount = cpu_to_le16(params);
3179         pSMB->TotalParameterCount = pSMB->ParameterCount;
3180         pSMB->Reserved4 = 0;
3181         inc_rfc1001_len(pSMB, byte_count);
3182         pSMB->ByteCount = cpu_to_le16(byte_count);
3183         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3184                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3185         if (rc)
3186                 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3187
3188 setACLerrorExit:
3189         cifs_buf_release(pSMB);
3190         if (rc == -EAGAIN)
3191                 goto setAclRetry;
3192         return rc;
3193 }
3194 #else
3195 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3196                     const unsigned char *searchName, struct posix_acl **acl,
3197                     const int acl_type, const struct nls_table *nls_codepage,
3198                     int remap)
3199 {
3200         return -EOPNOTSUPP;
3201 }
3202
3203 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3204                     const unsigned char *fileName, const struct posix_acl *acl,
3205                     const int acl_type, const struct nls_table *nls_codepage,
3206                     int remap)
3207 {
3208         return -EOPNOTSUPP;
3209 }
3210 #endif /* CONFIG_FS_POSIX_ACL */
3211
3212 int
3213 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3214                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3215 {
3216         int rc = 0;
3217         struct smb_t2_qfi_req *pSMB = NULL;
3218         struct smb_t2_qfi_rsp *pSMBr = NULL;
3219         int bytes_returned;
3220         __u16 params, byte_count;
3221
3222         cifs_dbg(FYI, "In GetExtAttr\n");
3223         if (tcon == NULL)
3224                 return -ENODEV;
3225
3226 GetExtAttrRetry:
3227         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3228                       (void **) &pSMBr);
3229         if (rc)
3230                 return rc;
3231
3232         params = 2 /* level */ + 2 /* fid */;
3233         pSMB->t2.TotalDataCount = 0;
3234         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3235         /* BB find exact max data count below from sess structure BB */
3236         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3237         pSMB->t2.MaxSetupCount = 0;
3238         pSMB->t2.Reserved = 0;
3239         pSMB->t2.Flags = 0;
3240         pSMB->t2.Timeout = 0;
3241         pSMB->t2.Reserved2 = 0;
3242         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3243                                                Fid) - 4);
3244         pSMB->t2.DataCount = 0;
3245         pSMB->t2.DataOffset = 0;
3246         pSMB->t2.SetupCount = 1;
3247         pSMB->t2.Reserved3 = 0;
3248         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3249         byte_count = params + 1 /* pad */ ;
3250         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3251         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3252         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3253         pSMB->Pad = 0;
3254         pSMB->Fid = netfid;
3255         inc_rfc1001_len(pSMB, byte_count);
3256         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3257
3258         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3259                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3260         if (rc) {
3261                 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3262         } else {
3263                 /* decode response */
3264                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3265                 /* BB also check enough total bytes returned */
3266                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3267                         /* If rc should we check for EOPNOSUPP and
3268                            disable the srvino flag? or in caller? */
3269                         rc = -EIO;      /* bad smb */
3270                 else {
3271                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3272                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3273                         struct file_chattr_info *pfinfo;
3274
3275                         if (count != 16) {
3276                                 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3277                                 rc = -EIO;
3278                                 goto GetExtAttrOut;
3279                         }
3280                         pfinfo = (struct file_chattr_info *)
3281                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3282                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3283                         *pMask = le64_to_cpu(pfinfo->mask);
3284                 }
3285         }
3286 GetExtAttrOut:
3287         cifs_buf_release(pSMB);
3288         if (rc == -EAGAIN)
3289                 goto GetExtAttrRetry;
3290         return rc;
3291 }
3292
3293 #endif /* CONFIG_POSIX */
3294
3295 /*
3296  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3297  * all NT TRANSACTS that we init here have total parm and data under about 400
3298  * bytes (to fit in small cifs buffer size), which is the case so far, it
3299  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3300  * returned setup area) and MaxParameterCount (returned parms size) must be set
3301  * by caller
3302  */
3303 static int
3304 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3305                    const int parm_len, struct cifs_tcon *tcon,
3306                    void **ret_buf)
3307 {
3308         int rc;
3309         __u32 temp_offset;
3310         struct smb_com_ntransact_req *pSMB;
3311
3312         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3313                                 (void **)&pSMB);
3314         if (rc)
3315                 return rc;
3316         *ret_buf = (void *)pSMB;
3317         pSMB->Reserved = 0;
3318         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3319         pSMB->TotalDataCount  = 0;
3320         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3321         pSMB->ParameterCount = pSMB->TotalParameterCount;
3322         pSMB->DataCount  = pSMB->TotalDataCount;
3323         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3324                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3325         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3326         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3327         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3328         pSMB->SubCommand = cpu_to_le16(sub_command);
3329         return 0;
3330 }
3331
3332 static int
3333 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3334                    __u32 *pparmlen, __u32 *pdatalen)
3335 {
3336         char *end_of_smb;
3337         __u32 data_count, data_offset, parm_count, parm_offset;
3338         struct smb_com_ntransact_rsp *pSMBr;
3339         u16 bcc;
3340
3341         *pdatalen = 0;
3342         *pparmlen = 0;
3343
3344         if (buf == NULL)
3345                 return -EINVAL;
3346
3347         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3348
3349         bcc = get_bcc(&pSMBr->hdr);
3350         end_of_smb = 2 /* sizeof byte count */ + bcc +
3351                         (char *)&pSMBr->ByteCount;
3352
3353         data_offset = le32_to_cpu(pSMBr->DataOffset);
3354         data_count = le32_to_cpu(pSMBr->DataCount);
3355         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3356         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3357
3358         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3359         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3360
3361         /* should we also check that parm and data areas do not overlap? */
3362         if (*ppparm > end_of_smb) {
3363                 cifs_dbg(FYI, "parms start after end of smb\n");
3364                 return -EINVAL;
3365         } else if (parm_count + *ppparm > end_of_smb) {
3366                 cifs_dbg(FYI, "parm end after end of smb\n");
3367                 return -EINVAL;
3368         } else if (*ppdata > end_of_smb) {
3369                 cifs_dbg(FYI, "data starts after end of smb\n");
3370                 return -EINVAL;
3371         } else if (data_count + *ppdata > end_of_smb) {
3372                 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3373                          *ppdata, data_count, (data_count + *ppdata),
3374                          end_of_smb, pSMBr);
3375                 return -EINVAL;
3376         } else if (parm_count + data_count > bcc) {
3377                 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3378                 return -EINVAL;
3379         }
3380         *pdatalen = data_count;
3381         *pparmlen = parm_count;
3382         return 0;
3383 }
3384
3385 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3386 int
3387 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3388                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3389 {
3390         int rc = 0;
3391         int buf_type = 0;
3392         QUERY_SEC_DESC_REQ *pSMB;
3393         struct kvec iov[1];
3394         struct kvec rsp_iov;
3395
3396         cifs_dbg(FYI, "GetCifsACL\n");
3397
3398         *pbuflen = 0;
3399         *acl_inf = NULL;
3400
3401         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3402                         8 /* parm len */, tcon, (void **) &pSMB);
3403         if (rc)
3404                 return rc;
3405
3406         pSMB->MaxParameterCount = cpu_to_le32(4);
3407         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3408         pSMB->MaxSetupCount = 0;
3409         pSMB->Fid = fid; /* file handle always le */
3410         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3411                                      CIFS_ACL_DACL);
3412         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3413         inc_rfc1001_len(pSMB, 11);
3414         iov[0].iov_base = (char *)pSMB;
3415         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3416
3417         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3418                           0, &rsp_iov);
3419         cifs_small_buf_release(pSMB);
3420         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3421         if (rc) {
3422                 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3423         } else {                /* decode response */
3424                 __le32 *parm;
3425                 __u32 parm_len;
3426                 __u32 acl_len;
3427                 struct smb_com_ntransact_rsp *pSMBr;
3428                 char *pdata;
3429
3430 /* validate_nttransact */
3431                 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3432                                         &pdata, &parm_len, pbuflen);
3433                 if (rc)
3434                         goto qsec_out;
3435                 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3436
3437                 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3438                          pSMBr, parm, *acl_inf);
3439
3440                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3441                         rc = -EIO;      /* bad smb */
3442                         *pbuflen = 0;
3443                         goto qsec_out;
3444                 }
3445
3446 /* BB check that data area is minimum length and as big as acl_len */
3447
3448                 acl_len = le32_to_cpu(*parm);
3449                 if (acl_len != *pbuflen) {
3450                         cifs_dbg(VFS, "acl length %d does not match %d\n",
3451                                  acl_len, *pbuflen);
3452                         if (*pbuflen > acl_len)
3453                                 *pbuflen = acl_len;
3454                 }
3455
3456                 /* check if buffer is big enough for the acl
3457                    header followed by the smallest SID */
3458                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3459                     (*pbuflen >= 64 * 1024)) {
3460                         cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3461                         rc = -EINVAL;
3462                         *pbuflen = 0;
3463                 } else {
3464                         *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3465                         if (*acl_inf == NULL) {
3466                                 *pbuflen = 0;
3467                                 rc = -ENOMEM;
3468                         }
3469                 }
3470         }
3471 qsec_out:
3472         free_rsp_buf(buf_type, rsp_iov.iov_base);
3473         return rc;
3474 }
3475
3476 int
3477 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3478                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3479 {
3480         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3481         int rc = 0;
3482         int bytes_returned = 0;
3483         SET_SEC_DESC_REQ *pSMB = NULL;
3484         void *pSMBr;
3485
3486 setCifsAclRetry:
3487         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3488         if (rc)
3489                 return rc;
3490
3491         pSMB->MaxSetupCount = 0;
3492         pSMB->Reserved = 0;
3493
3494         param_count = 8;
3495         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3496         data_count = acllen;
3497         data_offset = param_offset + param_count;
3498         byte_count = 3 /* pad */  + param_count;
3499
3500         pSMB->DataCount = cpu_to_le32(data_count);
3501         pSMB->TotalDataCount = pSMB->DataCount;
3502         pSMB->MaxParameterCount = cpu_to_le32(4);
3503         pSMB->MaxDataCount = cpu_to_le32(16384);
3504         pSMB->ParameterCount = cpu_to_le32(param_count);
3505         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3506         pSMB->TotalParameterCount = pSMB->ParameterCount;
3507         pSMB->DataOffset = cpu_to_le32(data_offset);
3508         pSMB->SetupCount = 0;
3509         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3510         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3511
3512         pSMB->Fid = fid; /* file handle always le */
3513         pSMB->Reserved2 = 0;
3514         pSMB->AclFlags = cpu_to_le32(aclflag);
3515
3516         if (pntsd && acllen) {
3517                 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3518                                 data_offset, pntsd, acllen);
3519                 inc_rfc1001_len(pSMB, byte_count + data_count);
3520         } else
3521                 inc_rfc1001_len(pSMB, byte_count);
3522
3523         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3524                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3525
3526         cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3527                  bytes_returned, rc);
3528         if (rc)
3529                 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3530         cifs_buf_release(pSMB);
3531
3532         if (rc == -EAGAIN)
3533                 goto setCifsAclRetry;
3534
3535         return (rc);
3536 }
3537
3538
3539 /* Legacy Query Path Information call for lookup to old servers such
3540    as Win9x/WinME */
3541 int
3542 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3543                     const char *search_name, FILE_ALL_INFO *data,
3544                     const struct nls_table *nls_codepage, int remap)
3545 {
3546         QUERY_INFORMATION_REQ *pSMB;
3547         QUERY_INFORMATION_RSP *pSMBr;
3548         int rc = 0;
3549         int bytes_returned;
3550         int name_len;
3551
3552         cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3553 QInfRetry:
3554         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3555                       (void **) &pSMBr);
3556         if (rc)
3557                 return rc;
3558
3559         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3560                 name_len =
3561                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3562                                            search_name, PATH_MAX, nls_codepage,
3563                                            remap);
3564                 name_len++;     /* trailing null */
3565                 name_len *= 2;
3566         } else {
3567                 name_len = copy_path_name(pSMB->FileName, search_name);
3568         }
3569         pSMB->BufferFormat = 0x04;
3570         name_len++; /* account for buffer type byte */
3571         inc_rfc1001_len(pSMB, (__u16)name_len);
3572         pSMB->ByteCount = cpu_to_le16(name_len);
3573
3574         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3575                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3576         if (rc) {
3577                 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3578         } else if (data) {
3579                 struct timespec64 ts;
3580                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3581
3582                 /* decode response */
3583                 /* BB FIXME - add time zone adjustment BB */
3584                 memset(data, 0, sizeof(FILE_ALL_INFO));
3585                 ts.tv_nsec = 0;
3586                 ts.tv_sec = time;
3587                 /* decode time fields */
3588                 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3589                 data->LastWriteTime = data->ChangeTime;
3590                 data->LastAccessTime = 0;
3591                 data->AllocationSize =
3592                         cpu_to_le64(le32_to_cpu(pSMBr->size));
3593                 data->EndOfFile = data->AllocationSize;
3594                 data->Attributes =
3595                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
3596         } else
3597                 rc = -EIO; /* bad buffer passed in */
3598
3599         cifs_buf_release(pSMB);
3600
3601         if (rc == -EAGAIN)
3602                 goto QInfRetry;
3603
3604         return rc;
3605 }
3606
3607 int
3608 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3609                  u16 netfid, FILE_ALL_INFO *pFindData)
3610 {
3611         struct smb_t2_qfi_req *pSMB = NULL;
3612         struct smb_t2_qfi_rsp *pSMBr = NULL;
3613         int rc = 0;
3614         int bytes_returned;
3615         __u16 params, byte_count;
3616
3617 QFileInfoRetry:
3618         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3619                       (void **) &pSMBr);
3620         if (rc)
3621                 return rc;
3622
3623         params = 2 /* level */ + 2 /* fid */;
3624         pSMB->t2.TotalDataCount = 0;
3625         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3626         /* BB find exact max data count below from sess structure BB */
3627         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3628         pSMB->t2.MaxSetupCount = 0;
3629         pSMB->t2.Reserved = 0;
3630         pSMB->t2.Flags = 0;
3631         pSMB->t2.Timeout = 0;
3632         pSMB->t2.Reserved2 = 0;
3633         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3634                                                Fid) - 4);
3635         pSMB->t2.DataCount = 0;
3636         pSMB->t2.DataOffset = 0;
3637         pSMB->t2.SetupCount = 1;
3638         pSMB->t2.Reserved3 = 0;
3639         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3640         byte_count = params + 1 /* pad */ ;
3641         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3642         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3643         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3644         pSMB->Pad = 0;
3645         pSMB->Fid = netfid;
3646         inc_rfc1001_len(pSMB, byte_count);
3647         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3648
3649         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3650                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3651         if (rc) {
3652                 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3653         } else {                /* decode response */
3654                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3655
3656                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3657                         rc = -EIO;
3658                 else if (get_bcc(&pSMBr->hdr) < 40)
3659                         rc = -EIO;      /* bad smb */
3660                 else if (pFindData) {
3661                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3662                         memcpy((char *) pFindData,
3663                                (char *) &pSMBr->hdr.Protocol +
3664                                data_offset, sizeof(FILE_ALL_INFO));
3665                 } else
3666                     rc = -ENOMEM;
3667         }
3668         cifs_buf_release(pSMB);
3669         if (rc == -EAGAIN)
3670                 goto QFileInfoRetry;
3671
3672         return rc;
3673 }
3674
3675 int
3676 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3677                  const char *search_name, FILE_ALL_INFO *data,
3678                  int legacy /* old style infolevel */,
3679                  const struct nls_table *nls_codepage, int remap)
3680 {
3681         /* level 263 SMB_QUERY_FILE_ALL_INFO */
3682         TRANSACTION2_QPI_REQ *pSMB = NULL;
3683         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3684         int rc = 0;
3685         int bytes_returned;
3686         int name_len;
3687         __u16 params, byte_count;
3688
3689         /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3690 QPathInfoRetry:
3691         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3692                       (void **) &pSMBr);
3693         if (rc)
3694                 return rc;
3695
3696         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3697                 name_len =
3698                     cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3699                                        PATH_MAX, nls_codepage, remap);
3700                 name_len++;     /* trailing null */
3701                 name_len *= 2;
3702         } else {
3703                 name_len = copy_path_name(pSMB->FileName, search_name);
3704         }
3705
3706         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3707         pSMB->TotalDataCount = 0;
3708         pSMB->MaxParameterCount = cpu_to_le16(2);
3709         /* BB find exact max SMB PDU from sess structure BB */
3710         pSMB->MaxDataCount = cpu_to_le16(4000);
3711         pSMB->MaxSetupCount = 0;
3712         pSMB->Reserved = 0;
3713         pSMB->Flags = 0;
3714         pSMB->Timeout = 0;
3715         pSMB->Reserved2 = 0;
3716         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3717         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3718         pSMB->DataCount = 0;
3719         pSMB->DataOffset = 0;
3720         pSMB->SetupCount = 1;
3721         pSMB->Reserved3 = 0;
3722         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3723         byte_count = params + 1 /* pad */ ;
3724         pSMB->TotalParameterCount = cpu_to_le16(params);
3725         pSMB->ParameterCount = pSMB->TotalParameterCount;
3726         if (legacy)
3727                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3728         else
3729                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3730         pSMB->Reserved4 = 0;
3731         inc_rfc1001_len(pSMB, byte_count);
3732         pSMB->ByteCount = cpu_to_le16(byte_count);
3733
3734         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3735                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3736         if (rc) {
3737                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3738         } else {                /* decode response */
3739                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3740
3741                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3742                         rc = -EIO;
3743                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3744                         rc = -EIO;      /* bad smb */
3745                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3746                         rc = -EIO;  /* 24 or 26 expected but we do not read
3747                                         last field */
3748                 else if (data) {
3749                         int size;
3750                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3751
3752                         /*
3753                          * On legacy responses we do not read the last field,
3754                          * EAsize, fortunately since it varies by subdialect and
3755                          * also note it differs on Set vs Get, ie two bytes or 4
3756                          * bytes depending but we don't care here.
3757                          */
3758                         if (legacy)
3759                                 size = sizeof(FILE_INFO_STANDARD);
3760                         else
3761                                 size = sizeof(FILE_ALL_INFO);
3762                         memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3763                                data_offset, size);
3764                 } else
3765                     rc = -ENOMEM;
3766         }
3767         cifs_buf_release(pSMB);
3768         if (rc == -EAGAIN)
3769                 goto QPathInfoRetry;
3770
3771         return rc;
3772 }
3773
3774 int
3775 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3776                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3777 {
3778         struct smb_t2_qfi_req *pSMB = NULL;
3779         struct smb_t2_qfi_rsp *pSMBr = NULL;
3780         int rc = 0;
3781         int bytes_returned;
3782         __u16 params, byte_count;
3783
3784 UnixQFileInfoRetry:
3785         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3786                       (void **) &pSMBr);
3787         if (rc)
3788                 return rc;
3789
3790         params = 2 /* level */ + 2 /* fid */;
3791         pSMB->t2.TotalDataCount = 0;
3792         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3793         /* BB find exact max data count below from sess structure BB */
3794         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3795         pSMB->t2.MaxSetupCount = 0;
3796         pSMB->t2.Reserved = 0;
3797         pSMB->t2.Flags = 0;
3798         pSMB->t2.Timeout = 0;
3799         pSMB->t2.Reserved2 = 0;
3800         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3801                                                Fid) - 4);
3802         pSMB->t2.DataCount = 0;
3803         pSMB->t2.DataOffset = 0;
3804         pSMB->t2.SetupCount = 1;
3805         pSMB->t2.Reserved3 = 0;
3806         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3807         byte_count = params + 1 /* pad */ ;
3808         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3809         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3810         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3811         pSMB->Pad = 0;
3812         pSMB->Fid = netfid;
3813         inc_rfc1001_len(pSMB, byte_count);
3814         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3815
3816         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3817                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3818         if (rc) {
3819                 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3820         } else {                /* decode response */
3821                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3822
3823                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3824                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3825                         rc = -EIO;      /* bad smb */
3826                 } else {
3827                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3828                         memcpy((char *) pFindData,
3829                                (char *) &pSMBr->hdr.Protocol +
3830                                data_offset,
3831                                sizeof(FILE_UNIX_BASIC_INFO));
3832                 }
3833         }
3834
3835         cifs_buf_release(pSMB);
3836         if (rc == -EAGAIN)
3837                 goto UnixQFileInfoRetry;
3838
3839         return rc;
3840 }
3841
3842 int
3843 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3844                      const unsigned char *searchName,
3845                      FILE_UNIX_BASIC_INFO *pFindData,
3846                      const struct nls_table *nls_codepage, int remap)
3847 {
3848 /* SMB_QUERY_FILE_UNIX_BASIC */
3849         TRANSACTION2_QPI_REQ *pSMB = NULL;
3850         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3851         int rc = 0;
3852         int bytes_returned = 0;
3853         int name_len;
3854         __u16 params, byte_count;
3855
3856         cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3857 UnixQPathInfoRetry:
3858         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3859                       (void **) &pSMBr);
3860         if (rc)
3861                 return rc;
3862
3863         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3864                 name_len =
3865                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3866                                        PATH_MAX, nls_codepage, remap);
3867                 name_len++;     /* trailing null */
3868                 name_len *= 2;
3869         } else {
3870                 name_len = copy_path_name(pSMB->FileName, searchName);
3871         }
3872
3873         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3874         pSMB->TotalDataCount = 0;
3875         pSMB->MaxParameterCount = cpu_to_le16(2);
3876         /* BB find exact max SMB PDU from sess structure BB */
3877         pSMB->MaxDataCount = cpu_to_le16(4000);
3878         pSMB->MaxSetupCount = 0;
3879         pSMB->Reserved = 0;
3880         pSMB->Flags = 0;
3881         pSMB->Timeout = 0;
3882         pSMB->Reserved2 = 0;
3883         pSMB->ParameterOffset = cpu_to_le16(offsetof(
3884         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3885         pSMB->DataCount = 0;
3886         pSMB->DataOffset = 0;
3887         pSMB->SetupCount = 1;
3888         pSMB->Reserved3 = 0;
3889         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3890         byte_count = params + 1 /* pad */ ;
3891         pSMB->TotalParameterCount = cpu_to_le16(params);
3892         pSMB->ParameterCount = pSMB->TotalParameterCount;
3893         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3894         pSMB->Reserved4 = 0;
3895         inc_rfc1001_len(pSMB, byte_count);
3896         pSMB->ByteCount = cpu_to_le16(byte_count);
3897
3898         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3899                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3900         if (rc) {
3901                 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3902         } else {                /* decode response */
3903                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3904
3905                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3906                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3907                         rc = -EIO;      /* bad smb */
3908                 } else {
3909                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3910                         memcpy((char *) pFindData,
3911                                (char *) &pSMBr->hdr.Protocol +
3912                                data_offset,
3913                                sizeof(FILE_UNIX_BASIC_INFO));
3914                 }
3915         }
3916         cifs_buf_release(pSMB);
3917         if (rc == -EAGAIN)
3918                 goto UnixQPathInfoRetry;
3919
3920         return rc;
3921 }
3922
3923 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3924 int
3925 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3926               const char *searchName, struct cifs_sb_info *cifs_sb,
3927               __u16 *pnetfid, __u16 search_flags,
3928               struct cifs_search_info *psrch_inf, bool msearch)
3929 {
3930 /* level 257 SMB_ */
3931         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3932         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3933         T2_FFIRST_RSP_PARMS *parms;
3934         struct nls_table *nls_codepage;
3935         unsigned int lnoff;
3936         __u16 params, byte_count;
3937         int bytes_returned = 0;
3938         int name_len, remap;
3939         int rc = 0;
3940
3941         cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3942
3943 findFirstRetry:
3944         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3945                       (void **) &pSMBr);
3946         if (rc)
3947                 return rc;
3948
3949         nls_codepage = cifs_sb->local_nls;
3950         remap = cifs_remap(cifs_sb);
3951
3952         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3953                 name_len =
3954                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3955                                        PATH_MAX, nls_codepage, remap);
3956                 /* We can not add the asterik earlier in case
3957                 it got remapped to 0xF03A as if it were part of the
3958                 directory name instead of a wildcard */
3959                 name_len *= 2;
3960                 if (msearch) {
3961                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3962                         pSMB->FileName[name_len+1] = 0;
3963                         pSMB->FileName[name_len+2] = '*';
3964                         pSMB->FileName[name_len+3] = 0;
3965                         name_len += 4; /* now the trailing null */
3966                         /* null terminate just in case */
3967                         pSMB->FileName[name_len] = 0;
3968                         pSMB->FileName[name_len+1] = 0;
3969                         name_len += 2;
3970                 }
3971         } else {
3972                 name_len = copy_path_name(pSMB->FileName, searchName);
3973                 if (msearch) {
3974                         if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3975                                 name_len = PATH_MAX-2;
3976                         /* overwrite nul byte */
3977                         pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3978                         pSMB->FileName[name_len] = '*';
3979                         pSMB->FileName[name_len+1] = 0;
3980                         name_len += 2;
3981                 }
3982         }
3983
3984         params = 12 + name_len /* includes null */ ;
3985         pSMB->TotalDataCount = 0;       /* no EAs */
3986         pSMB->MaxParameterCount = cpu_to_le16(10);
3987         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
3988         pSMB->MaxSetupCount = 0;
3989         pSMB->Reserved = 0;
3990         pSMB->Flags = 0;
3991         pSMB->Timeout = 0;
3992         pSMB->Reserved2 = 0;
3993         byte_count = params + 1 /* pad */ ;
3994         pSMB->TotalParameterCount = cpu_to_le16(params);
3995         pSMB->ParameterCount = pSMB->TotalParameterCount;
3996         pSMB->ParameterOffset = cpu_to_le16(
3997               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3998                 - 4);
3999         pSMB->DataCount = 0;
4000         pSMB->DataOffset = 0;
4001         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4002         pSMB->Reserved3 = 0;
4003         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4004         pSMB->SearchAttributes =
4005             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4006                         ATTR_DIRECTORY);
4007         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4008         pSMB->SearchFlags = cpu_to_le16(search_flags);
4009         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4010
4011         /* BB what should we set StorageType to? Does it matter? BB */
4012         pSMB->SearchStorageType = 0;
4013         inc_rfc1001_len(pSMB, byte_count);
4014         pSMB->ByteCount = cpu_to_le16(byte_count);
4015
4016         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4017                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4018         cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4019
4020         if (rc) {
4021                 /*
4022                  * BB: add logic to retry regular search if Unix search rejected
4023                  * unexpectedly by server.
4024                  */
4025                 /* BB: add code to handle unsupported level rc */
4026                 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4027                 cifs_buf_release(pSMB);
4028                 /*
4029                  * BB: eventually could optimize out free and realloc of buf for
4030                  * this case.
4031                  */
4032                 if (rc == -EAGAIN)
4033                         goto findFirstRetry;
4034                 return rc;
4035         }
4036         /* decode response */
4037         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4038         if (rc) {
4039                 cifs_buf_release(pSMB);
4040                 return rc;
4041         }
4042
4043         psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4044         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4045         psrch_inf->smallBuf = false;
4046         psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol +
4047                 le16_to_cpu(pSMBr->t2.DataOffset);
4048
4049         parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol +
4050                                         le16_to_cpu(pSMBr->t2.ParameterOffset));
4051         psrch_inf->endOfSearch = !!parms->EndofSearch;
4052
4053         psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4054         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4055                 psrch_inf->entries_in_buffer;
4056         lnoff = le16_to_cpu(parms->LastNameOffset);
4057         if (CIFSMaxBufSize < lnoff) {
4058                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4059                 psrch_inf->last_entry = NULL;
4060         } else {
4061                 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff;
4062                 if (pnetfid)
4063                         *pnetfid = parms->SearchHandle;
4064         }
4065         return 0;
4066 }
4067
4068 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4069                  __u16 searchHandle, __u16 search_flags,
4070                  struct cifs_search_info *psrch_inf)
4071 {
4072         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4073         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4074         T2_FNEXT_RSP_PARMS *parms;
4075         unsigned int name_len;
4076         unsigned int lnoff;
4077         __u16 params, byte_count;
4078         char *response_data;
4079         int bytes_returned;
4080         int rc = 0;
4081
4082         cifs_dbg(FYI, "In FindNext\n");
4083
4084         if (psrch_inf->endOfSearch)
4085                 return -ENOENT;
4086
4087         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4088                 (void **) &pSMBr);
4089         if (rc)
4090                 return rc;
4091
4092         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4093         byte_count = 0;
4094         pSMB->TotalDataCount = 0;       /* no EAs */
4095         pSMB->MaxParameterCount = cpu_to_le16(8);
4096         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4097         pSMB->MaxSetupCount = 0;
4098         pSMB->Reserved = 0;
4099         pSMB->Flags = 0;
4100         pSMB->Timeout = 0;
4101         pSMB->Reserved2 = 0;
4102         pSMB->ParameterOffset =  cpu_to_le16(
4103               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4104         pSMB->DataCount = 0;
4105         pSMB->DataOffset = 0;
4106         pSMB->SetupCount = 1;
4107         pSMB->Reserved3 = 0;
4108         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4109         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4110         pSMB->SearchCount =
4111                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4112         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4113         pSMB->ResumeKey = psrch_inf->resume_key;
4114         pSMB->SearchFlags = cpu_to_le16(search_flags);
4115
4116         name_len = psrch_inf->resume_name_len;
4117         params += name_len;
4118         if (name_len < PATH_MAX) {
4119                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4120                 byte_count += name_len;
4121                 /* 14 byte parm len above enough for 2 byte null terminator */
4122                 pSMB->ResumeFileName[name_len] = 0;
4123                 pSMB->ResumeFileName[name_len+1] = 0;
4124         } else {
4125                 cifs_buf_release(pSMB);
4126                 return -EINVAL;
4127         }
4128         byte_count = params + 1 /* pad */ ;
4129         pSMB->TotalParameterCount = cpu_to_le16(params);
4130         pSMB->ParameterCount = pSMB->TotalParameterCount;
4131         inc_rfc1001_len(pSMB, byte_count);
4132         pSMB->ByteCount = cpu_to_le16(byte_count);
4133
4134         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4135                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4136         cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4137
4138         if (rc) {
4139                 cifs_buf_release(pSMB);
4140                 if (rc == -EBADF) {
4141                         psrch_inf->endOfSearch = true;
4142                         rc = 0; /* search probably was closed at end of search*/
4143                 } else {
4144                         cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4145                 }
4146                 return rc;
4147         }
4148
4149         /* decode response */
4150         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4151         if (rc) {
4152                 cifs_buf_release(pSMB);
4153                 return rc;
4154         }
4155         /* BB fixme add lock for file (srch_info) struct here */
4156         psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4157         response_data = (char *)&pSMBr->hdr.Protocol +
4158                 le16_to_cpu(pSMBr->t2.ParameterOffset);
4159         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4160         response_data = (char *)&pSMBr->hdr.Protocol +
4161                 le16_to_cpu(pSMBr->t2.DataOffset);
4162
4163         if (psrch_inf->smallBuf)
4164                 cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
4165         else
4166                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4167
4168         psrch_inf->srch_entries_start = response_data;
4169         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4170         psrch_inf->smallBuf = false;
4171         psrch_inf->endOfSearch = !!parms->EndofSearch;
4172         psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4173         psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer;
4174         lnoff = le16_to_cpu(parms->LastNameOffset);
4175         if (CIFSMaxBufSize < lnoff) {
4176                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4177                 psrch_inf->last_entry = NULL;
4178         } else {
4179                 psrch_inf->last_entry =
4180                         psrch_inf->srch_entries_start + lnoff;
4181         }
4182         /* BB fixme add unlock here */
4183
4184         /*
4185          * BB: On error, should we leave previous search buf
4186          * (and count and last entry fields) intact or free the previous one?
4187          *
4188          * Note: On -EAGAIN error only caller can retry on handle based calls
4189          * since file handle passed in no longer valid.
4190          */
4191         return 0;
4192 }
4193
4194 int
4195 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4196               const __u16 searchHandle)
4197 {
4198         int rc = 0;
4199         FINDCLOSE_REQ *pSMB = NULL;
4200
4201         cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4202         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4203
4204         /* no sense returning error if session restarted
4205                 as file handle has been closed */
4206         if (rc == -EAGAIN)
4207                 return 0;
4208         if (rc)
4209                 return rc;
4210
4211         pSMB->FileID = searchHandle;
4212         pSMB->ByteCount = 0;
4213         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4214         cifs_small_buf_release(pSMB);
4215         if (rc)
4216                 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4217
4218         cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4219
4220         /* Since session is dead, search handle closed on server already */
4221         if (rc == -EAGAIN)
4222                 rc = 0;
4223
4224         return rc;
4225 }
4226
4227 int
4228 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4229                       const char *search_name, __u64 *inode_number,
4230                       const struct nls_table *nls_codepage, int remap)
4231 {
4232         int rc = 0;
4233         TRANSACTION2_QPI_REQ *pSMB = NULL;
4234         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4235         int name_len, bytes_returned;
4236         __u16 params, byte_count;
4237
4238         cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4239         if (tcon == NULL)
4240                 return -ENODEV;
4241
4242 GetInodeNumberRetry:
4243         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4244                       (void **) &pSMBr);
4245         if (rc)
4246                 return rc;
4247
4248         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4249                 name_len =
4250                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4251                                            search_name, PATH_MAX, nls_codepage,
4252                                            remap);
4253                 name_len++;     /* trailing null */
4254                 name_len *= 2;
4255         } else {
4256                 name_len = copy_path_name(pSMB->FileName, search_name);
4257         }
4258
4259         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4260         pSMB->TotalDataCount = 0;
4261         pSMB->MaxParameterCount = cpu_to_le16(2);
4262         /* BB find exact max data count below from sess structure BB */
4263         pSMB->MaxDataCount = cpu_to_le16(4000);
4264         pSMB->MaxSetupCount = 0;
4265         pSMB->Reserved = 0;
4266         pSMB->Flags = 0;
4267         pSMB->Timeout = 0;
4268         pSMB->Reserved2 = 0;
4269         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4270                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4271         pSMB->DataCount = 0;
4272         pSMB->DataOffset = 0;
4273         pSMB->SetupCount = 1;
4274         pSMB->Reserved3 = 0;
4275         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4276         byte_count = params + 1 /* pad */ ;
4277         pSMB->TotalParameterCount = cpu_to_le16(params);
4278         pSMB->ParameterCount = pSMB->TotalParameterCount;
4279         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4280         pSMB->Reserved4 = 0;
4281         inc_rfc1001_len(pSMB, byte_count);
4282         pSMB->ByteCount = cpu_to_le16(byte_count);
4283
4284         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4285                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4286         if (rc) {
4287                 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4288         } else {
4289                 /* decode response */
4290                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4291                 /* BB also check enough total bytes returned */
4292                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4293                         /* If rc should we check for EOPNOSUPP and
4294                         disable the srvino flag? or in caller? */
4295                         rc = -EIO;      /* bad smb */
4296                 else {
4297                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4298                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4299                         struct file_internal_info *pfinfo;
4300                         /* BB Do we need a cast or hash here ? */
4301                         if (count < 8) {
4302                                 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4303                                 rc = -EIO;
4304                                 goto GetInodeNumOut;
4305                         }
4306                         pfinfo = (struct file_internal_info *)
4307                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4308                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4309                 }
4310         }
4311 GetInodeNumOut:
4312         cifs_buf_release(pSMB);
4313         if (rc == -EAGAIN)
4314                 goto GetInodeNumberRetry;
4315         return rc;
4316 }
4317
4318 int
4319 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4320                 const char *search_name, struct dfs_info3_param **target_nodes,
4321                 unsigned int *num_of_nodes,
4322                 const struct nls_table *nls_codepage, int remap)
4323 {
4324 /* TRANS2_GET_DFS_REFERRAL */
4325         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4326         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4327         int rc = 0;
4328         int bytes_returned;
4329         int name_len;
4330         __u16 params, byte_count;
4331         *num_of_nodes = 0;
4332         *target_nodes = NULL;
4333
4334         cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4335         if (ses == NULL || ses->tcon_ipc == NULL)
4336                 return -ENODEV;
4337
4338 getDFSRetry:
4339         /*
4340          * Use smb_init_no_reconnect() instead of smb_init() as
4341          * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4342          * causing an infinite recursion.
4343          */
4344         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4345                                    (void **)&pSMB, (void **)&pSMBr);
4346         if (rc)
4347                 return rc;
4348
4349         /* server pointer checked in called function,
4350         but should never be null here anyway */
4351         pSMB->hdr.Mid = get_next_mid(ses->server);
4352         pSMB->hdr.Tid = ses->tcon_ipc->tid;
4353         pSMB->hdr.Uid = ses->Suid;
4354         if (ses->capabilities & CAP_STATUS32)
4355                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4356         if (ses->capabilities & CAP_DFS)
4357                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4358
4359         if (ses->capabilities & CAP_UNICODE) {
4360                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4361                 name_len =
4362                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4363                                        search_name, PATH_MAX, nls_codepage,
4364                                        remap);
4365                 name_len++;     /* trailing null */
4366                 name_len *= 2;
4367         } else {        /* BB improve the check for buffer overruns BB */
4368                 name_len = copy_path_name(pSMB->RequestFileName, search_name);
4369         }
4370
4371         if (ses->server->sign)
4372                 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4373
4374         pSMB->hdr.Uid = ses->Suid;
4375
4376         params = 2 /* level */  + name_len /*includes null */ ;
4377         pSMB->TotalDataCount = 0;
4378         pSMB->DataCount = 0;
4379         pSMB->DataOffset = 0;
4380         pSMB->MaxParameterCount = 0;
4381         /* BB find exact max SMB PDU from sess structure BB */
4382         pSMB->MaxDataCount = cpu_to_le16(4000);
4383         pSMB->MaxSetupCount = 0;
4384         pSMB->Reserved = 0;
4385         pSMB->Flags = 0;
4386         pSMB->Timeout = 0;
4387         pSMB->Reserved2 = 0;
4388         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4389           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4390         pSMB->SetupCount = 1;
4391         pSMB->Reserved3 = 0;
4392         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4393         byte_count = params + 3 /* pad */ ;
4394         pSMB->ParameterCount = cpu_to_le16(params);
4395         pSMB->TotalParameterCount = pSMB->ParameterCount;
4396         pSMB->MaxReferralLevel = cpu_to_le16(3);
4397         inc_rfc1001_len(pSMB, byte_count);
4398         pSMB->ByteCount = cpu_to_le16(byte_count);
4399
4400         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4401                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4402         if (rc) {
4403                 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4404                 goto GetDFSRefExit;
4405         }
4406         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4407
4408         /* BB Also check if enough total bytes returned? */
4409         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4410                 rc = -EIO;      /* bad smb */
4411                 goto GetDFSRefExit;
4412         }
4413
4414         cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4415                  get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4416
4417         /* parse returned result into more usable form */
4418         rc = parse_dfs_referrals(&pSMBr->dfs_data,
4419                                  le16_to_cpu(pSMBr->t2.DataCount),
4420                                  num_of_nodes, target_nodes, nls_codepage,
4421                                  remap, search_name,
4422                                  (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4423
4424 GetDFSRefExit:
4425         cifs_buf_release(pSMB);
4426
4427         if (rc == -EAGAIN)
4428                 goto getDFSRetry;
4429
4430         return rc;
4431 }
4432
4433 /* Query File System Info such as free space to old servers such as Win 9x */
4434 int
4435 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4436               struct kstatfs *FSData)
4437 {
4438 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4439         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4440         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4441         FILE_SYSTEM_ALLOC_INFO *response_data;
4442         int rc = 0;
4443         int bytes_returned = 0;
4444         __u16 params, byte_count;
4445
4446         cifs_dbg(FYI, "OldQFSInfo\n");
4447 oldQFSInfoRetry:
4448         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4449                 (void **) &pSMBr);
4450         if (rc)
4451                 return rc;
4452
4453         params = 2;     /* level */
4454         pSMB->TotalDataCount = 0;
4455         pSMB->MaxParameterCount = cpu_to_le16(2);
4456         pSMB->MaxDataCount = cpu_to_le16(1000);
4457         pSMB->MaxSetupCount = 0;
4458         pSMB->Reserved = 0;
4459         pSMB->Flags = 0;
4460         pSMB->Timeout = 0;
4461         pSMB->Reserved2 = 0;
4462         byte_count = params + 1 /* pad */ ;
4463         pSMB->TotalParameterCount = cpu_to_le16(params);
4464         pSMB->ParameterCount = pSMB->TotalParameterCount;
4465         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4466         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4467         pSMB->DataCount = 0;
4468         pSMB->DataOffset = 0;
4469         pSMB->SetupCount = 1;
4470         pSMB->Reserved3 = 0;
4471         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4472         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4473         inc_rfc1001_len(pSMB, byte_count);
4474         pSMB->ByteCount = cpu_to_le16(byte_count);
4475
4476         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4477                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4478         if (rc) {
4479                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4480         } else {                /* decode response */
4481                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4482
4483                 if (rc || get_bcc(&pSMBr->hdr) < 18)
4484                         rc = -EIO;      /* bad smb */
4485                 else {
4486                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4487                         cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
4488                                  get_bcc(&pSMBr->hdr), data_offset);
4489
4490                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
4491                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4492                         FSData->f_bsize =
4493                                 le16_to_cpu(response_data->BytesPerSector) *
4494                                 le32_to_cpu(response_data->
4495                                         SectorsPerAllocationUnit);
4496                         /*
4497                          * much prefer larger but if server doesn't report
4498                          * a valid size than 4K is a reasonable minimum
4499                          */
4500                         if (FSData->f_bsize < 512)
4501                                 FSData->f_bsize = 4096;
4502
4503                         FSData->f_blocks =
4504                                le32_to_cpu(response_data->TotalAllocationUnits);
4505                         FSData->f_bfree = FSData->f_bavail =
4506                                 le32_to_cpu(response_data->FreeAllocationUnits);
4507                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4508                                  (unsigned long long)FSData->f_blocks,
4509                                  (unsigned long long)FSData->f_bfree,
4510                                  FSData->f_bsize);
4511                 }
4512         }
4513         cifs_buf_release(pSMB);
4514
4515         if (rc == -EAGAIN)
4516                 goto oldQFSInfoRetry;
4517
4518         return rc;
4519 }
4520
4521 int
4522 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4523                struct kstatfs *FSData)
4524 {
4525 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4526         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4527         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4528         FILE_SYSTEM_INFO *response_data;
4529         int rc = 0;
4530         int bytes_returned = 0;
4531         __u16 params, byte_count;
4532
4533         cifs_dbg(FYI, "In QFSInfo\n");
4534 QFSInfoRetry:
4535         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4536                       (void **) &pSMBr);
4537         if (rc)
4538                 return rc;
4539
4540         params = 2;     /* level */
4541         pSMB->TotalDataCount = 0;
4542         pSMB->MaxParameterCount = cpu_to_le16(2);
4543         pSMB->MaxDataCount = cpu_to_le16(1000);
4544         pSMB->MaxSetupCount = 0;
4545         pSMB->Reserved = 0;
4546         pSMB->Flags = 0;
4547         pSMB->Timeout = 0;
4548         pSMB->Reserved2 = 0;
4549         byte_count = params + 1 /* pad */ ;
4550         pSMB->TotalParameterCount = cpu_to_le16(params);
4551         pSMB->ParameterCount = pSMB->TotalParameterCount;
4552         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4553                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4554         pSMB->DataCount = 0;
4555         pSMB->DataOffset = 0;
4556         pSMB->SetupCount = 1;
4557         pSMB->Reserved3 = 0;
4558         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4559         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4560         inc_rfc1001_len(pSMB, byte_count);
4561         pSMB->ByteCount = cpu_to_le16(byte_count);
4562
4563         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4564                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4565         if (rc) {
4566                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4567         } else {                /* decode response */
4568                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4569
4570                 if (rc || get_bcc(&pSMBr->hdr) < 24)
4571                         rc = -EIO;      /* bad smb */
4572                 else {
4573                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4574
4575                         response_data =
4576                             (FILE_SYSTEM_INFO
4577                              *) (((char *) &pSMBr->hdr.Protocol) +
4578                                  data_offset);
4579                         FSData->f_bsize =
4580                             le32_to_cpu(response_data->BytesPerSector) *
4581                             le32_to_cpu(response_data->
4582                                         SectorsPerAllocationUnit);
4583                         /*
4584                          * much prefer larger but if server doesn't report
4585                          * a valid size than 4K is a reasonable minimum
4586                          */
4587                         if (FSData->f_bsize < 512)
4588                                 FSData->f_bsize = 4096;
4589
4590                         FSData->f_blocks =
4591                             le64_to_cpu(response_data->TotalAllocationUnits);
4592                         FSData->f_bfree = FSData->f_bavail =
4593                             le64_to_cpu(response_data->FreeAllocationUnits);
4594                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4595                                  (unsigned long long)FSData->f_blocks,
4596                                  (unsigned long long)FSData->f_bfree,
4597                                  FSData->f_bsize);
4598                 }
4599         }
4600         cifs_buf_release(pSMB);
4601
4602         if (rc == -EAGAIN)
4603                 goto QFSInfoRetry;
4604
4605         return rc;
4606 }
4607
4608 int
4609 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4610 {
4611 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
4612         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4613         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4614         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4615         int rc = 0;
4616         int bytes_returned = 0;
4617         __u16 params, byte_count;
4618
4619         cifs_dbg(FYI, "In QFSAttributeInfo\n");
4620 QFSAttributeRetry:
4621         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4622                       (void **) &pSMBr);
4623         if (rc)
4624                 return rc;
4625
4626         params = 2;     /* level */
4627         pSMB->TotalDataCount = 0;
4628         pSMB->MaxParameterCount = cpu_to_le16(2);
4629         /* BB find exact max SMB PDU from sess structure BB */
4630         pSMB->MaxDataCount = cpu_to_le16(1000);
4631         pSMB->MaxSetupCount = 0;
4632         pSMB->Reserved = 0;
4633         pSMB->Flags = 0;
4634         pSMB->Timeout = 0;
4635         pSMB->Reserved2 = 0;
4636         byte_count = params + 1 /* pad */ ;
4637         pSMB->TotalParameterCount = cpu_to_le16(params);
4638         pSMB->ParameterCount = pSMB->TotalParameterCount;
4639         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4640                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4641         pSMB->DataCount = 0;
4642         pSMB->DataOffset = 0;
4643         pSMB->SetupCount = 1;
4644         pSMB->Reserved3 = 0;
4645         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4646         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4647         inc_rfc1001_len(pSMB, byte_count);
4648         pSMB->ByteCount = cpu_to_le16(byte_count);
4649
4650         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4651                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4652         if (rc) {
4653                 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4654         } else {                /* decode response */
4655                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4656
4657                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4658                         /* BB also check if enough bytes returned */
4659                         rc = -EIO;      /* bad smb */
4660                 } else {
4661                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4662                         response_data =
4663                             (FILE_SYSTEM_ATTRIBUTE_INFO
4664                              *) (((char *) &pSMBr->hdr.Protocol) +
4665                                  data_offset);
4666                         memcpy(&tcon->fsAttrInfo, response_data,
4667                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4668                 }
4669         }
4670         cifs_buf_release(pSMB);
4671
4672         if (rc == -EAGAIN)
4673                 goto QFSAttributeRetry;
4674
4675         return rc;
4676 }
4677
4678 int
4679 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4680 {
4681 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4682         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4683         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4684         FILE_SYSTEM_DEVICE_INFO *response_data;
4685         int rc = 0;
4686         int bytes_returned = 0;
4687         __u16 params, byte_count;
4688
4689         cifs_dbg(FYI, "In QFSDeviceInfo\n");
4690 QFSDeviceRetry:
4691         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4692                       (void **) &pSMBr);
4693         if (rc)
4694                 return rc;
4695
4696         params = 2;     /* level */
4697         pSMB->TotalDataCount = 0;
4698         pSMB->MaxParameterCount = cpu_to_le16(2);
4699         /* BB find exact max SMB PDU from sess structure BB */
4700         pSMB->MaxDataCount = cpu_to_le16(1000);
4701         pSMB->MaxSetupCount = 0;
4702         pSMB->Reserved = 0;
4703         pSMB->Flags = 0;
4704         pSMB->Timeout = 0;
4705         pSMB->Reserved2 = 0;
4706         byte_count = params + 1 /* pad */ ;
4707         pSMB->TotalParameterCount = cpu_to_le16(params);
4708         pSMB->ParameterCount = pSMB->TotalParameterCount;
4709         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4710                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4711
4712         pSMB->DataCount = 0;
4713         pSMB->DataOffset = 0;
4714         pSMB->SetupCount = 1;
4715         pSMB->Reserved3 = 0;
4716         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4717         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4718         inc_rfc1001_len(pSMB, byte_count);
4719         pSMB->ByteCount = cpu_to_le16(byte_count);
4720
4721         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4722                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4723         if (rc) {
4724                 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4725         } else {                /* decode response */
4726                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4727
4728                 if (rc || get_bcc(&pSMBr->hdr) <
4729                           sizeof(FILE_SYSTEM_DEVICE_INFO))
4730                         rc = -EIO;      /* bad smb */
4731                 else {
4732                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4733                         response_data =
4734                             (FILE_SYSTEM_DEVICE_INFO *)
4735                                 (((char *) &pSMBr->hdr.Protocol) +
4736                                  data_offset);
4737                         memcpy(&tcon->fsDevInfo, response_data,
4738                                sizeof(FILE_SYSTEM_DEVICE_INFO));
4739                 }
4740         }
4741         cifs_buf_release(pSMB);
4742
4743         if (rc == -EAGAIN)
4744                 goto QFSDeviceRetry;
4745
4746         return rc;
4747 }
4748
4749 int
4750 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4751 {
4752 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
4753         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4754         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4755         FILE_SYSTEM_UNIX_INFO *response_data;
4756         int rc = 0;
4757         int bytes_returned = 0;
4758         __u16 params, byte_count;
4759
4760         cifs_dbg(FYI, "In QFSUnixInfo\n");
4761 QFSUnixRetry:
4762         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4763                                    (void **) &pSMB, (void **) &pSMBr);
4764         if (rc)
4765                 return rc;
4766
4767         params = 2;     /* level */
4768         pSMB->TotalDataCount = 0;
4769         pSMB->DataCount = 0;
4770         pSMB->DataOffset = 0;
4771         pSMB->MaxParameterCount = cpu_to_le16(2);
4772         /* BB find exact max SMB PDU from sess structure BB */
4773         pSMB->MaxDataCount = cpu_to_le16(100);
4774         pSMB->MaxSetupCount = 0;
4775         pSMB->Reserved = 0;
4776         pSMB->Flags = 0;
4777         pSMB->Timeout = 0;
4778         pSMB->Reserved2 = 0;
4779         byte_count = params + 1 /* pad */ ;
4780         pSMB->ParameterCount = cpu_to_le16(params);
4781         pSMB->TotalParameterCount = pSMB->ParameterCount;
4782         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4783                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4784         pSMB->SetupCount = 1;
4785         pSMB->Reserved3 = 0;
4786         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4787         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4788         inc_rfc1001_len(pSMB, byte_count);
4789         pSMB->ByteCount = cpu_to_le16(byte_count);
4790
4791         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4792                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4793         if (rc) {
4794                 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4795         } else {                /* decode response */
4796                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4797
4798                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4799                         rc = -EIO;      /* bad smb */
4800                 } else {
4801                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4802                         response_data =
4803                             (FILE_SYSTEM_UNIX_INFO
4804                              *) (((char *) &pSMBr->hdr.Protocol) +
4805                                  data_offset);
4806                         memcpy(&tcon->fsUnixInfo, response_data,
4807                                sizeof(FILE_SYSTEM_UNIX_INFO));
4808                 }
4809         }
4810         cifs_buf_release(pSMB);
4811
4812         if (rc == -EAGAIN)
4813                 goto QFSUnixRetry;
4814
4815
4816         return rc;
4817 }
4818
4819 int
4820 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4821 {
4822 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
4823         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4824         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4825         int rc = 0;
4826         int bytes_returned = 0;
4827         __u16 params, param_offset, offset, byte_count;
4828
4829         cifs_dbg(FYI, "In SETFSUnixInfo\n");
4830 SETFSUnixRetry:
4831         /* BB switch to small buf init to save memory */
4832         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4833                                         (void **) &pSMB, (void **) &pSMBr);
4834         if (rc)
4835                 return rc;
4836
4837         params = 4;     /* 2 bytes zero followed by info level. */
4838         pSMB->MaxSetupCount = 0;
4839         pSMB->Reserved = 0;
4840         pSMB->Flags = 0;
4841         pSMB->Timeout = 0;
4842         pSMB->Reserved2 = 0;
4843         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4844                                 - 4;
4845         offset = param_offset + params;
4846
4847         pSMB->MaxParameterCount = cpu_to_le16(4);
4848         /* BB find exact max SMB PDU from sess structure BB */
4849         pSMB->MaxDataCount = cpu_to_le16(100);
4850         pSMB->SetupCount = 1;
4851         pSMB->Reserved3 = 0;
4852         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4853         byte_count = 1 /* pad */ + params + 12;
4854
4855         pSMB->DataCount = cpu_to_le16(12);
4856         pSMB->ParameterCount = cpu_to_le16(params);
4857         pSMB->TotalDataCount = pSMB->DataCount;
4858         pSMB->TotalParameterCount = pSMB->ParameterCount;
4859         pSMB->ParameterOffset = cpu_to_le16(param_offset);
4860         pSMB->DataOffset = cpu_to_le16(offset);
4861
4862         /* Params. */
4863         pSMB->FileNum = 0;
4864         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4865
4866         /* Data. */
4867         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4868         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4869         pSMB->ClientUnixCap = cpu_to_le64(cap);
4870
4871         inc_rfc1001_len(pSMB, byte_count);
4872         pSMB->ByteCount = cpu_to_le16(byte_count);
4873
4874         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4875                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4876         if (rc) {
4877                 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4878         } else {                /* decode response */
4879                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4880                 if (rc)
4881                         rc = -EIO;      /* bad smb */
4882         }
4883         cifs_buf_release(pSMB);
4884
4885         if (rc == -EAGAIN)
4886                 goto SETFSUnixRetry;
4887
4888         return rc;
4889 }
4890
4891
4892
4893 int
4894 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4895                    struct kstatfs *FSData)
4896 {
4897 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
4898         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4899         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4900         FILE_SYSTEM_POSIX_INFO *response_data;
4901         int rc = 0;
4902         int bytes_returned = 0;
4903         __u16 params, byte_count;
4904
4905         cifs_dbg(FYI, "In QFSPosixInfo\n");
4906 QFSPosixRetry:
4907         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4908                       (void **) &pSMBr);
4909         if (rc)
4910                 return rc;
4911
4912         params = 2;     /* level */
4913         pSMB->TotalDataCount = 0;
4914         pSMB->DataCount = 0;
4915         pSMB->DataOffset = 0;
4916         pSMB->MaxParameterCount = cpu_to_le16(2);
4917         /* BB find exact max SMB PDU from sess structure BB */
4918         pSMB->MaxDataCount = cpu_to_le16(100);
4919         pSMB->MaxSetupCount = 0;
4920         pSMB->Reserved = 0;
4921         pSMB->Flags = 0;
4922         pSMB->Timeout = 0;
4923         pSMB->Reserved2 = 0;
4924         byte_count = params + 1 /* pad */ ;
4925         pSMB->ParameterCount = cpu_to_le16(params);
4926         pSMB->TotalParameterCount = pSMB->ParameterCount;
4927         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4928                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4929         pSMB->SetupCount = 1;
4930         pSMB->Reserved3 = 0;
4931         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4932         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4933         inc_rfc1001_len(pSMB, byte_count);
4934         pSMB->ByteCount = cpu_to_le16(byte_count);
4935
4936         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4937                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4938         if (rc) {
4939                 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4940         } else {                /* decode response */
4941                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4942
4943                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4944                         rc = -EIO;      /* bad smb */
4945                 } else {
4946                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4947                         response_data =
4948                             (FILE_SYSTEM_POSIX_INFO
4949                              *) (((char *) &pSMBr->hdr.Protocol) +
4950                                  data_offset);
4951                         FSData->f_bsize =
4952                                         le32_to_cpu(response_data->BlockSize);
4953                         /*
4954                          * much prefer larger but if server doesn't report
4955                          * a valid size than 4K is a reasonable minimum
4956                          */
4957                         if (FSData->f_bsize < 512)
4958                                 FSData->f_bsize = 4096;
4959
4960                         FSData->f_blocks =
4961                                         le64_to_cpu(response_data->TotalBlocks);
4962                         FSData->f_bfree =
4963                             le64_to_cpu(response_data->BlocksAvail);
4964                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4965                                 FSData->f_bavail = FSData->f_bfree;
4966                         } else {
4967                                 FSData->f_bavail =
4968                                     le64_to_cpu(response_data->UserBlocksAvail);
4969                         }
4970                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
4971                                 FSData->f_files =
4972                                      le64_to_cpu(response_data->TotalFileNodes);
4973                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
4974                                 FSData->f_ffree =
4975                                       le64_to_cpu(response_data->FreeFileNodes);
4976                 }
4977         }
4978         cifs_buf_release(pSMB);
4979
4980         if (rc == -EAGAIN)
4981                 goto QFSPosixRetry;
4982
4983         return rc;
4984 }
4985
4986
4987 /*
4988  * We can not use write of zero bytes trick to set file size due to need for
4989  * large file support. Also note that this SetPathInfo is preferred to
4990  * SetFileInfo based method in next routine which is only needed to work around
4991  * a sharing violation bugin Samba which this routine can run into.
4992  */
4993 int
4994 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
4995               const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
4996               bool set_allocation, struct dentry *dentry)
4997 {
4998         struct smb_com_transaction2_spi_req *pSMB = NULL;
4999         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5000         struct file_end_of_file_info *parm_data;
5001         int name_len;
5002         int rc = 0;
5003         int bytes_returned = 0;
5004         int remap = cifs_remap(cifs_sb);
5005
5006         __u16 params, byte_count, data_count, param_offset, offset;
5007
5008         cifs_dbg(FYI, "In SetEOF\n");
5009 SetEOFRetry:
5010         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5011                       (void **) &pSMBr);
5012         if (rc)
5013                 return rc;
5014
5015         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5016                 name_len =
5017                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5018                                        PATH_MAX, cifs_sb->local_nls, remap);
5019                 name_len++;     /* trailing null */
5020                 name_len *= 2;
5021         } else {
5022                 name_len = copy_path_name(pSMB->FileName, file_name);
5023         }
5024         params = 6 + name_len;
5025         data_count = sizeof(struct file_end_of_file_info);
5026         pSMB->MaxParameterCount = cpu_to_le16(2);
5027         pSMB->MaxDataCount = cpu_to_le16(4100);
5028         pSMB->MaxSetupCount = 0;
5029         pSMB->Reserved = 0;
5030         pSMB->Flags = 0;
5031         pSMB->Timeout = 0;
5032         pSMB->Reserved2 = 0;
5033         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5034                                 InformationLevel) - 4;
5035         offset = param_offset + params;
5036         if (set_allocation) {
5037                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5038                         pSMB->InformationLevel =
5039                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5040                 else
5041                         pSMB->InformationLevel =
5042                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5043         } else /* Set File Size */  {
5044             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5045                     pSMB->InformationLevel =
5046                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5047             else
5048                     pSMB->InformationLevel =
5049                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5050         }
5051
5052         parm_data =
5053             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5054                                        offset);
5055         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5056         pSMB->DataOffset = cpu_to_le16(offset);
5057         pSMB->SetupCount = 1;
5058         pSMB->Reserved3 = 0;
5059         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5060         byte_count = 3 /* pad */  + params + data_count;
5061         pSMB->DataCount = cpu_to_le16(data_count);
5062         pSMB->TotalDataCount = pSMB->DataCount;
5063         pSMB->ParameterCount = cpu_to_le16(params);
5064         pSMB->TotalParameterCount = pSMB->ParameterCount;
5065         pSMB->Reserved4 = 0;
5066         inc_rfc1001_len(pSMB, byte_count);
5067         parm_data->FileSize = cpu_to_le64(size);
5068         pSMB->ByteCount = cpu_to_le16(byte_count);
5069         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5070                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5071         if (rc)
5072                 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5073
5074         cifs_buf_release(pSMB);
5075
5076         if (rc == -EAGAIN)
5077                 goto SetEOFRetry;
5078
5079         return rc;
5080 }
5081
5082 int
5083 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5084                    struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5085 {
5086         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5087         struct file_end_of_file_info *parm_data;
5088         int rc = 0;
5089         __u16 params, param_offset, offset, byte_count, count;
5090
5091         cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5092                  (long long)size);
5093         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5094
5095         if (rc)
5096                 return rc;
5097
5098         pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5099         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5100
5101         params = 6;
5102         pSMB->MaxSetupCount = 0;
5103         pSMB->Reserved = 0;
5104         pSMB->Flags = 0;
5105         pSMB->Timeout = 0;
5106         pSMB->Reserved2 = 0;
5107         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5108         offset = param_offset + params;
5109
5110         count = sizeof(struct file_end_of_file_info);
5111         pSMB->MaxParameterCount = cpu_to_le16(2);
5112         /* BB find exact max SMB PDU from sess structure BB */
5113         pSMB->MaxDataCount = cpu_to_le16(1000);
5114         pSMB->SetupCount = 1;
5115         pSMB->Reserved3 = 0;
5116         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5117         byte_count = 3 /* pad */  + params + count;
5118         pSMB->DataCount = cpu_to_le16(count);
5119         pSMB->ParameterCount = cpu_to_le16(params);
5120         pSMB->TotalDataCount = pSMB->DataCount;
5121         pSMB->TotalParameterCount = pSMB->ParameterCount;
5122         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5123         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5124         parm_data =
5125                 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5126         pSMB->DataOffset = cpu_to_le16(offset);
5127         parm_data->FileSize = cpu_to_le64(size);
5128         pSMB->Fid = cfile->fid.netfid;
5129         if (set_allocation) {
5130                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5131                         pSMB->InformationLevel =
5132                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5133                 else
5134                         pSMB->InformationLevel =
5135                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5136         } else /* Set File Size */  {
5137             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5138                     pSMB->InformationLevel =
5139                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5140             else
5141                     pSMB->InformationLevel =
5142                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5143         }
5144         pSMB->Reserved4 = 0;
5145         inc_rfc1001_len(pSMB, byte_count);
5146         pSMB->ByteCount = cpu_to_le16(byte_count);
5147         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5148         cifs_small_buf_release(pSMB);
5149         if (rc) {
5150                 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5151                          rc);
5152         }
5153
5154         /* Note: On -EAGAIN error only caller can retry on handle based calls
5155                 since file handle passed in no longer valid */
5156
5157         return rc;
5158 }
5159
5160 /* Some legacy servers such as NT4 require that the file times be set on
5161    an open handle, rather than by pathname - this is awkward due to
5162    potential access conflicts on the open, but it is unavoidable for these
5163    old servers since the only other choice is to go from 100 nanosecond DCE
5164    time and resort to the original setpathinfo level which takes the ancient
5165    DOS time format with 2 second granularity */
5166 int
5167 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5168                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5169 {
5170         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5171         char *data_offset;
5172         int rc = 0;
5173         __u16 params, param_offset, offset, byte_count, count;
5174
5175         cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5176         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5177
5178         if (rc)
5179                 return rc;
5180
5181         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5182         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5183
5184         params = 6;
5185         pSMB->MaxSetupCount = 0;
5186         pSMB->Reserved = 0;
5187         pSMB->Flags = 0;
5188         pSMB->Timeout = 0;
5189         pSMB->Reserved2 = 0;
5190         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5191         offset = param_offset + params;
5192
5193         data_offset = (char *)pSMB +
5194                         offsetof(struct smb_hdr, Protocol) + offset;
5195
5196         count = sizeof(FILE_BASIC_INFO);
5197         pSMB->MaxParameterCount = cpu_to_le16(2);
5198         /* BB find max SMB PDU from sess */
5199         pSMB->MaxDataCount = cpu_to_le16(1000);
5200         pSMB->SetupCount = 1;
5201         pSMB->Reserved3 = 0;
5202         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5203         byte_count = 3 /* pad */  + params + count;
5204         pSMB->DataCount = cpu_to_le16(count);
5205         pSMB->ParameterCount = cpu_to_le16(params);
5206         pSMB->TotalDataCount = pSMB->DataCount;
5207         pSMB->TotalParameterCount = pSMB->ParameterCount;
5208         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5209         pSMB->DataOffset = cpu_to_le16(offset);
5210         pSMB->Fid = fid;
5211         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5212                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5213         else
5214                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5215         pSMB->Reserved4 = 0;
5216         inc_rfc1001_len(pSMB, byte_count);
5217         pSMB->ByteCount = cpu_to_le16(byte_count);
5218         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5219         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5220         cifs_small_buf_release(pSMB);
5221         if (rc)
5222                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5223                          rc);
5224
5225         /* Note: On -EAGAIN error only caller can retry on handle based calls
5226                 since file handle passed in no longer valid */
5227
5228         return rc;
5229 }
5230
5231 int
5232 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5233                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5234 {
5235         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5236         char *data_offset;
5237         int rc = 0;
5238         __u16 params, param_offset, offset, byte_count, count;
5239
5240         cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5241         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5242
5243         if (rc)
5244                 return rc;
5245
5246         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5247         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5248
5249         params = 6;
5250         pSMB->MaxSetupCount = 0;
5251         pSMB->Reserved = 0;
5252         pSMB->Flags = 0;
5253         pSMB->Timeout = 0;
5254         pSMB->Reserved2 = 0;
5255         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5256         offset = param_offset + params;
5257
5258         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5259         data_offset = (char *)(pSMB) + offset + 4;
5260
5261         count = 1;
5262         pSMB->MaxParameterCount = cpu_to_le16(2);
5263         /* BB find max SMB PDU from sess */
5264         pSMB->MaxDataCount = cpu_to_le16(1000);
5265         pSMB->SetupCount = 1;
5266         pSMB->Reserved3 = 0;
5267         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5268         byte_count = 3 /* pad */  + params + count;
5269         pSMB->DataCount = cpu_to_le16(count);
5270         pSMB->ParameterCount = cpu_to_le16(params);
5271         pSMB->TotalDataCount = pSMB->DataCount;
5272         pSMB->TotalParameterCount = pSMB->ParameterCount;
5273         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5274         pSMB->DataOffset = cpu_to_le16(offset);
5275         pSMB->Fid = fid;
5276         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5277         pSMB->Reserved4 = 0;
5278         inc_rfc1001_len(pSMB, byte_count);
5279         pSMB->ByteCount = cpu_to_le16(byte_count);
5280         *data_offset = delete_file ? 1 : 0;
5281         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5282         cifs_small_buf_release(pSMB);
5283         if (rc)
5284                 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5285
5286         return rc;
5287 }
5288
5289 static int
5290 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5291                      const char *fileName, const FILE_BASIC_INFO *data,
5292                      const struct nls_table *nls_codepage,
5293                      struct cifs_sb_info *cifs_sb)
5294 {
5295         int oplock = 0;
5296         struct cifs_open_parms oparms;
5297         struct cifs_fid fid;
5298         int rc;
5299
5300         oparms = (struct cifs_open_parms) {
5301                 .tcon = tcon,
5302                 .cifs_sb = cifs_sb,
5303                 .desired_access = GENERIC_WRITE,
5304                 .create_options = cifs_create_options(cifs_sb, 0),
5305                 .disposition = FILE_OPEN,
5306                 .path = fileName,
5307                 .fid = &fid,
5308         };
5309
5310         rc = CIFS_open(xid, &oparms, &oplock, NULL);
5311         if (rc)
5312                 goto out;
5313
5314         rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5315         CIFSSMBClose(xid, tcon, fid.netfid);
5316 out:
5317
5318         return rc;
5319 }
5320
5321 int
5322 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5323                    const char *fileName, const FILE_BASIC_INFO *data,
5324                    const struct nls_table *nls_codepage,
5325                      struct cifs_sb_info *cifs_sb)
5326 {
5327         TRANSACTION2_SPI_REQ *pSMB = NULL;
5328         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5329         int name_len;
5330         int rc = 0;
5331         int bytes_returned = 0;
5332         char *data_offset;
5333         __u16 params, param_offset, offset, byte_count, count;
5334         int remap = cifs_remap(cifs_sb);
5335
5336         cifs_dbg(FYI, "In SetTimes\n");
5337
5338 SetTimesRetry:
5339         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5340                       (void **) &pSMBr);
5341         if (rc)
5342                 return rc;
5343
5344         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5345                 name_len =
5346                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5347                                        PATH_MAX, nls_codepage, remap);
5348                 name_len++;     /* trailing null */
5349                 name_len *= 2;
5350         } else {
5351                 name_len = copy_path_name(pSMB->FileName, fileName);
5352         }
5353
5354         params = 6 + name_len;
5355         count = sizeof(FILE_BASIC_INFO);
5356         pSMB->MaxParameterCount = cpu_to_le16(2);
5357         /* BB find max SMB PDU from sess structure BB */
5358         pSMB->MaxDataCount = cpu_to_le16(1000);
5359         pSMB->MaxSetupCount = 0;
5360         pSMB->Reserved = 0;
5361         pSMB->Flags = 0;
5362         pSMB->Timeout = 0;
5363         pSMB->Reserved2 = 0;
5364         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5365                                 InformationLevel) - 4;
5366         offset = param_offset + params;
5367         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5368         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5369         pSMB->DataOffset = cpu_to_le16(offset);
5370         pSMB->SetupCount = 1;
5371         pSMB->Reserved3 = 0;
5372         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5373         byte_count = 3 /* pad */  + params + count;
5374
5375         pSMB->DataCount = cpu_to_le16(count);
5376         pSMB->ParameterCount = cpu_to_le16(params);
5377         pSMB->TotalDataCount = pSMB->DataCount;
5378         pSMB->TotalParameterCount = pSMB->ParameterCount;
5379         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5380                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5381         else
5382                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5383         pSMB->Reserved4 = 0;
5384         inc_rfc1001_len(pSMB, byte_count);
5385         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5386         pSMB->ByteCount = cpu_to_le16(byte_count);
5387         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5388                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5389         if (rc)
5390                 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5391
5392         cifs_buf_release(pSMB);
5393
5394         if (rc == -EAGAIN)
5395                 goto SetTimesRetry;
5396
5397         if (rc == -EOPNOTSUPP)
5398                 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5399                                             nls_codepage, cifs_sb);
5400
5401         return rc;
5402 }
5403
5404 static void
5405 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5406                         const struct cifs_unix_set_info_args *args)
5407 {
5408         u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5409         u64 mode = args->mode;
5410
5411         if (uid_valid(args->uid))
5412                 uid = from_kuid(&init_user_ns, args->uid);
5413         if (gid_valid(args->gid))
5414                 gid = from_kgid(&init_user_ns, args->gid);
5415
5416         /*
5417          * Samba server ignores set of file size to zero due to bugs in some
5418          * older clients, but we should be precise - we use SetFileSize to
5419          * set file size and do not want to truncate file size to zero
5420          * accidentally as happened on one Samba server beta by putting
5421          * zero instead of -1 here
5422          */
5423         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5424         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5425         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5426         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5427         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5428         data_offset->Uid = cpu_to_le64(uid);
5429         data_offset->Gid = cpu_to_le64(gid);
5430         /* better to leave device as zero when it is  */
5431         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5432         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5433         data_offset->Permissions = cpu_to_le64(mode);
5434
5435         if (S_ISREG(mode))
5436                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5437         else if (S_ISDIR(mode))
5438                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5439         else if (S_ISLNK(mode))
5440                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5441         else if (S_ISCHR(mode))
5442                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5443         else if (S_ISBLK(mode))
5444                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5445         else if (S_ISFIFO(mode))
5446                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5447         else if (S_ISSOCK(mode))
5448                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5449 }
5450
5451 int
5452 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5453                        const struct cifs_unix_set_info_args *args,
5454                        u16 fid, u32 pid_of_opener)
5455 {
5456         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5457         char *data_offset;
5458         int rc = 0;
5459         u16 params, param_offset, offset, byte_count, count;
5460
5461         cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5462         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5463
5464         if (rc)
5465                 return rc;
5466
5467         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5468         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5469
5470         params = 6;
5471         pSMB->MaxSetupCount = 0;
5472         pSMB->Reserved = 0;
5473         pSMB->Flags = 0;
5474         pSMB->Timeout = 0;
5475         pSMB->Reserved2 = 0;
5476         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5477         offset = param_offset + params;
5478
5479         data_offset = (char *)pSMB +
5480                         offsetof(struct smb_hdr, Protocol) + offset;
5481
5482         count = sizeof(FILE_UNIX_BASIC_INFO);
5483
5484         pSMB->MaxParameterCount = cpu_to_le16(2);
5485         /* BB find max SMB PDU from sess */
5486         pSMB->MaxDataCount = cpu_to_le16(1000);
5487         pSMB->SetupCount = 1;
5488         pSMB->Reserved3 = 0;
5489         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5490         byte_count = 3 /* pad */  + params + count;
5491         pSMB->DataCount = cpu_to_le16(count);
5492         pSMB->ParameterCount = cpu_to_le16(params);
5493         pSMB->TotalDataCount = pSMB->DataCount;
5494         pSMB->TotalParameterCount = pSMB->ParameterCount;
5495         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5496         pSMB->DataOffset = cpu_to_le16(offset);
5497         pSMB->Fid = fid;
5498         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5499         pSMB->Reserved4 = 0;
5500         inc_rfc1001_len(pSMB, byte_count);
5501         pSMB->ByteCount = cpu_to_le16(byte_count);
5502
5503         cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5504
5505         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5506         cifs_small_buf_release(pSMB);
5507         if (rc)
5508                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5509                          rc);
5510
5511         /* Note: On -EAGAIN error only caller can retry on handle based calls
5512                 since file handle passed in no longer valid */
5513
5514         return rc;
5515 }
5516
5517 int
5518 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5519                        const char *file_name,
5520                        const struct cifs_unix_set_info_args *args,
5521                        const struct nls_table *nls_codepage, int remap)
5522 {
5523         TRANSACTION2_SPI_REQ *pSMB = NULL;
5524         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5525         int name_len;
5526         int rc = 0;
5527         int bytes_returned = 0;
5528         FILE_UNIX_BASIC_INFO *data_offset;
5529         __u16 params, param_offset, offset, count, byte_count;
5530
5531         cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5532 setPermsRetry:
5533         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5534                       (void **) &pSMBr);
5535         if (rc)
5536                 return rc;
5537
5538         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5539                 name_len =
5540                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5541                                        PATH_MAX, nls_codepage, remap);
5542                 name_len++;     /* trailing null */
5543                 name_len *= 2;
5544         } else {
5545                 name_len = copy_path_name(pSMB->FileName, file_name);
5546         }
5547
5548         params = 6 + name_len;
5549         count = sizeof(FILE_UNIX_BASIC_INFO);
5550         pSMB->MaxParameterCount = cpu_to_le16(2);
5551         /* BB find max SMB PDU from sess structure BB */
5552         pSMB->MaxDataCount = cpu_to_le16(1000);
5553         pSMB->MaxSetupCount = 0;
5554         pSMB->Reserved = 0;
5555         pSMB->Flags = 0;
5556         pSMB->Timeout = 0;
5557         pSMB->Reserved2 = 0;
5558         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5559                                 InformationLevel) - 4;
5560         offset = param_offset + params;
5561         /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5562         data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5563         memset(data_offset, 0, count);
5564         pSMB->DataOffset = cpu_to_le16(offset);
5565         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5566         pSMB->SetupCount = 1;
5567         pSMB->Reserved3 = 0;
5568         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5569         byte_count = 3 /* pad */  + params + count;
5570         pSMB->ParameterCount = cpu_to_le16(params);
5571         pSMB->DataCount = cpu_to_le16(count);
5572         pSMB->TotalParameterCount = pSMB->ParameterCount;
5573         pSMB->TotalDataCount = pSMB->DataCount;
5574         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5575         pSMB->Reserved4 = 0;
5576         inc_rfc1001_len(pSMB, byte_count);
5577
5578         cifs_fill_unix_set_info(data_offset, args);
5579
5580         pSMB->ByteCount = cpu_to_le16(byte_count);
5581         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5582                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5583         if (rc)
5584                 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5585
5586         cifs_buf_release(pSMB);
5587         if (rc == -EAGAIN)
5588                 goto setPermsRetry;
5589         return rc;
5590 }
5591
5592 #ifdef CONFIG_CIFS_XATTR
5593 /*
5594  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5595  * function used by listxattr and getxattr type calls. When ea_name is set,
5596  * it looks for that attribute name and stuffs that value into the EAData
5597  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5598  * buffer. In both cases, the return value is either the length of the
5599  * resulting data or a negative error code. If EAData is a NULL pointer then
5600  * the data isn't copied to it, but the length is returned.
5601  */
5602 ssize_t
5603 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5604                 const unsigned char *searchName, const unsigned char *ea_name,
5605                 char *EAData, size_t buf_size,
5606                 struct cifs_sb_info *cifs_sb)
5607 {
5608                 /* BB assumes one setup word */
5609         TRANSACTION2_QPI_REQ *pSMB = NULL;
5610         TRANSACTION2_QPI_RSP *pSMBr = NULL;
5611         int remap = cifs_remap(cifs_sb);
5612         struct nls_table *nls_codepage = cifs_sb->local_nls;
5613         int rc = 0;
5614         int bytes_returned;
5615         int list_len;
5616         struct fealist *ea_response_data;
5617         struct fea *temp_fea;
5618         char *temp_ptr;
5619         char *end_of_smb;
5620         __u16 params, byte_count, data_offset;
5621         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5622
5623         cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5624 QAllEAsRetry:
5625         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5626                       (void **) &pSMBr);
5627         if (rc)
5628                 return rc;
5629
5630         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5631                 list_len =
5632                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5633                                        PATH_MAX, nls_codepage, remap);
5634                 list_len++;     /* trailing null */
5635                 list_len *= 2;
5636         } else {
5637                 list_len = copy_path_name(pSMB->FileName, searchName);
5638         }
5639
5640         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5641         pSMB->TotalDataCount = 0;
5642         pSMB->MaxParameterCount = cpu_to_le16(2);
5643         /* BB find exact max SMB PDU from sess structure BB */
5644         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5645         pSMB->MaxSetupCount = 0;
5646         pSMB->Reserved = 0;
5647         pSMB->Flags = 0;
5648         pSMB->Timeout = 0;
5649         pSMB->Reserved2 = 0;
5650         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5651         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5652         pSMB->DataCount = 0;
5653         pSMB->DataOffset = 0;
5654         pSMB->SetupCount = 1;
5655         pSMB->Reserved3 = 0;
5656         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5657         byte_count = params + 1 /* pad */ ;
5658         pSMB->TotalParameterCount = cpu_to_le16(params);
5659         pSMB->ParameterCount = pSMB->TotalParameterCount;
5660         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5661         pSMB->Reserved4 = 0;
5662         inc_rfc1001_len(pSMB, byte_count);
5663         pSMB->ByteCount = cpu_to_le16(byte_count);
5664
5665         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5666                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5667         if (rc) {
5668                 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5669                 goto QAllEAsOut;
5670         }
5671
5672
5673         /* BB also check enough total bytes returned */
5674         /* BB we need to improve the validity checking
5675         of these trans2 responses */
5676
5677         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5678         if (rc || get_bcc(&pSMBr->hdr) < 4) {
5679                 rc = -EIO;      /* bad smb */
5680                 goto QAllEAsOut;
5681         }
5682
5683         /* check that length of list is not more than bcc */
5684         /* check that each entry does not go beyond length
5685            of list */
5686         /* check that each element of each entry does not
5687            go beyond end of list */
5688         /* validate_trans2_offsets() */
5689         /* BB check if start of smb + data_offset > &bcc+ bcc */
5690
5691         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5692         ea_response_data = (struct fealist *)
5693                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5694
5695         list_len = le32_to_cpu(ea_response_data->list_len);
5696         cifs_dbg(FYI, "ea length %d\n", list_len);
5697         if (list_len <= 8) {
5698                 cifs_dbg(FYI, "empty EA list returned from server\n");
5699                 /* didn't find the named attribute */
5700                 if (ea_name)
5701                         rc = -ENODATA;
5702                 goto QAllEAsOut;
5703         }
5704
5705         /* make sure list_len doesn't go past end of SMB */
5706         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5707         if ((char *)ea_response_data + list_len > end_of_smb) {
5708                 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5709                 rc = -EIO;
5710                 goto QAllEAsOut;
5711         }
5712
5713         /* account for ea list len */
5714         list_len -= 4;
5715         temp_fea = &ea_response_data->list;
5716         temp_ptr = (char *)temp_fea;
5717         while (list_len > 0) {
5718                 unsigned int name_len;
5719                 __u16 value_len;
5720
5721                 list_len -= 4;
5722                 temp_ptr += 4;
5723                 /* make sure we can read name_len and value_len */
5724                 if (list_len < 0) {
5725                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5726                         rc = -EIO;
5727                         goto QAllEAsOut;
5728                 }
5729
5730                 name_len = temp_fea->name_len;
5731                 value_len = le16_to_cpu(temp_fea->value_len);
5732                 list_len -= name_len + 1 + value_len;
5733                 if (list_len < 0) {
5734                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5735                         rc = -EIO;
5736                         goto QAllEAsOut;
5737                 }
5738
5739                 if (ea_name) {
5740                         if (ea_name_len == name_len &&
5741                             memcmp(ea_name, temp_ptr, name_len) == 0) {
5742                                 temp_ptr += name_len + 1;
5743                                 rc = value_len;
5744                                 if (buf_size == 0)
5745                                         goto QAllEAsOut;
5746                                 if ((size_t)value_len > buf_size) {
5747                                         rc = -ERANGE;
5748                                         goto QAllEAsOut;
5749                                 }
5750                                 memcpy(EAData, temp_ptr, value_len);
5751                                 goto QAllEAsOut;
5752                         }
5753                 } else {
5754                         /* account for prefix user. and trailing null */
5755                         rc += (5 + 1 + name_len);
5756                         if (rc < (int) buf_size) {
5757                                 memcpy(EAData, "user.", 5);
5758                                 EAData += 5;
5759                                 memcpy(EAData, temp_ptr, name_len);
5760                                 EAData += name_len;
5761                                 /* null terminate name */
5762                                 *EAData = 0;
5763                                 ++EAData;
5764                         } else if (buf_size == 0) {
5765                                 /* skip copy - calc size only */
5766                         } else {
5767                                 /* stop before overrun buffer */
5768                                 rc = -ERANGE;
5769                                 break;
5770                         }
5771                 }
5772                 temp_ptr += name_len + 1 + value_len;
5773                 temp_fea = (struct fea *)temp_ptr;
5774         }
5775
5776         /* didn't find the named attribute */
5777         if (ea_name)
5778                 rc = -ENODATA;
5779
5780 QAllEAsOut:
5781         cifs_buf_release(pSMB);
5782         if (rc == -EAGAIN)
5783                 goto QAllEAsRetry;
5784
5785         return (ssize_t)rc;
5786 }
5787
5788 int
5789 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5790              const char *fileName, const char *ea_name, const void *ea_value,
5791              const __u16 ea_value_len, const struct nls_table *nls_codepage,
5792              struct cifs_sb_info *cifs_sb)
5793 {
5794         struct smb_com_transaction2_spi_req *pSMB = NULL;
5795         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5796         struct fealist *parm_data;
5797         int name_len;
5798         int rc = 0;
5799         int bytes_returned = 0;
5800         __u16 params, param_offset, byte_count, offset, count;
5801         int remap = cifs_remap(cifs_sb);
5802
5803         cifs_dbg(FYI, "In SetEA\n");
5804 SetEARetry:
5805         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5806                       (void **) &pSMBr);
5807         if (rc)
5808                 return rc;
5809
5810         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5811                 name_len =
5812                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5813                                        PATH_MAX, nls_codepage, remap);
5814                 name_len++;     /* trailing null */
5815                 name_len *= 2;
5816         } else {
5817                 name_len = copy_path_name(pSMB->FileName, fileName);
5818         }
5819
5820         params = 6 + name_len;
5821
5822         /* done calculating parms using name_len of file name,
5823         now use name_len to calculate length of ea name
5824         we are going to create in the inode xattrs */
5825         if (ea_name == NULL)
5826                 name_len = 0;
5827         else
5828                 name_len = strnlen(ea_name, 255);
5829
5830         count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
5831         pSMB->MaxParameterCount = cpu_to_le16(2);
5832         /* BB find max SMB PDU from sess */
5833         pSMB->MaxDataCount = cpu_to_le16(1000);
5834         pSMB->MaxSetupCount = 0;
5835         pSMB->Reserved = 0;
5836         pSMB->Flags = 0;
5837         pSMB->Timeout = 0;
5838         pSMB->Reserved2 = 0;
5839         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5840                                 InformationLevel) - 4;
5841         offset = param_offset + params;
5842         pSMB->InformationLevel =
5843                 cpu_to_le16(SMB_SET_FILE_EA);
5844
5845         parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5846         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5847         pSMB->DataOffset = cpu_to_le16(offset);
5848         pSMB->SetupCount = 1;
5849         pSMB->Reserved3 = 0;
5850         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5851         byte_count = 3 /* pad */  + params + count;
5852         pSMB->DataCount = cpu_to_le16(count);
5853         parm_data->list_len = cpu_to_le32(count);
5854         parm_data->list.EA_flags = 0;
5855         /* we checked above that name len is less than 255 */
5856         parm_data->list.name_len = (__u8)name_len;
5857         /* EA names are always ASCII and NUL-terminated */
5858         strscpy(parm_data->list.name, ea_name ?: "", name_len + 1);
5859         parm_data->list.value_len = cpu_to_le16(ea_value_len);
5860         /* caller ensures that ea_value_len is less than 64K but
5861         we need to ensure that it fits within the smb */
5862
5863         /*BB add length check to see if it would fit in
5864              negotiated SMB buffer size BB */
5865         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5866         if (ea_value_len)
5867                 memcpy(parm_data->list.name + name_len + 1,
5868                        ea_value, ea_value_len);
5869
5870         pSMB->TotalDataCount = pSMB->DataCount;
5871         pSMB->ParameterCount = cpu_to_le16(params);
5872         pSMB->TotalParameterCount = pSMB->ParameterCount;
5873         pSMB->Reserved4 = 0;
5874         inc_rfc1001_len(pSMB, byte_count);
5875         pSMB->ByteCount = cpu_to_le16(byte_count);
5876         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5877                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5878         if (rc)
5879                 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5880
5881         cifs_buf_release(pSMB);
5882
5883         if (rc == -EAGAIN)
5884                 goto SetEARetry;
5885
5886         return rc;
5887 }
5888 #endif