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