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