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