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