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