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