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