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