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