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