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