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