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