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