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