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