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