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