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