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