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