OSDN Git Service

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