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