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