Merge tag 'xtensa-next-20130710' of git://github.com/czankel/xtensa-linux
[platform/adaptation/renesas_rcar/renesas_kernel.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 #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
3071 /*
3072  *      Recent Windows versions now create symlinks more frequently
3073  *      and they use the "reparse point" mechanism below.  We can of course
3074  *      do symlinks nicely to Samba and other servers which support the
3075  *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3076  *      "MF" symlinks optionally, but for recent Windows we really need to
3077  *      reenable the code below and fix the cifs_symlink callers to handle this.
3078  *      In the interim this code has been moved to its own config option so
3079  *      it is not compiled in by default until callers fixed up and more tested.
3080  */
3081 int
3082 CIFSSMBQueryReparseLinkInfo(const unsigned int xid, struct cifs_tcon *tcon,
3083                         const unsigned char *searchName,
3084                         char *symlinkinfo, const int buflen, __u16 fid,
3085                         const struct nls_table *nls_codepage)
3086 {
3087         int rc = 0;
3088         int bytes_returned;
3089         struct smb_com_transaction_ioctl_req *pSMB;
3090         struct smb_com_transaction_ioctl_rsp *pSMBr;
3091
3092         cifs_dbg(FYI, "In Windows reparse style QueryLink for path %s\n",
3093                  searchName);
3094         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3095                       (void **) &pSMBr);
3096         if (rc)
3097                 return rc;
3098
3099         pSMB->TotalParameterCount = 0 ;
3100         pSMB->TotalDataCount = 0;
3101         pSMB->MaxParameterCount = cpu_to_le32(2);
3102         /* BB find exact data count max from sess structure BB */
3103         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3104         pSMB->MaxSetupCount = 4;
3105         pSMB->Reserved = 0;
3106         pSMB->ParameterOffset = 0;
3107         pSMB->DataCount = 0;
3108         pSMB->DataOffset = 0;
3109         pSMB->SetupCount = 4;
3110         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3111         pSMB->ParameterCount = pSMB->TotalParameterCount;
3112         pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3113         pSMB->IsFsctl = 1; /* FSCTL */
3114         pSMB->IsRootFlag = 0;
3115         pSMB->Fid = fid; /* file handle always le */
3116         pSMB->ByteCount = 0;
3117
3118         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3119                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3120         if (rc) {
3121                 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3122         } else {                /* decode response */
3123                 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
3124                 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
3125                 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3126                         /* BB also check enough total bytes returned */
3127                         rc = -EIO;      /* bad smb */
3128                         goto qreparse_out;
3129                 }
3130                 if (data_count && (data_count < 2048)) {
3131                         char *end_of_smb = 2 /* sizeof byte count */ +
3132                                get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3133
3134                         struct reparse_data *reparse_buf =
3135                                                 (struct reparse_data *)
3136                                                 ((char *)&pSMBr->hdr.Protocol
3137                                                                  + data_offset);
3138                         if ((char *)reparse_buf >= end_of_smb) {
3139                                 rc = -EIO;
3140                                 goto qreparse_out;
3141                         }
3142                         if ((reparse_buf->LinkNamesBuf +
3143                                 reparse_buf->TargetNameOffset +
3144                                 reparse_buf->TargetNameLen) > end_of_smb) {
3145                                 cifs_dbg(FYI, "reparse buf beyond SMB\n");
3146                                 rc = -EIO;
3147                                 goto qreparse_out;
3148                         }
3149
3150                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3151                                 cifs_from_ucs2(symlinkinfo, (__le16 *)
3152                                                 (reparse_buf->LinkNamesBuf +
3153                                                 reparse_buf->TargetNameOffset),
3154                                                 buflen,
3155                                                 reparse_buf->TargetNameLen,
3156                                                 nls_codepage, 0);
3157                         } else { /* ASCII names */
3158                                 strncpy(symlinkinfo,
3159                                         reparse_buf->LinkNamesBuf +
3160                                         reparse_buf->TargetNameOffset,
3161                                         min_t(const int, buflen,
3162                                            reparse_buf->TargetNameLen));
3163                         }
3164                 } else {
3165                         rc = -EIO;
3166                         cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3167                 }
3168                 symlinkinfo[buflen] = 0; /* just in case so the caller
3169                                         does not go off the end of the buffer */
3170                 cifs_dbg(FYI, "readlink result - %s\n", symlinkinfo);
3171         }
3172
3173 qreparse_out:
3174         cifs_buf_release(pSMB);
3175
3176         /* Note: On -EAGAIN error only caller can retry on handle based calls
3177                 since file handle passed in no longer valid */
3178
3179         return rc;
3180 }
3181 #endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
3182
3183 #ifdef CONFIG_CIFS_POSIX
3184
3185 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3186 static void cifs_convert_ace(posix_acl_xattr_entry *ace,
3187                              struct cifs_posix_ace *cifs_ace)
3188 {
3189         /* u8 cifs fields do not need le conversion */
3190         ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3191         ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3192         ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3193 /*
3194         cifs_dbg(FYI, "perm %d tag %d id %d\n",
3195                  ace->e_perm, ace->e_tag, ace->e_id);
3196 */
3197
3198         return;
3199 }
3200
3201 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3202 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3203                                const int acl_type, const int size_of_data_area)
3204 {
3205         int size =  0;
3206         int i;
3207         __u16 count;
3208         struct cifs_posix_ace *pACE;
3209         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3210         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
3211
3212         if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3213                 return -EOPNOTSUPP;
3214
3215         if (acl_type & ACL_TYPE_ACCESS) {
3216                 count = le16_to_cpu(cifs_acl->access_entry_count);
3217                 pACE = &cifs_acl->ace_array[0];
3218                 size = sizeof(struct cifs_posix_acl);
3219                 size += sizeof(struct cifs_posix_ace) * count;
3220                 /* check if we would go beyond end of SMB */
3221                 if (size_of_data_area < size) {
3222                         cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3223                                  size_of_data_area, size);
3224                         return -EINVAL;
3225                 }
3226         } else if (acl_type & ACL_TYPE_DEFAULT) {
3227                 count = le16_to_cpu(cifs_acl->access_entry_count);
3228                 size = sizeof(struct cifs_posix_acl);
3229                 size += sizeof(struct cifs_posix_ace) * count;
3230 /* skip past access ACEs to get to default ACEs */
3231                 pACE = &cifs_acl->ace_array[count];
3232                 count = le16_to_cpu(cifs_acl->default_entry_count);
3233                 size += sizeof(struct cifs_posix_ace) * count;
3234                 /* check if we would go beyond end of SMB */
3235                 if (size_of_data_area < size)
3236                         return -EINVAL;
3237         } else {
3238                 /* illegal type */
3239                 return -EINVAL;
3240         }
3241
3242         size = posix_acl_xattr_size(count);
3243         if ((buflen == 0) || (local_acl == NULL)) {
3244                 /* used to query ACL EA size */
3245         } else if (size > buflen) {
3246                 return -ERANGE;
3247         } else /* buffer big enough */ {
3248                 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3249                 for (i = 0; i < count ; i++) {
3250                         cifs_convert_ace(&local_acl->a_entries[i], pACE);
3251                         pACE++;
3252                 }
3253         }
3254         return size;
3255 }
3256
3257 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3258                                      const posix_acl_xattr_entry *local_ace)
3259 {
3260         __u16 rc = 0; /* 0 = ACL converted ok */
3261
3262         cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3263         cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
3264         /* BB is there a better way to handle the large uid? */
3265         if (local_ace->e_id == cpu_to_le32(-1)) {
3266         /* Probably no need to le convert -1 on any arch but can not hurt */
3267                 cifs_ace->cifs_uid = cpu_to_le64(-1);
3268         } else
3269                 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3270 /*
3271         cifs_dbg(FYI, "perm %d tag %d id %d\n",
3272                  ace->e_perm, ace->e_tag, ace->e_id);
3273 */
3274         return rc;
3275 }
3276
3277 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3278 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3279                                const int buflen, const int acl_type)
3280 {
3281         __u16 rc = 0;
3282         struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3283         posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
3284         int count;
3285         int i;
3286
3287         if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3288                 return 0;
3289
3290         count = posix_acl_xattr_count((size_t)buflen);
3291         cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3292                  count, buflen, le32_to_cpu(local_acl->a_version));
3293         if (le32_to_cpu(local_acl->a_version) != 2) {
3294                 cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3295                          le32_to_cpu(local_acl->a_version));
3296                 return 0;
3297         }
3298         cifs_acl->version = cpu_to_le16(1);
3299         if (acl_type == ACL_TYPE_ACCESS)
3300                 cifs_acl->access_entry_count = cpu_to_le16(count);
3301         else if (acl_type == ACL_TYPE_DEFAULT)
3302                 cifs_acl->default_entry_count = cpu_to_le16(count);
3303         else {
3304                 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3305                 return 0;
3306         }
3307         for (i = 0; i < count; i++) {
3308                 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3309                                         &local_acl->a_entries[i]);
3310                 if (rc != 0) {
3311                         /* ACE not converted */
3312                         break;
3313                 }
3314         }
3315         if (rc == 0) {
3316                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3317                 rc += sizeof(struct cifs_posix_acl);
3318                 /* BB add check to make sure ACL does not overflow SMB */
3319         }
3320         return rc;
3321 }
3322
3323 int
3324 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3325                    const unsigned char *searchName,
3326                    char *acl_inf, const int buflen, const int acl_type,
3327                    const struct nls_table *nls_codepage, int remap)
3328 {
3329 /* SMB_QUERY_POSIX_ACL */
3330         TRANSACTION2_QPI_REQ *pSMB = NULL;
3331         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3332         int rc = 0;
3333         int bytes_returned;
3334         int name_len;
3335         __u16 params, byte_count;
3336
3337         cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3338
3339 queryAclRetry:
3340         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3341                 (void **) &pSMBr);
3342         if (rc)
3343                 return rc;
3344
3345         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3346                 name_len =
3347                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3348                                            searchName, PATH_MAX, nls_codepage,
3349                                            remap);
3350                 name_len++;     /* trailing null */
3351                 name_len *= 2;
3352                 pSMB->FileName[name_len] = 0;
3353                 pSMB->FileName[name_len+1] = 0;
3354         } else {        /* BB improve the check for buffer overruns BB */
3355                 name_len = strnlen(searchName, PATH_MAX);
3356                 name_len++;     /* trailing null */
3357                 strncpy(pSMB->FileName, searchName, name_len);
3358         }
3359
3360         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3361         pSMB->TotalDataCount = 0;
3362         pSMB->MaxParameterCount = cpu_to_le16(2);
3363         /* BB find exact max data count below from sess structure BB */
3364         pSMB->MaxDataCount = cpu_to_le16(4000);
3365         pSMB->MaxSetupCount = 0;
3366         pSMB->Reserved = 0;
3367         pSMB->Flags = 0;
3368         pSMB->Timeout = 0;
3369         pSMB->Reserved2 = 0;
3370         pSMB->ParameterOffset = cpu_to_le16(
3371                 offsetof(struct smb_com_transaction2_qpi_req,
3372                          InformationLevel) - 4);
3373         pSMB->DataCount = 0;
3374         pSMB->DataOffset = 0;
3375         pSMB->SetupCount = 1;
3376         pSMB->Reserved3 = 0;
3377         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3378         byte_count = params + 1 /* pad */ ;
3379         pSMB->TotalParameterCount = cpu_to_le16(params);
3380         pSMB->ParameterCount = pSMB->TotalParameterCount;
3381         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3382         pSMB->Reserved4 = 0;
3383         inc_rfc1001_len(pSMB, byte_count);
3384         pSMB->ByteCount = cpu_to_le16(byte_count);
3385
3386         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3387                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3388         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3389         if (rc) {
3390                 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3391         } else {
3392                 /* decode response */
3393
3394                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3395                 /* BB also check enough total bytes returned */
3396                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3397                         rc = -EIO;      /* bad smb */
3398                 else {
3399                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3400                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3401                         rc = cifs_copy_posix_acl(acl_inf,
3402                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3403                                 buflen, acl_type, count);
3404                 }
3405         }
3406         cifs_buf_release(pSMB);
3407         if (rc == -EAGAIN)
3408                 goto queryAclRetry;
3409         return rc;
3410 }
3411
3412 int
3413 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3414                    const unsigned char *fileName,
3415                    const char *local_acl, const int buflen,
3416                    const int acl_type,
3417                    const struct nls_table *nls_codepage, int remap)
3418 {
3419         struct smb_com_transaction2_spi_req *pSMB = NULL;
3420         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3421         char *parm_data;
3422         int name_len;
3423         int rc = 0;
3424         int bytes_returned = 0;
3425         __u16 params, byte_count, data_count, param_offset, offset;
3426
3427         cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3428 setAclRetry:
3429         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3430                       (void **) &pSMBr);
3431         if (rc)
3432                 return rc;
3433         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3434                 name_len =
3435                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3436                                            PATH_MAX, nls_codepage, remap);
3437                 name_len++;     /* trailing null */
3438                 name_len *= 2;
3439         } else {        /* BB improve the check for buffer overruns BB */
3440                 name_len = strnlen(fileName, PATH_MAX);
3441                 name_len++;     /* trailing null */
3442                 strncpy(pSMB->FileName, fileName, name_len);
3443         }
3444         params = 6 + name_len;
3445         pSMB->MaxParameterCount = cpu_to_le16(2);
3446         /* BB find max SMB size from sess */
3447         pSMB->MaxDataCount = cpu_to_le16(1000);
3448         pSMB->MaxSetupCount = 0;
3449         pSMB->Reserved = 0;
3450         pSMB->Flags = 0;
3451         pSMB->Timeout = 0;
3452         pSMB->Reserved2 = 0;
3453         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3454                                 InformationLevel) - 4;
3455         offset = param_offset + params;
3456         parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3457         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3458
3459         /* convert to on the wire format for POSIX ACL */
3460         data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3461
3462         if (data_count == 0) {
3463                 rc = -EOPNOTSUPP;
3464                 goto setACLerrorExit;
3465         }
3466         pSMB->DataOffset = cpu_to_le16(offset);
3467         pSMB->SetupCount = 1;
3468         pSMB->Reserved3 = 0;
3469         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3470         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3471         byte_count = 3 /* pad */  + params + data_count;
3472         pSMB->DataCount = cpu_to_le16(data_count);
3473         pSMB->TotalDataCount = pSMB->DataCount;
3474         pSMB->ParameterCount = cpu_to_le16(params);
3475         pSMB->TotalParameterCount = pSMB->ParameterCount;
3476         pSMB->Reserved4 = 0;
3477         inc_rfc1001_len(pSMB, byte_count);
3478         pSMB->ByteCount = cpu_to_le16(byte_count);
3479         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3480                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3481         if (rc)
3482                 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3483
3484 setACLerrorExit:
3485         cifs_buf_release(pSMB);
3486         if (rc == -EAGAIN)
3487                 goto setAclRetry;
3488         return rc;
3489 }
3490
3491 /* BB fix tabs in this function FIXME BB */
3492 int
3493 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3494                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3495 {
3496         int rc = 0;
3497         struct smb_t2_qfi_req *pSMB = NULL;
3498         struct smb_t2_qfi_rsp *pSMBr = NULL;
3499         int bytes_returned;
3500         __u16 params, byte_count;
3501
3502         cifs_dbg(FYI, "In GetExtAttr\n");
3503         if (tcon == NULL)
3504                 return -ENODEV;
3505
3506 GetExtAttrRetry:
3507         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3508                         (void **) &pSMBr);
3509         if (rc)
3510                 return rc;
3511
3512         params = 2 /* level */ + 2 /* fid */;
3513         pSMB->t2.TotalDataCount = 0;
3514         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3515         /* BB find exact max data count below from sess structure BB */
3516         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3517         pSMB->t2.MaxSetupCount = 0;
3518         pSMB->t2.Reserved = 0;
3519         pSMB->t2.Flags = 0;
3520         pSMB->t2.Timeout = 0;
3521         pSMB->t2.Reserved2 = 0;
3522         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3523                                                Fid) - 4);
3524         pSMB->t2.DataCount = 0;
3525         pSMB->t2.DataOffset = 0;
3526         pSMB->t2.SetupCount = 1;
3527         pSMB->t2.Reserved3 = 0;
3528         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3529         byte_count = params + 1 /* pad */ ;
3530         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3531         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3532         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3533         pSMB->Pad = 0;
3534         pSMB->Fid = netfid;
3535         inc_rfc1001_len(pSMB, byte_count);
3536         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3537
3538         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3539                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3540         if (rc) {
3541                 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3542         } else {
3543                 /* decode response */
3544                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3545                 /* BB also check enough total bytes returned */
3546                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3547                         /* If rc should we check for EOPNOSUPP and
3548                            disable the srvino flag? or in caller? */
3549                         rc = -EIO;      /* bad smb */
3550                 else {
3551                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3552                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3553                         struct file_chattr_info *pfinfo;
3554                         /* BB Do we need a cast or hash here ? */
3555                         if (count != 16) {
3556                                 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3557                                 rc = -EIO;
3558                                 goto GetExtAttrOut;
3559                         }
3560                         pfinfo = (struct file_chattr_info *)
3561                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3562                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3563                         *pMask = le64_to_cpu(pfinfo->mask);
3564                 }
3565         }
3566 GetExtAttrOut:
3567         cifs_buf_release(pSMB);
3568         if (rc == -EAGAIN)
3569                 goto GetExtAttrRetry;
3570         return rc;
3571 }
3572
3573 #endif /* CONFIG_POSIX */
3574
3575 #ifdef CONFIG_CIFS_ACL
3576 /*
3577  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3578  * all NT TRANSACTS that we init here have total parm and data under about 400
3579  * bytes (to fit in small cifs buffer size), which is the case so far, it
3580  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3581  * returned setup area) and MaxParameterCount (returned parms size) must be set
3582  * by caller
3583  */
3584 static int
3585 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3586                    const int parm_len, struct cifs_tcon *tcon,
3587                    void **ret_buf)
3588 {
3589         int rc;
3590         __u32 temp_offset;
3591         struct smb_com_ntransact_req *pSMB;
3592
3593         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3594                                 (void **)&pSMB);
3595         if (rc)
3596                 return rc;
3597         *ret_buf = (void *)pSMB;
3598         pSMB->Reserved = 0;
3599         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3600         pSMB->TotalDataCount  = 0;
3601         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3602         pSMB->ParameterCount = pSMB->TotalParameterCount;
3603         pSMB->DataCount  = pSMB->TotalDataCount;
3604         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3605                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3606         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3607         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3608         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3609         pSMB->SubCommand = cpu_to_le16(sub_command);
3610         return 0;
3611 }
3612
3613 static int
3614 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3615                    __u32 *pparmlen, __u32 *pdatalen)
3616 {
3617         char *end_of_smb;
3618         __u32 data_count, data_offset, parm_count, parm_offset;
3619         struct smb_com_ntransact_rsp *pSMBr;
3620         u16 bcc;
3621
3622         *pdatalen = 0;
3623         *pparmlen = 0;
3624
3625         if (buf == NULL)
3626                 return -EINVAL;
3627
3628         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3629
3630         bcc = get_bcc(&pSMBr->hdr);
3631         end_of_smb = 2 /* sizeof byte count */ + bcc +
3632                         (char *)&pSMBr->ByteCount;
3633
3634         data_offset = le32_to_cpu(pSMBr->DataOffset);
3635         data_count = le32_to_cpu(pSMBr->DataCount);
3636         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3637         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3638
3639         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3640         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3641
3642         /* should we also check that parm and data areas do not overlap? */
3643         if (*ppparm > end_of_smb) {
3644                 cifs_dbg(FYI, "parms start after end of smb\n");
3645                 return -EINVAL;
3646         } else if (parm_count + *ppparm > end_of_smb) {
3647                 cifs_dbg(FYI, "parm end after end of smb\n");
3648                 return -EINVAL;
3649         } else if (*ppdata > end_of_smb) {
3650                 cifs_dbg(FYI, "data starts after end of smb\n");
3651                 return -EINVAL;
3652         } else if (data_count + *ppdata > end_of_smb) {
3653                 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3654                          *ppdata, data_count, (data_count + *ppdata),
3655                          end_of_smb, pSMBr);
3656                 return -EINVAL;
3657         } else if (parm_count + data_count > bcc) {
3658                 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3659                 return -EINVAL;
3660         }
3661         *pdatalen = data_count;
3662         *pparmlen = parm_count;
3663         return 0;
3664 }
3665
3666 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3667 int
3668 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3669                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3670 {
3671         int rc = 0;
3672         int buf_type = 0;
3673         QUERY_SEC_DESC_REQ *pSMB;
3674         struct kvec iov[1];
3675
3676         cifs_dbg(FYI, "GetCifsACL\n");
3677
3678         *pbuflen = 0;
3679         *acl_inf = NULL;
3680
3681         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3682                         8 /* parm len */, tcon, (void **) &pSMB);
3683         if (rc)
3684                 return rc;
3685
3686         pSMB->MaxParameterCount = cpu_to_le32(4);
3687         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3688         pSMB->MaxSetupCount = 0;
3689         pSMB->Fid = fid; /* file handle always le */
3690         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3691                                      CIFS_ACL_DACL);
3692         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3693         inc_rfc1001_len(pSMB, 11);
3694         iov[0].iov_base = (char *)pSMB;
3695         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3696
3697         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3698                          0);
3699         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3700         if (rc) {
3701                 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3702         } else {                /* decode response */
3703                 __le32 *parm;
3704                 __u32 parm_len;
3705                 __u32 acl_len;
3706                 struct smb_com_ntransact_rsp *pSMBr;
3707                 char *pdata;
3708
3709 /* validate_nttransact */
3710                 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3711                                         &pdata, &parm_len, pbuflen);
3712                 if (rc)
3713                         goto qsec_out;
3714                 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3715
3716                 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3717                          pSMBr, parm, *acl_inf);
3718
3719                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3720                         rc = -EIO;      /* bad smb */
3721                         *pbuflen = 0;
3722                         goto qsec_out;
3723                 }
3724
3725 /* BB check that data area is minimum length and as big as acl_len */
3726
3727                 acl_len = le32_to_cpu(*parm);
3728                 if (acl_len != *pbuflen) {
3729                         cifs_dbg(VFS, "acl length %d does not match %d\n",
3730                                  acl_len, *pbuflen);
3731                         if (*pbuflen > acl_len)
3732                                 *pbuflen = acl_len;
3733                 }
3734
3735                 /* check if buffer is big enough for the acl
3736                    header followed by the smallest SID */
3737                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3738                     (*pbuflen >= 64 * 1024)) {
3739                         cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3740                         rc = -EINVAL;
3741                         *pbuflen = 0;
3742                 } else {
3743                         *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3744                         if (*acl_inf == NULL) {
3745                                 *pbuflen = 0;
3746                                 rc = -ENOMEM;
3747                         }
3748                 }
3749         }
3750 qsec_out:
3751         if (buf_type == CIFS_SMALL_BUFFER)
3752                 cifs_small_buf_release(iov[0].iov_base);
3753         else if (buf_type == CIFS_LARGE_BUFFER)
3754                 cifs_buf_release(iov[0].iov_base);
3755 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3756         return rc;
3757 }
3758
3759 int
3760 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3761                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3762 {
3763         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3764         int rc = 0;
3765         int bytes_returned = 0;
3766         SET_SEC_DESC_REQ *pSMB = NULL;
3767         void *pSMBr;
3768
3769 setCifsAclRetry:
3770         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3771         if (rc)
3772                 return rc;
3773
3774         pSMB->MaxSetupCount = 0;
3775         pSMB->Reserved = 0;
3776
3777         param_count = 8;
3778         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3779         data_count = acllen;
3780         data_offset = param_offset + param_count;
3781         byte_count = 3 /* pad */  + param_count;
3782
3783         pSMB->DataCount = cpu_to_le32(data_count);
3784         pSMB->TotalDataCount = pSMB->DataCount;
3785         pSMB->MaxParameterCount = cpu_to_le32(4);
3786         pSMB->MaxDataCount = cpu_to_le32(16384);
3787         pSMB->ParameterCount = cpu_to_le32(param_count);
3788         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3789         pSMB->TotalParameterCount = pSMB->ParameterCount;
3790         pSMB->DataOffset = cpu_to_le32(data_offset);
3791         pSMB->SetupCount = 0;
3792         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3793         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3794
3795         pSMB->Fid = fid; /* file handle always le */
3796         pSMB->Reserved2 = 0;
3797         pSMB->AclFlags = cpu_to_le32(aclflag);
3798
3799         if (pntsd && acllen) {
3800                 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3801                                 data_offset, pntsd, acllen);
3802                 inc_rfc1001_len(pSMB, byte_count + data_count);
3803         } else
3804                 inc_rfc1001_len(pSMB, byte_count);
3805
3806         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3807                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3808
3809         cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3810                  bytes_returned, rc);
3811         if (rc)
3812                 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3813         cifs_buf_release(pSMB);
3814
3815         if (rc == -EAGAIN)
3816                 goto setCifsAclRetry;
3817
3818         return (rc);
3819 }
3820
3821 #endif /* CONFIG_CIFS_ACL */
3822
3823 /* Legacy Query Path Information call for lookup to old servers such
3824    as Win9x/WinME */
3825 int
3826 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3827                     const char *search_name, FILE_ALL_INFO *data,
3828                     const struct nls_table *nls_codepage, int remap)
3829 {
3830         QUERY_INFORMATION_REQ *pSMB;
3831         QUERY_INFORMATION_RSP *pSMBr;
3832         int rc = 0;
3833         int bytes_returned;
3834         int name_len;
3835
3836         cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3837 QInfRetry:
3838         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3839                       (void **) &pSMBr);
3840         if (rc)
3841                 return rc;
3842
3843         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3844                 name_len =
3845                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3846                                            search_name, PATH_MAX, nls_codepage,
3847                                            remap);
3848                 name_len++;     /* trailing null */
3849                 name_len *= 2;
3850         } else {
3851                 name_len = strnlen(search_name, PATH_MAX);
3852                 name_len++;     /* trailing null */
3853                 strncpy(pSMB->FileName, search_name, name_len);
3854         }
3855         pSMB->BufferFormat = 0x04;
3856         name_len++; /* account for buffer type byte */
3857         inc_rfc1001_len(pSMB, (__u16)name_len);
3858         pSMB->ByteCount = cpu_to_le16(name_len);
3859
3860         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3861                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3862         if (rc) {
3863                 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3864         } else if (data) {
3865                 struct timespec ts;
3866                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3867
3868                 /* decode response */
3869                 /* BB FIXME - add time zone adjustment BB */
3870                 memset(data, 0, sizeof(FILE_ALL_INFO));
3871                 ts.tv_nsec = 0;
3872                 ts.tv_sec = time;
3873                 /* decode time fields */
3874                 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3875                 data->LastWriteTime = data->ChangeTime;
3876                 data->LastAccessTime = 0;
3877                 data->AllocationSize =
3878                         cpu_to_le64(le32_to_cpu(pSMBr->size));
3879                 data->EndOfFile = data->AllocationSize;
3880                 data->Attributes =
3881                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
3882         } else
3883                 rc = -EIO; /* bad buffer passed in */
3884
3885         cifs_buf_release(pSMB);
3886
3887         if (rc == -EAGAIN)
3888                 goto QInfRetry;
3889
3890         return rc;
3891 }
3892
3893 int
3894 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3895                  u16 netfid, FILE_ALL_INFO *pFindData)
3896 {
3897         struct smb_t2_qfi_req *pSMB = NULL;
3898         struct smb_t2_qfi_rsp *pSMBr = NULL;
3899         int rc = 0;
3900         int bytes_returned;
3901         __u16 params, byte_count;
3902
3903 QFileInfoRetry:
3904         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3905                       (void **) &pSMBr);
3906         if (rc)
3907                 return rc;
3908
3909         params = 2 /* level */ + 2 /* fid */;
3910         pSMB->t2.TotalDataCount = 0;
3911         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3912         /* BB find exact max data count below from sess structure BB */
3913         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3914         pSMB->t2.MaxSetupCount = 0;
3915         pSMB->t2.Reserved = 0;
3916         pSMB->t2.Flags = 0;
3917         pSMB->t2.Timeout = 0;
3918         pSMB->t2.Reserved2 = 0;
3919         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3920                                                Fid) - 4);
3921         pSMB->t2.DataCount = 0;
3922         pSMB->t2.DataOffset = 0;
3923         pSMB->t2.SetupCount = 1;
3924         pSMB->t2.Reserved3 = 0;
3925         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3926         byte_count = params + 1 /* pad */ ;
3927         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3928         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3929         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3930         pSMB->Pad = 0;
3931         pSMB->Fid = netfid;
3932         inc_rfc1001_len(pSMB, byte_count);
3933         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3934
3935         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3936                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3937         if (rc) {
3938                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3939         } else {                /* decode response */
3940                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3941
3942                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3943                         rc = -EIO;
3944                 else if (get_bcc(&pSMBr->hdr) < 40)
3945                         rc = -EIO;      /* bad smb */
3946                 else if (pFindData) {
3947                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3948                         memcpy((char *) pFindData,
3949                                (char *) &pSMBr->hdr.Protocol +
3950                                data_offset, sizeof(FILE_ALL_INFO));
3951                 } else
3952                     rc = -ENOMEM;
3953         }
3954         cifs_buf_release(pSMB);
3955         if (rc == -EAGAIN)
3956                 goto QFileInfoRetry;
3957
3958         return rc;
3959 }
3960
3961 int
3962 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3963                  const char *search_name, FILE_ALL_INFO *data,
3964                  int legacy /* old style infolevel */,
3965                  const struct nls_table *nls_codepage, int remap)
3966 {
3967         /* level 263 SMB_QUERY_FILE_ALL_INFO */
3968         TRANSACTION2_QPI_REQ *pSMB = NULL;
3969         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3970         int rc = 0;
3971         int bytes_returned;
3972         int name_len;
3973         __u16 params, byte_count;
3974
3975         /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3976 QPathInfoRetry:
3977         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3978                       (void **) &pSMBr);
3979         if (rc)
3980                 return rc;
3981
3982         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3983                 name_len =
3984                     cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3985                                        PATH_MAX, nls_codepage, remap);
3986                 name_len++;     /* trailing null */
3987                 name_len *= 2;
3988         } else {        /* BB improve the check for buffer overruns BB */
3989                 name_len = strnlen(search_name, PATH_MAX);
3990                 name_len++;     /* trailing null */
3991                 strncpy(pSMB->FileName, search_name, name_len);
3992         }
3993
3994         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3995         pSMB->TotalDataCount = 0;
3996         pSMB->MaxParameterCount = cpu_to_le16(2);
3997         /* BB find exact max SMB PDU from sess structure BB */
3998         pSMB->MaxDataCount = cpu_to_le16(4000);
3999         pSMB->MaxSetupCount = 0;
4000         pSMB->Reserved = 0;
4001         pSMB->Flags = 0;
4002         pSMB->Timeout = 0;
4003         pSMB->Reserved2 = 0;
4004         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4005         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4006         pSMB->DataCount = 0;
4007         pSMB->DataOffset = 0;
4008         pSMB->SetupCount = 1;
4009         pSMB->Reserved3 = 0;
4010         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4011         byte_count = params + 1 /* pad */ ;
4012         pSMB->TotalParameterCount = cpu_to_le16(params);
4013         pSMB->ParameterCount = pSMB->TotalParameterCount;
4014         if (legacy)
4015                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4016         else
4017                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4018         pSMB->Reserved4 = 0;
4019         inc_rfc1001_len(pSMB, byte_count);
4020         pSMB->ByteCount = cpu_to_le16(byte_count);
4021
4022         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4023                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4024         if (rc) {
4025                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4026         } else {                /* decode response */
4027                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4028
4029                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4030                         rc = -EIO;
4031                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4032                         rc = -EIO;      /* bad smb */
4033                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4034                         rc = -EIO;  /* 24 or 26 expected but we do not read
4035                                         last field */
4036                 else if (data) {
4037                         int size;
4038                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4039
4040                         /*
4041                          * On legacy responses we do not read the last field,
4042                          * EAsize, fortunately since it varies by subdialect and
4043                          * also note it differs on Set vs Get, ie two bytes or 4
4044                          * bytes depending but we don't care here.
4045                          */
4046                         if (legacy)
4047                                 size = sizeof(FILE_INFO_STANDARD);
4048                         else
4049                                 size = sizeof(FILE_ALL_INFO);
4050                         memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4051                                data_offset, size);
4052                 } else
4053                     rc = -ENOMEM;
4054         }
4055         cifs_buf_release(pSMB);
4056         if (rc == -EAGAIN)
4057                 goto QPathInfoRetry;
4058
4059         return rc;
4060 }
4061
4062 int
4063 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4064                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4065 {
4066         struct smb_t2_qfi_req *pSMB = NULL;
4067         struct smb_t2_qfi_rsp *pSMBr = NULL;
4068         int rc = 0;
4069         int bytes_returned;
4070         __u16 params, byte_count;
4071
4072 UnixQFileInfoRetry:
4073         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4074                       (void **) &pSMBr);
4075         if (rc)
4076                 return rc;
4077
4078         params = 2 /* level */ + 2 /* fid */;
4079         pSMB->t2.TotalDataCount = 0;
4080         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4081         /* BB find exact max data count below from sess structure BB */
4082         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4083         pSMB->t2.MaxSetupCount = 0;
4084         pSMB->t2.Reserved = 0;
4085         pSMB->t2.Flags = 0;
4086         pSMB->t2.Timeout = 0;
4087         pSMB->t2.Reserved2 = 0;
4088         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4089                                                Fid) - 4);
4090         pSMB->t2.DataCount = 0;
4091         pSMB->t2.DataOffset = 0;
4092         pSMB->t2.SetupCount = 1;
4093         pSMB->t2.Reserved3 = 0;
4094         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4095         byte_count = params + 1 /* pad */ ;
4096         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4097         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4098         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4099         pSMB->Pad = 0;
4100         pSMB->Fid = netfid;
4101         inc_rfc1001_len(pSMB, byte_count);
4102         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4103
4104         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4105                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4106         if (rc) {
4107                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4108         } else {                /* decode response */
4109                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4110
4111                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4112                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4113                         rc = -EIO;      /* bad smb */
4114                 } else {
4115                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4116                         memcpy((char *) pFindData,
4117                                (char *) &pSMBr->hdr.Protocol +
4118                                data_offset,
4119                                sizeof(FILE_UNIX_BASIC_INFO));
4120                 }
4121         }
4122
4123         cifs_buf_release(pSMB);
4124         if (rc == -EAGAIN)
4125                 goto UnixQFileInfoRetry;
4126
4127         return rc;
4128 }
4129
4130 int
4131 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4132                      const unsigned char *searchName,
4133                      FILE_UNIX_BASIC_INFO *pFindData,
4134                      const struct nls_table *nls_codepage, int remap)
4135 {
4136 /* SMB_QUERY_FILE_UNIX_BASIC */
4137         TRANSACTION2_QPI_REQ *pSMB = NULL;
4138         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4139         int rc = 0;
4140         int bytes_returned = 0;
4141         int name_len;
4142         __u16 params, byte_count;
4143
4144         cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4145 UnixQPathInfoRetry:
4146         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4147                       (void **) &pSMBr);
4148         if (rc)
4149                 return rc;
4150
4151         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4152                 name_len =
4153                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4154                                        PATH_MAX, nls_codepage, remap);
4155                 name_len++;     /* trailing null */
4156                 name_len *= 2;
4157         } else {        /* BB improve the check for buffer overruns BB */
4158                 name_len = strnlen(searchName, PATH_MAX);
4159                 name_len++;     /* trailing null */
4160                 strncpy(pSMB->FileName, searchName, name_len);
4161         }
4162
4163         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4164         pSMB->TotalDataCount = 0;
4165         pSMB->MaxParameterCount = cpu_to_le16(2);
4166         /* BB find exact max SMB PDU from sess structure BB */
4167         pSMB->MaxDataCount = cpu_to_le16(4000);
4168         pSMB->MaxSetupCount = 0;
4169         pSMB->Reserved = 0;
4170         pSMB->Flags = 0;
4171         pSMB->Timeout = 0;
4172         pSMB->Reserved2 = 0;
4173         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4174         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4175         pSMB->DataCount = 0;
4176         pSMB->DataOffset = 0;
4177         pSMB->SetupCount = 1;
4178         pSMB->Reserved3 = 0;
4179         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4180         byte_count = params + 1 /* pad */ ;
4181         pSMB->TotalParameterCount = cpu_to_le16(params);
4182         pSMB->ParameterCount = pSMB->TotalParameterCount;
4183         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4184         pSMB->Reserved4 = 0;
4185         inc_rfc1001_len(pSMB, byte_count);
4186         pSMB->ByteCount = cpu_to_le16(byte_count);
4187
4188         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4189                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4190         if (rc) {
4191                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4192         } else {                /* decode response */
4193                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4194
4195                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4196                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4197                         rc = -EIO;      /* bad smb */
4198                 } else {
4199                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4200                         memcpy((char *) pFindData,
4201                                (char *) &pSMBr->hdr.Protocol +
4202                                data_offset,
4203                                sizeof(FILE_UNIX_BASIC_INFO));
4204                 }
4205         }
4206         cifs_buf_release(pSMB);
4207         if (rc == -EAGAIN)
4208                 goto UnixQPathInfoRetry;
4209
4210         return rc;
4211 }
4212
4213 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4214 int
4215 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4216               const char *searchName, struct cifs_sb_info *cifs_sb,
4217               __u16 *pnetfid, __u16 search_flags,
4218               struct cifs_search_info *psrch_inf, bool msearch)
4219 {
4220 /* level 257 SMB_ */
4221         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4222         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4223         T2_FFIRST_RSP_PARMS *parms;
4224         int rc = 0;
4225         int bytes_returned = 0;
4226         int name_len, remap;
4227         __u16 params, byte_count;
4228         struct nls_table *nls_codepage;
4229
4230         cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4231
4232 findFirstRetry:
4233         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4234                       (void **) &pSMBr);
4235         if (rc)
4236                 return rc;
4237
4238         nls_codepage = cifs_sb->local_nls;
4239         remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
4240
4241         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4242                 name_len =
4243                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4244                                        PATH_MAX, nls_codepage, remap);
4245                 /* We can not add the asterik earlier in case
4246                 it got remapped to 0xF03A as if it were part of the
4247                 directory name instead of a wildcard */
4248                 name_len *= 2;
4249                 if (msearch) {
4250                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4251                         pSMB->FileName[name_len+1] = 0;
4252                         pSMB->FileName[name_len+2] = '*';
4253                         pSMB->FileName[name_len+3] = 0;
4254                         name_len += 4; /* now the trailing null */
4255                         /* null terminate just in case */
4256                         pSMB->FileName[name_len] = 0;
4257                         pSMB->FileName[name_len+1] = 0;
4258                         name_len += 2;
4259                 }
4260         } else {        /* BB add check for overrun of SMB buf BB */
4261                 name_len = strnlen(searchName, PATH_MAX);
4262 /* BB fix here and in unicode clause above ie
4263                 if (name_len > buffersize-header)
4264                         free buffer exit; BB */
4265                 strncpy(pSMB->FileName, searchName, name_len);
4266                 if (msearch) {
4267                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4268                         pSMB->FileName[name_len+1] = '*';
4269                         pSMB->FileName[name_len+2] = 0;
4270                         name_len += 3;
4271                 }
4272         }
4273
4274         params = 12 + name_len /* includes null */ ;
4275         pSMB->TotalDataCount = 0;       /* no EAs */
4276         pSMB->MaxParameterCount = cpu_to_le16(10);
4277         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4278         pSMB->MaxSetupCount = 0;
4279         pSMB->Reserved = 0;
4280         pSMB->Flags = 0;
4281         pSMB->Timeout = 0;
4282         pSMB->Reserved2 = 0;
4283         byte_count = params + 1 /* pad */ ;
4284         pSMB->TotalParameterCount = cpu_to_le16(params);
4285         pSMB->ParameterCount = pSMB->TotalParameterCount;
4286         pSMB->ParameterOffset = cpu_to_le16(
4287               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4288                 - 4);
4289         pSMB->DataCount = 0;
4290         pSMB->DataOffset = 0;
4291         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4292         pSMB->Reserved3 = 0;
4293         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4294         pSMB->SearchAttributes =
4295             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4296                         ATTR_DIRECTORY);
4297         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4298         pSMB->SearchFlags = cpu_to_le16(search_flags);
4299         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4300
4301         /* BB what should we set StorageType to? Does it matter? BB */
4302         pSMB->SearchStorageType = 0;
4303         inc_rfc1001_len(pSMB, byte_count);
4304         pSMB->ByteCount = cpu_to_le16(byte_count);
4305
4306         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4307                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4308         cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4309
4310         if (rc) {/* BB add logic to retry regular search if Unix search
4311                         rejected unexpectedly by server */
4312                 /* BB Add code to handle unsupported level rc */
4313                 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4314
4315                 cifs_buf_release(pSMB);
4316
4317                 /* BB eventually could optimize out free and realloc of buf */
4318                 /*    for this case */
4319                 if (rc == -EAGAIN)
4320                         goto findFirstRetry;
4321         } else { /* decode response */
4322                 /* BB remember to free buffer if error BB */
4323                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4324                 if (rc == 0) {
4325                         unsigned int lnoff;
4326
4327                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4328                                 psrch_inf->unicode = true;
4329                         else
4330                                 psrch_inf->unicode = false;
4331
4332                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4333                         psrch_inf->smallBuf = 0;
4334                         psrch_inf->srch_entries_start =
4335                                 (char *) &pSMBr->hdr.Protocol +
4336                                         le16_to_cpu(pSMBr->t2.DataOffset);
4337                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4338                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4339
4340                         if (parms->EndofSearch)
4341                                 psrch_inf->endOfSearch = true;
4342                         else
4343                                 psrch_inf->endOfSearch = false;
4344
4345                         psrch_inf->entries_in_buffer =
4346                                         le16_to_cpu(parms->SearchCount);
4347                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4348                                 psrch_inf->entries_in_buffer;
4349                         lnoff = le16_to_cpu(parms->LastNameOffset);
4350                         if (CIFSMaxBufSize < lnoff) {
4351                                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4352                                 psrch_inf->last_entry = NULL;
4353                                 return rc;
4354                         }
4355
4356                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4357                                                         lnoff;
4358
4359                         if (pnetfid)
4360                                 *pnetfid = parms->SearchHandle;
4361                 } else {
4362                         cifs_buf_release(pSMB);
4363                 }
4364         }
4365
4366         return rc;
4367 }
4368
4369 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4370                  __u16 searchHandle, __u16 search_flags,
4371                  struct cifs_search_info *psrch_inf)
4372 {
4373         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4374         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4375         T2_FNEXT_RSP_PARMS *parms;
4376         char *response_data;
4377         int rc = 0;
4378         int bytes_returned;
4379         unsigned int name_len;
4380         __u16 params, byte_count;
4381
4382         cifs_dbg(FYI, "In FindNext\n");
4383
4384         if (psrch_inf->endOfSearch)
4385                 return -ENOENT;
4386
4387         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4388                 (void **) &pSMBr);
4389         if (rc)
4390                 return rc;
4391
4392         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4393         byte_count = 0;
4394         pSMB->TotalDataCount = 0;       /* no EAs */
4395         pSMB->MaxParameterCount = cpu_to_le16(8);
4396         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4397         pSMB->MaxSetupCount = 0;
4398         pSMB->Reserved = 0;
4399         pSMB->Flags = 0;
4400         pSMB->Timeout = 0;
4401         pSMB->Reserved2 = 0;
4402         pSMB->ParameterOffset =  cpu_to_le16(
4403               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4404         pSMB->DataCount = 0;
4405         pSMB->DataOffset = 0;
4406         pSMB->SetupCount = 1;
4407         pSMB->Reserved3 = 0;
4408         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4409         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4410         pSMB->SearchCount =
4411                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4412         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4413         pSMB->ResumeKey = psrch_inf->resume_key;
4414         pSMB->SearchFlags = cpu_to_le16(search_flags);
4415
4416         name_len = psrch_inf->resume_name_len;
4417         params += name_len;
4418         if (name_len < PATH_MAX) {
4419                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4420                 byte_count += name_len;
4421                 /* 14 byte parm len above enough for 2 byte null terminator */
4422                 pSMB->ResumeFileName[name_len] = 0;
4423                 pSMB->ResumeFileName[name_len+1] = 0;
4424         } else {
4425                 rc = -EINVAL;
4426                 goto FNext2_err_exit;
4427         }
4428         byte_count = params + 1 /* pad */ ;
4429         pSMB->TotalParameterCount = cpu_to_le16(params);
4430         pSMB->ParameterCount = pSMB->TotalParameterCount;
4431         inc_rfc1001_len(pSMB, byte_count);
4432         pSMB->ByteCount = cpu_to_le16(byte_count);
4433
4434         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4435                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4436         cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4437         if (rc) {
4438                 if (rc == -EBADF) {
4439                         psrch_inf->endOfSearch = true;
4440                         cifs_buf_release(pSMB);
4441                         rc = 0; /* search probably was closed at end of search*/
4442                 } else
4443                         cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4444         } else {                /* decode response */
4445                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4446
4447                 if (rc == 0) {
4448                         unsigned int lnoff;
4449
4450                         /* BB fixme add lock for file (srch_info) struct here */
4451                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4452                                 psrch_inf->unicode = true;
4453                         else
4454                                 psrch_inf->unicode = false;
4455                         response_data = (char *) &pSMBr->hdr.Protocol +
4456                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4457                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4458                         response_data = (char *)&pSMBr->hdr.Protocol +
4459                                 le16_to_cpu(pSMBr->t2.DataOffset);
4460                         if (psrch_inf->smallBuf)
4461                                 cifs_small_buf_release(
4462                                         psrch_inf->ntwrk_buf_start);
4463                         else
4464                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4465                         psrch_inf->srch_entries_start = response_data;
4466                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4467                         psrch_inf->smallBuf = 0;
4468                         if (parms->EndofSearch)
4469                                 psrch_inf->endOfSearch = true;
4470                         else
4471                                 psrch_inf->endOfSearch = false;
4472                         psrch_inf->entries_in_buffer =
4473                                                 le16_to_cpu(parms->SearchCount);
4474                         psrch_inf->index_of_last_entry +=
4475                                 psrch_inf->entries_in_buffer;
4476                         lnoff = le16_to_cpu(parms->LastNameOffset);
4477                         if (CIFSMaxBufSize < lnoff) {
4478                                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4479                                 psrch_inf->last_entry = NULL;
4480                                 return rc;
4481                         } else
4482                                 psrch_inf->last_entry =
4483                                         psrch_inf->srch_entries_start + lnoff;
4484
4485 /*  cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4486     psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4487
4488                         /* BB fixme add unlock here */
4489                 }
4490
4491         }
4492
4493         /* BB On error, should we leave previous search buf (and count and
4494         last entry fields) intact or free the previous one? */
4495
4496         /* Note: On -EAGAIN error only caller can retry on handle based calls
4497         since file handle passed in no longer valid */
4498 FNext2_err_exit:
4499         if (rc != 0)
4500                 cifs_buf_release(pSMB);
4501         return rc;
4502 }
4503
4504 int
4505 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4506               const __u16 searchHandle)
4507 {
4508         int rc = 0;
4509         FINDCLOSE_REQ *pSMB = NULL;
4510
4511         cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4512         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4513
4514         /* no sense returning error if session restarted
4515                 as file handle has been closed */
4516         if (rc == -EAGAIN)
4517                 return 0;
4518         if (rc)
4519                 return rc;
4520
4521         pSMB->FileID = searchHandle;
4522         pSMB->ByteCount = 0;
4523         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4524         if (rc)
4525                 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4526
4527         cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4528
4529         /* Since session is dead, search handle closed on server already */
4530         if (rc == -EAGAIN)
4531                 rc = 0;
4532
4533         return rc;
4534 }
4535
4536 int
4537 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4538                       const char *search_name, __u64 *inode_number,
4539                       const struct nls_table *nls_codepage, int remap)
4540 {
4541         int rc = 0;
4542         TRANSACTION2_QPI_REQ *pSMB = NULL;
4543         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4544         int name_len, bytes_returned;
4545         __u16 params, byte_count;
4546
4547         cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4548         if (tcon == NULL)
4549                 return -ENODEV;
4550
4551 GetInodeNumberRetry:
4552         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4553                       (void **) &pSMBr);
4554         if (rc)
4555                 return rc;
4556
4557         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4558                 name_len =
4559                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4560                                            search_name, PATH_MAX, nls_codepage,
4561                                            remap);
4562                 name_len++;     /* trailing null */
4563                 name_len *= 2;
4564         } else {        /* BB improve the check for buffer overruns BB */
4565                 name_len = strnlen(search_name, PATH_MAX);
4566                 name_len++;     /* trailing null */
4567                 strncpy(pSMB->FileName, search_name, name_len);
4568         }
4569
4570         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4571         pSMB->TotalDataCount = 0;
4572         pSMB->MaxParameterCount = cpu_to_le16(2);
4573         /* BB find exact max data count below from sess structure BB */
4574         pSMB->MaxDataCount = cpu_to_le16(4000);
4575         pSMB->MaxSetupCount = 0;
4576         pSMB->Reserved = 0;
4577         pSMB->Flags = 0;
4578         pSMB->Timeout = 0;
4579         pSMB->Reserved2 = 0;
4580         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4581                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4582         pSMB->DataCount = 0;
4583         pSMB->DataOffset = 0;
4584         pSMB->SetupCount = 1;
4585         pSMB->Reserved3 = 0;
4586         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4587         byte_count = params + 1 /* pad */ ;
4588         pSMB->TotalParameterCount = cpu_to_le16(params);
4589         pSMB->ParameterCount = pSMB->TotalParameterCount;
4590         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4591         pSMB->Reserved4 = 0;
4592         inc_rfc1001_len(pSMB, byte_count);
4593         pSMB->ByteCount = cpu_to_le16(byte_count);
4594
4595         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4596                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4597         if (rc) {
4598                 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4599         } else {
4600                 /* decode response */
4601                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4602                 /* BB also check enough total bytes returned */
4603                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4604                         /* If rc should we check for EOPNOSUPP and
4605                         disable the srvino flag? or in caller? */
4606                         rc = -EIO;      /* bad smb */
4607                 else {
4608                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4609                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4610                         struct file_internal_info *pfinfo;
4611                         /* BB Do we need a cast or hash here ? */
4612                         if (count < 8) {
4613                                 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4614                                 rc = -EIO;
4615                                 goto GetInodeNumOut;
4616                         }
4617                         pfinfo = (struct file_internal_info *)
4618                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4619                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4620                 }
4621         }
4622 GetInodeNumOut:
4623         cifs_buf_release(pSMB);
4624         if (rc == -EAGAIN)
4625                 goto GetInodeNumberRetry;
4626         return rc;
4627 }
4628
4629 /* parses DFS refferal V3 structure
4630  * caller is responsible for freeing target_nodes
4631  * returns:
4632  *      on success - 0
4633  *      on failure - errno
4634  */
4635 static int
4636 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4637                 unsigned int *num_of_nodes,
4638                 struct dfs_info3_param **target_nodes,
4639                 const struct nls_table *nls_codepage, int remap,
4640                 const char *searchName)
4641 {
4642         int i, rc = 0;
4643         char *data_end;
4644         bool is_unicode;
4645         struct dfs_referral_level_3 *ref;
4646
4647         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4648                 is_unicode = true;
4649         else
4650                 is_unicode = false;
4651         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4652
4653         if (*num_of_nodes < 1) {
4654                 cifs_dbg(VFS, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4655                          *num_of_nodes);
4656                 rc = -EINVAL;
4657                 goto parse_DFS_referrals_exit;
4658         }
4659
4660         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4661         if (ref->VersionNumber != cpu_to_le16(3)) {
4662                 cifs_dbg(VFS, "Referrals of V%d version are not supported, should be V3\n",
4663                          le16_to_cpu(ref->VersionNumber));
4664                 rc = -EINVAL;
4665                 goto parse_DFS_referrals_exit;
4666         }
4667
4668         /* get the upper boundary of the resp buffer */
4669         data_end = (char *)(&(pSMBr->PathConsumed)) +
4670                                 le16_to_cpu(pSMBr->t2.DataCount);
4671
4672         cifs_dbg(FYI, "num_referrals: %d dfs flags: 0x%x ...\n",
4673                  *num_of_nodes, le32_to_cpu(pSMBr->DFSFlags));
4674
4675         *target_nodes = kcalloc(*num_of_nodes, sizeof(struct dfs_info3_param),
4676                                 GFP_KERNEL);
4677         if (*target_nodes == NULL) {
4678                 rc = -ENOMEM;
4679                 goto parse_DFS_referrals_exit;
4680         }
4681
4682         /* collect necessary data from referrals */
4683         for (i = 0; i < *num_of_nodes; i++) {
4684                 char *temp;
4685                 int max_len;
4686                 struct dfs_info3_param *node = (*target_nodes)+i;
4687
4688                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4689                 if (is_unicode) {
4690                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4691                                                 GFP_KERNEL);
4692                         if (tmp == NULL) {
4693                                 rc = -ENOMEM;
4694                                 goto parse_DFS_referrals_exit;
4695                         }
4696                         cifsConvertToUTF16((__le16 *) tmp, searchName,
4697                                            PATH_MAX, nls_codepage, remap);
4698                         node->path_consumed = cifs_utf16_bytes(tmp,
4699                                         le16_to_cpu(pSMBr->PathConsumed),
4700                                         nls_codepage);
4701                         kfree(tmp);
4702                 } else
4703                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4704
4705                 node->server_type = le16_to_cpu(ref->ServerType);
4706                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4707
4708                 /* copy DfsPath */
4709                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4710                 max_len = data_end - temp;
4711                 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4712                                                 is_unicode, nls_codepage);
4713                 if (!node->path_name) {
4714                         rc = -ENOMEM;
4715                         goto parse_DFS_referrals_exit;
4716                 }
4717
4718                 /* copy link target UNC */
4719                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4720                 max_len = data_end - temp;
4721                 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4722                                                 is_unicode, nls_codepage);
4723                 if (!node->node_name) {
4724                         rc = -ENOMEM;
4725                         goto parse_DFS_referrals_exit;
4726                 }
4727
4728                 ref++;
4729         }
4730
4731 parse_DFS_referrals_exit:
4732         if (rc) {
4733                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4734                 *target_nodes = NULL;
4735                 *num_of_nodes = 0;
4736         }
4737         return rc;
4738 }
4739
4740 int
4741 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4742                 const char *search_name, struct dfs_info3_param **target_nodes,
4743                 unsigned int *num_of_nodes,
4744                 const struct nls_table *nls_codepage, int remap)
4745 {
4746 /* TRANS2_GET_DFS_REFERRAL */
4747         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4748         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4749         int rc = 0;
4750         int bytes_returned;
4751         int name_len;
4752         __u16 params, byte_count;
4753         *num_of_nodes = 0;
4754         *target_nodes = NULL;
4755
4756         cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4757         if (ses == NULL)
4758                 return -ENODEV;
4759 getDFSRetry:
4760         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4761                       (void **) &pSMBr);
4762         if (rc)
4763                 return rc;
4764
4765         /* server pointer checked in called function,
4766         but should never be null here anyway */
4767         pSMB->hdr.Mid = get_next_mid(ses->server);
4768         pSMB->hdr.Tid = ses->ipc_tid;
4769         pSMB->hdr.Uid = ses->Suid;
4770         if (ses->capabilities & CAP_STATUS32)
4771                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4772         if (ses->capabilities & CAP_DFS)
4773                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4774
4775         if (ses->capabilities & CAP_UNICODE) {
4776                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4777                 name_len =
4778                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4779                                        search_name, PATH_MAX, nls_codepage,
4780                                        remap);
4781                 name_len++;     /* trailing null */
4782                 name_len *= 2;
4783         } else {        /* BB improve the check for buffer overruns BB */
4784                 name_len = strnlen(search_name, PATH_MAX);
4785                 name_len++;     /* trailing null */
4786                 strncpy(pSMB->RequestFileName, search_name, name_len);
4787         }
4788
4789         if (ses->server && ses->server->sign)
4790                 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4791
4792         pSMB->hdr.Uid = ses->Suid;
4793
4794         params = 2 /* level */  + name_len /*includes null */ ;
4795         pSMB->TotalDataCount = 0;
4796         pSMB->DataCount = 0;
4797         pSMB->DataOffset = 0;
4798         pSMB->MaxParameterCount = 0;
4799         /* BB find exact max SMB PDU from sess structure BB */
4800         pSMB->MaxDataCount = cpu_to_le16(4000);
4801         pSMB->MaxSetupCount = 0;
4802         pSMB->Reserved = 0;
4803         pSMB->Flags = 0;
4804         pSMB->Timeout = 0;
4805         pSMB->Reserved2 = 0;
4806         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4807           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4808         pSMB->SetupCount = 1;
4809         pSMB->Reserved3 = 0;
4810         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4811         byte_count = params + 3 /* pad */ ;
4812         pSMB->ParameterCount = cpu_to_le16(params);
4813         pSMB->TotalParameterCount = pSMB->ParameterCount;
4814         pSMB->MaxReferralLevel = cpu_to_le16(3);
4815         inc_rfc1001_len(pSMB, byte_count);
4816         pSMB->ByteCount = cpu_to_le16(byte_count);
4817
4818         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4819                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4820         if (rc) {
4821                 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4822                 goto GetDFSRefExit;
4823         }
4824         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4825
4826         /* BB Also check if enough total bytes returned? */
4827         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4828                 rc = -EIO;      /* bad smb */
4829                 goto GetDFSRefExit;
4830         }
4831
4832         cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4833                  get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4834
4835         /* parse returned result into more usable form */
4836         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4837                                  target_nodes, nls_codepage, remap,
4838                                  search_name);
4839
4840 GetDFSRefExit:
4841         cifs_buf_release(pSMB);
4842
4843         if (rc == -EAGAIN)
4844                 goto getDFSRetry;
4845
4846         return rc;
4847 }
4848
4849 /* Query File System Info such as free space to old servers such as Win 9x */
4850 int
4851 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4852               struct kstatfs *FSData)
4853 {
4854 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4855         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4856         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4857         FILE_SYSTEM_ALLOC_INFO *response_data;
4858         int rc = 0;
4859         int bytes_returned = 0;
4860         __u16 params, byte_count;
4861
4862         cifs_dbg(FYI, "OldQFSInfo\n");
4863 oldQFSInfoRetry:
4864         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4865                 (void **) &pSMBr);
4866         if (rc)
4867                 return rc;
4868
4869         params = 2;     /* level */
4870         pSMB->TotalDataCount = 0;
4871         pSMB->MaxParameterCount = cpu_to_le16(2);
4872         pSMB->MaxDataCount = cpu_to_le16(1000);
4873         pSMB->MaxSetupCount = 0;
4874         pSMB->Reserved = 0;
4875         pSMB->Flags = 0;
4876         pSMB->Timeout = 0;
4877         pSMB->Reserved2 = 0;
4878         byte_count = params + 1 /* pad */ ;
4879         pSMB->TotalParameterCount = cpu_to_le16(params);
4880         pSMB->ParameterCount = pSMB->TotalParameterCount;
4881         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4882         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4883         pSMB->DataCount = 0;
4884         pSMB->DataOffset = 0;
4885         pSMB->SetupCount = 1;
4886         pSMB->Reserved3 = 0;
4887         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4888         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4889         inc_rfc1001_len(pSMB, byte_count);
4890         pSMB->ByteCount = cpu_to_le16(byte_count);
4891
4892         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4893                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4894         if (rc) {
4895                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4896         } else {                /* decode response */
4897                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4898
4899                 if (rc || get_bcc(&pSMBr->hdr) < 18)
4900                         rc = -EIO;      /* bad smb */
4901                 else {
4902                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4903                         cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
4904                                  get_bcc(&pSMBr->hdr), data_offset);
4905
4906                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
4907                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4908                         FSData->f_bsize =
4909                                 le16_to_cpu(response_data->BytesPerSector) *
4910                                 le32_to_cpu(response_data->
4911                                         SectorsPerAllocationUnit);
4912                         FSData->f_blocks =
4913                                le32_to_cpu(response_data->TotalAllocationUnits);
4914                         FSData->f_bfree = FSData->f_bavail =
4915                                 le32_to_cpu(response_data->FreeAllocationUnits);
4916                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4917                                  (unsigned long long)FSData->f_blocks,
4918                                  (unsigned long long)FSData->f_bfree,
4919                                  FSData->f_bsize);
4920                 }
4921         }
4922         cifs_buf_release(pSMB);
4923
4924         if (rc == -EAGAIN)
4925                 goto oldQFSInfoRetry;
4926
4927         return rc;
4928 }
4929
4930 int
4931 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4932                struct kstatfs *FSData)
4933 {
4934 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4935         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4936         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4937         FILE_SYSTEM_INFO *response_data;
4938         int rc = 0;
4939         int bytes_returned = 0;
4940         __u16 params, byte_count;
4941
4942         cifs_dbg(FYI, "In QFSInfo\n");
4943 QFSInfoRetry:
4944         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4945                       (void **) &pSMBr);
4946         if (rc)
4947                 return rc;
4948
4949         params = 2;     /* level */
4950         pSMB->TotalDataCount = 0;
4951         pSMB->MaxParameterCount = cpu_to_le16(2);
4952         pSMB->MaxDataCount = cpu_to_le16(1000);
4953         pSMB->MaxSetupCount = 0;
4954         pSMB->Reserved = 0;
4955         pSMB->Flags = 0;
4956         pSMB->Timeout = 0;
4957         pSMB->Reserved2 = 0;
4958         byte_count = params + 1 /* pad */ ;
4959         pSMB->TotalParameterCount = cpu_to_le16(params);
4960         pSMB->ParameterCount = pSMB->TotalParameterCount;
4961         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4962                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4963         pSMB->DataCount = 0;
4964         pSMB->DataOffset = 0;
4965         pSMB->SetupCount = 1;
4966         pSMB->Reserved3 = 0;
4967         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4968         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4969         inc_rfc1001_len(pSMB, byte_count);
4970         pSMB->ByteCount = cpu_to_le16(byte_count);
4971
4972         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4973                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4974         if (rc) {
4975                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4976         } else {                /* decode response */
4977                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4978
4979                 if (rc || get_bcc(&pSMBr->hdr) < 24)
4980                         rc = -EIO;      /* bad smb */
4981                 else {
4982                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4983
4984                         response_data =
4985                             (FILE_SYSTEM_INFO
4986                              *) (((char *) &pSMBr->hdr.Protocol) +
4987                                  data_offset);
4988                         FSData->f_bsize =
4989                             le32_to_cpu(response_data->BytesPerSector) *
4990                             le32_to_cpu(response_data->
4991                                         SectorsPerAllocationUnit);
4992                         FSData->f_blocks =
4993                             le64_to_cpu(response_data->TotalAllocationUnits);
4994                         FSData->f_bfree = FSData->f_bavail =
4995                             le64_to_cpu(response_data->FreeAllocationUnits);
4996                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4997                                  (unsigned long long)FSData->f_blocks,
4998                                  (unsigned long long)FSData->f_bfree,
4999                                  FSData->f_bsize);
5000                 }
5001         }
5002         cifs_buf_release(pSMB);
5003
5004         if (rc == -EAGAIN)
5005                 goto QFSInfoRetry;
5006
5007         return rc;
5008 }
5009
5010 int
5011 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5012 {
5013 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5014         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5015         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5016         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5017         int rc = 0;
5018         int bytes_returned = 0;
5019         __u16 params, byte_count;
5020
5021         cifs_dbg(FYI, "In QFSAttributeInfo\n");
5022 QFSAttributeRetry:
5023         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5024                       (void **) &pSMBr);
5025         if (rc)
5026                 return rc;
5027
5028         params = 2;     /* level */
5029         pSMB->TotalDataCount = 0;
5030         pSMB->MaxParameterCount = cpu_to_le16(2);
5031         /* BB find exact max SMB PDU from sess structure BB */
5032         pSMB->MaxDataCount = cpu_to_le16(1000);
5033         pSMB->MaxSetupCount = 0;
5034         pSMB->Reserved = 0;
5035         pSMB->Flags = 0;
5036         pSMB->Timeout = 0;
5037         pSMB->Reserved2 = 0;
5038         byte_count = params + 1 /* pad */ ;
5039         pSMB->TotalParameterCount = cpu_to_le16(params);
5040         pSMB->ParameterCount = pSMB->TotalParameterCount;
5041         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5042                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5043         pSMB->DataCount = 0;
5044         pSMB->DataOffset = 0;
5045         pSMB->SetupCount = 1;
5046         pSMB->Reserved3 = 0;
5047         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5048         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5049         inc_rfc1001_len(pSMB, byte_count);
5050         pSMB->ByteCount = cpu_to_le16(byte_count);
5051
5052         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5053                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5054         if (rc) {
5055                 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5056         } else {                /* decode response */
5057                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5058
5059                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5060                         /* BB also check if enough bytes returned */
5061                         rc = -EIO;      /* bad smb */
5062                 } else {
5063                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5064                         response_data =
5065                             (FILE_SYSTEM_ATTRIBUTE_INFO
5066                              *) (((char *) &pSMBr->hdr.Protocol) +
5067                                  data_offset);
5068                         memcpy(&tcon->fsAttrInfo, response_data,
5069                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5070                 }
5071         }
5072         cifs_buf_release(pSMB);
5073
5074         if (rc == -EAGAIN)
5075                 goto QFSAttributeRetry;
5076
5077         return rc;
5078 }
5079
5080 int
5081 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5082 {
5083 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5084         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5085         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5086         FILE_SYSTEM_DEVICE_INFO *response_data;
5087         int rc = 0;
5088         int bytes_returned = 0;
5089         __u16 params, byte_count;
5090
5091         cifs_dbg(FYI, "In QFSDeviceInfo\n");
5092 QFSDeviceRetry:
5093         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5094                       (void **) &pSMBr);
5095         if (rc)
5096                 return rc;
5097
5098         params = 2;     /* level */
5099         pSMB->TotalDataCount = 0;
5100         pSMB->MaxParameterCount = cpu_to_le16(2);
5101         /* BB find exact max SMB PDU from sess structure BB */
5102         pSMB->MaxDataCount = cpu_to_le16(1000);
5103         pSMB->MaxSetupCount = 0;
5104         pSMB->Reserved = 0;
5105         pSMB->Flags = 0;
5106         pSMB->Timeout = 0;
5107         pSMB->Reserved2 = 0;
5108         byte_count = params + 1 /* pad */ ;
5109         pSMB->TotalParameterCount = cpu_to_le16(params);
5110         pSMB->ParameterCount = pSMB->TotalParameterCount;
5111         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5112                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5113
5114         pSMB->DataCount = 0;
5115         pSMB->DataOffset = 0;
5116         pSMB->SetupCount = 1;
5117         pSMB->Reserved3 = 0;
5118         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5119         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5120         inc_rfc1001_len(pSMB, byte_count);
5121         pSMB->ByteCount = cpu_to_le16(byte_count);
5122
5123         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5124                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5125         if (rc) {
5126                 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5127         } else {                /* decode response */
5128                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5129
5130                 if (rc || get_bcc(&pSMBr->hdr) <
5131                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5132                         rc = -EIO;      /* bad smb */
5133                 else {
5134                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5135                         response_data =
5136                             (FILE_SYSTEM_DEVICE_INFO *)
5137                                 (((char *) &pSMBr->hdr.Protocol) +
5138                                  data_offset);
5139                         memcpy(&tcon->fsDevInfo, response_data,
5140                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5141                 }
5142         }
5143         cifs_buf_release(pSMB);
5144
5145         if (rc == -EAGAIN)
5146                 goto QFSDeviceRetry;
5147
5148         return rc;
5149 }
5150
5151 int
5152 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5153 {
5154 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5155         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5156         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5157         FILE_SYSTEM_UNIX_INFO *response_data;
5158         int rc = 0;
5159         int bytes_returned = 0;
5160         __u16 params, byte_count;
5161
5162         cifs_dbg(FYI, "In QFSUnixInfo\n");
5163 QFSUnixRetry:
5164         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5165                                    (void **) &pSMB, (void **) &pSMBr);
5166         if (rc)
5167                 return rc;
5168
5169         params = 2;     /* level */
5170         pSMB->TotalDataCount = 0;
5171         pSMB->DataCount = 0;
5172         pSMB->DataOffset = 0;
5173         pSMB->MaxParameterCount = cpu_to_le16(2);
5174         /* BB find exact max SMB PDU from sess structure BB */
5175         pSMB->MaxDataCount = cpu_to_le16(100);
5176         pSMB->MaxSetupCount = 0;
5177         pSMB->Reserved = 0;
5178         pSMB->Flags = 0;
5179         pSMB->Timeout = 0;
5180         pSMB->Reserved2 = 0;
5181         byte_count = params + 1 /* pad */ ;
5182         pSMB->ParameterCount = cpu_to_le16(params);
5183         pSMB->TotalParameterCount = pSMB->ParameterCount;
5184         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5185                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5186         pSMB->SetupCount = 1;
5187         pSMB->Reserved3 = 0;
5188         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5189         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5190         inc_rfc1001_len(pSMB, byte_count);
5191         pSMB->ByteCount = cpu_to_le16(byte_count);
5192
5193         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5194                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5195         if (rc) {
5196                 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5197         } else {                /* decode response */
5198                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5199
5200                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5201                         rc = -EIO;      /* bad smb */
5202                 } else {
5203                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5204                         response_data =
5205                             (FILE_SYSTEM_UNIX_INFO
5206                              *) (((char *) &pSMBr->hdr.Protocol) +
5207                                  data_offset);
5208                         memcpy(&tcon->fsUnixInfo, response_data,
5209                                sizeof(FILE_SYSTEM_UNIX_INFO));
5210                 }
5211         }
5212         cifs_buf_release(pSMB);
5213
5214         if (rc == -EAGAIN)
5215                 goto QFSUnixRetry;
5216
5217
5218         return rc;
5219 }
5220
5221 int
5222 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5223 {
5224 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5225         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5226         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5227         int rc = 0;
5228         int bytes_returned = 0;
5229         __u16 params, param_offset, offset, byte_count;
5230
5231         cifs_dbg(FYI, "In SETFSUnixInfo\n");
5232 SETFSUnixRetry:
5233         /* BB switch to small buf init to save memory */
5234         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5235                                         (void **) &pSMB, (void **) &pSMBr);
5236         if (rc)
5237                 return rc;
5238
5239         params = 4;     /* 2 bytes zero followed by info level. */
5240         pSMB->MaxSetupCount = 0;
5241         pSMB->Reserved = 0;
5242         pSMB->Flags = 0;
5243         pSMB->Timeout = 0;
5244         pSMB->Reserved2 = 0;
5245         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5246                                 - 4;
5247         offset = param_offset + params;
5248
5249         pSMB->MaxParameterCount = cpu_to_le16(4);
5250         /* BB find exact max SMB PDU from sess structure BB */
5251         pSMB->MaxDataCount = cpu_to_le16(100);
5252         pSMB->SetupCount = 1;
5253         pSMB->Reserved3 = 0;
5254         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5255         byte_count = 1 /* pad */ + params + 12;
5256
5257         pSMB->DataCount = cpu_to_le16(12);
5258         pSMB->ParameterCount = cpu_to_le16(params);
5259         pSMB->TotalDataCount = pSMB->DataCount;
5260         pSMB->TotalParameterCount = pSMB->ParameterCount;
5261         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5262         pSMB->DataOffset = cpu_to_le16(offset);
5263
5264         /* Params. */
5265         pSMB->FileNum = 0;
5266         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5267
5268         /* Data. */
5269         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5270         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5271         pSMB->ClientUnixCap = cpu_to_le64(cap);
5272
5273         inc_rfc1001_len(pSMB, byte_count);
5274         pSMB->ByteCount = cpu_to_le16(byte_count);
5275
5276         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5277                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5278         if (rc) {
5279                 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5280         } else {                /* decode response */
5281                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5282                 if (rc)
5283                         rc = -EIO;      /* bad smb */
5284         }
5285         cifs_buf_release(pSMB);
5286
5287         if (rc == -EAGAIN)
5288                 goto SETFSUnixRetry;
5289
5290         return rc;
5291 }
5292
5293
5294
5295 int
5296 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5297                    struct kstatfs *FSData)
5298 {
5299 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5300         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5301         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5302         FILE_SYSTEM_POSIX_INFO *response_data;
5303         int rc = 0;
5304         int bytes_returned = 0;
5305         __u16 params, byte_count;
5306
5307         cifs_dbg(FYI, "In QFSPosixInfo\n");
5308 QFSPosixRetry:
5309         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5310                       (void **) &pSMBr);
5311         if (rc)
5312                 return rc;
5313
5314         params = 2;     /* level */
5315         pSMB->TotalDataCount = 0;
5316         pSMB->DataCount = 0;
5317         pSMB->DataOffset = 0;
5318         pSMB->MaxParameterCount = cpu_to_le16(2);
5319         /* BB find exact max SMB PDU from sess structure BB */
5320         pSMB->MaxDataCount = cpu_to_le16(100);
5321         pSMB->MaxSetupCount = 0;
5322         pSMB->Reserved = 0;
5323         pSMB->Flags = 0;
5324         pSMB->Timeout = 0;
5325         pSMB->Reserved2 = 0;
5326         byte_count = params + 1 /* pad */ ;
5327         pSMB->ParameterCount = cpu_to_le16(params);
5328         pSMB->TotalParameterCount = pSMB->ParameterCount;
5329         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5330                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5331         pSMB->SetupCount = 1;
5332         pSMB->Reserved3 = 0;
5333         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5334         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5335         inc_rfc1001_len(pSMB, byte_count);
5336         pSMB->ByteCount = cpu_to_le16(byte_count);
5337
5338         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5339                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5340         if (rc) {
5341                 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5342         } else {                /* decode response */
5343                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5344
5345                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5346                         rc = -EIO;      /* bad smb */
5347                 } else {
5348                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5349                         response_data =
5350                             (FILE_SYSTEM_POSIX_INFO
5351                              *) (((char *) &pSMBr->hdr.Protocol) +
5352                                  data_offset);
5353                         FSData->f_bsize =
5354                                         le32_to_cpu(response_data->BlockSize);
5355                         FSData->f_blocks =
5356                                         le64_to_cpu(response_data->TotalBlocks);
5357                         FSData->f_bfree =
5358                             le64_to_cpu(response_data->BlocksAvail);
5359                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5360                                 FSData->f_bavail = FSData->f_bfree;
5361                         } else {
5362                                 FSData->f_bavail =
5363                                     le64_to_cpu(response_data->UserBlocksAvail);
5364                         }
5365                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5366                                 FSData->f_files =
5367                                      le64_to_cpu(response_data->TotalFileNodes);
5368                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5369                                 FSData->f_ffree =
5370                                       le64_to_cpu(response_data->FreeFileNodes);
5371                 }
5372         }
5373         cifs_buf_release(pSMB);
5374
5375         if (rc == -EAGAIN)
5376                 goto QFSPosixRetry;
5377
5378         return rc;
5379 }
5380
5381
5382 /*
5383  * We can not use write of zero bytes trick to set file size due to need for
5384  * large file support. Also note that this SetPathInfo is preferred to
5385  * SetFileInfo based method in next routine which is only needed to work around
5386  * a sharing violation bugin Samba which this routine can run into.
5387  */
5388 int
5389 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5390               const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5391               bool set_allocation)
5392 {
5393         struct smb_com_transaction2_spi_req *pSMB = NULL;
5394         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5395         struct file_end_of_file_info *parm_data;
5396         int name_len;
5397         int rc = 0;
5398         int bytes_returned = 0;
5399         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
5400
5401         __u16 params, byte_count, data_count, param_offset, offset;
5402
5403         cifs_dbg(FYI, "In SetEOF\n");
5404 SetEOFRetry:
5405         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5406                       (void **) &pSMBr);
5407         if (rc)
5408                 return rc;
5409
5410         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5411                 name_len =
5412                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5413                                        PATH_MAX, cifs_sb->local_nls, remap);
5414                 name_len++;     /* trailing null */
5415                 name_len *= 2;
5416         } else {        /* BB improve the check for buffer overruns BB */
5417                 name_len = strnlen(file_name, PATH_MAX);
5418                 name_len++;     /* trailing null */
5419                 strncpy(pSMB->FileName, file_name, name_len);
5420         }
5421         params = 6 + name_len;
5422         data_count = sizeof(struct file_end_of_file_info);
5423         pSMB->MaxParameterCount = cpu_to_le16(2);
5424         pSMB->MaxDataCount = cpu_to_le16(4100);
5425         pSMB->MaxSetupCount = 0;
5426         pSMB->Reserved = 0;
5427         pSMB->Flags = 0;
5428         pSMB->Timeout = 0;
5429         pSMB->Reserved2 = 0;
5430         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5431                                 InformationLevel) - 4;
5432         offset = param_offset + params;
5433         if (set_allocation) {
5434                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5435                         pSMB->InformationLevel =
5436                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5437                 else
5438                         pSMB->InformationLevel =
5439                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5440         } else /* Set File Size */  {
5441             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5442                     pSMB->InformationLevel =
5443                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5444             else
5445                     pSMB->InformationLevel =
5446                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5447         }
5448
5449         parm_data =
5450             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5451                                        offset);
5452         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5453         pSMB->DataOffset = cpu_to_le16(offset);
5454         pSMB->SetupCount = 1;
5455         pSMB->Reserved3 = 0;
5456         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5457         byte_count = 3 /* pad */  + params + data_count;
5458         pSMB->DataCount = cpu_to_le16(data_count);
5459         pSMB->TotalDataCount = pSMB->DataCount;
5460         pSMB->ParameterCount = cpu_to_le16(params);
5461         pSMB->TotalParameterCount = pSMB->ParameterCount;
5462         pSMB->Reserved4 = 0;
5463         inc_rfc1001_len(pSMB, byte_count);
5464         parm_data->FileSize = cpu_to_le64(size);
5465         pSMB->ByteCount = cpu_to_le16(byte_count);
5466         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5467                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5468         if (rc)
5469                 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5470
5471         cifs_buf_release(pSMB);
5472
5473         if (rc == -EAGAIN)
5474                 goto SetEOFRetry;
5475
5476         return rc;
5477 }
5478
5479 int
5480 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5481                    struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5482 {
5483         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5484         struct file_end_of_file_info *parm_data;
5485         int rc = 0;
5486         __u16 params, param_offset, offset, byte_count, count;
5487
5488         cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5489                  (long long)size);
5490         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5491
5492         if (rc)
5493                 return rc;
5494
5495         pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5496         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5497
5498         params = 6;
5499         pSMB->MaxSetupCount = 0;
5500         pSMB->Reserved = 0;
5501         pSMB->Flags = 0;
5502         pSMB->Timeout = 0;
5503         pSMB->Reserved2 = 0;
5504         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5505         offset = param_offset + params;
5506
5507         count = sizeof(struct file_end_of_file_info);
5508         pSMB->MaxParameterCount = cpu_to_le16(2);
5509         /* BB find exact max SMB PDU from sess structure BB */
5510         pSMB->MaxDataCount = cpu_to_le16(1000);
5511         pSMB->SetupCount = 1;
5512         pSMB->Reserved3 = 0;
5513         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5514         byte_count = 3 /* pad */  + params + count;
5515         pSMB->DataCount = cpu_to_le16(count);
5516         pSMB->ParameterCount = cpu_to_le16(params);
5517         pSMB->TotalDataCount = pSMB->DataCount;
5518         pSMB->TotalParameterCount = pSMB->ParameterCount;
5519         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5520         parm_data =
5521                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5522                                 + offset);
5523         pSMB->DataOffset = cpu_to_le16(offset);
5524         parm_data->FileSize = cpu_to_le64(size);
5525         pSMB->Fid = cfile->fid.netfid;
5526         if (set_allocation) {
5527                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5528                         pSMB->InformationLevel =
5529                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5530                 else
5531                         pSMB->InformationLevel =
5532                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5533         } else /* Set File Size */  {
5534             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5535                     pSMB->InformationLevel =
5536                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5537             else
5538                     pSMB->InformationLevel =
5539                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5540         }
5541         pSMB->Reserved4 = 0;
5542         inc_rfc1001_len(pSMB, byte_count);
5543         pSMB->ByteCount = cpu_to_le16(byte_count);
5544         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5545         if (rc) {
5546                 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5547                          rc);
5548         }
5549
5550         /* Note: On -EAGAIN error only caller can retry on handle based calls
5551                 since file handle passed in no longer valid */
5552
5553         return rc;
5554 }
5555
5556 /* Some legacy servers such as NT4 require that the file times be set on
5557    an open handle, rather than by pathname - this is awkward due to
5558    potential access conflicts on the open, but it is unavoidable for these
5559    old servers since the only other choice is to go from 100 nanosecond DCE
5560    time and resort to the original setpathinfo level which takes the ancient
5561    DOS time format with 2 second granularity */
5562 int
5563 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5564                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5565 {
5566         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5567         char *data_offset;
5568         int rc = 0;
5569         __u16 params, param_offset, offset, byte_count, count;
5570
5571         cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5572         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5573
5574         if (rc)
5575                 return rc;
5576
5577         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5578         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5579
5580         params = 6;
5581         pSMB->MaxSetupCount = 0;
5582         pSMB->Reserved = 0;
5583         pSMB->Flags = 0;
5584         pSMB->Timeout = 0;
5585         pSMB->Reserved2 = 0;
5586         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5587         offset = param_offset + params;
5588
5589         data_offset = (char *)pSMB +
5590                         offsetof(struct smb_hdr, Protocol) + offset;
5591
5592         count = sizeof(FILE_BASIC_INFO);
5593         pSMB->MaxParameterCount = cpu_to_le16(2);
5594         /* BB find max SMB PDU from sess */
5595         pSMB->MaxDataCount = cpu_to_le16(1000);
5596         pSMB->SetupCount = 1;
5597         pSMB->Reserved3 = 0;
5598         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5599         byte_count = 3 /* pad */  + params + count;
5600         pSMB->DataCount = cpu_to_le16(count);
5601         pSMB->ParameterCount = cpu_to_le16(params);
5602         pSMB->TotalDataCount = pSMB->DataCount;
5603         pSMB->TotalParameterCount = pSMB->ParameterCount;
5604         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5605         pSMB->DataOffset = cpu_to_le16(offset);
5606         pSMB->Fid = fid;
5607         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5608                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5609         else
5610                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5611         pSMB->Reserved4 = 0;
5612         inc_rfc1001_len(pSMB, byte_count);
5613         pSMB->ByteCount = cpu_to_le16(byte_count);
5614         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5615         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5616         if (rc)
5617                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5618                          rc);
5619
5620         /* Note: On -EAGAIN error only caller can retry on handle based calls
5621                 since file handle passed in no longer valid */
5622
5623         return rc;
5624 }
5625
5626 int
5627 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5628                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5629 {
5630         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5631         char *data_offset;
5632         int rc = 0;
5633         __u16 params, param_offset, offset, byte_count, count;
5634
5635         cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5636         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5637
5638         if (rc)
5639                 return rc;
5640
5641         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5642         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5643
5644         params = 6;
5645         pSMB->MaxSetupCount = 0;
5646         pSMB->Reserved = 0;
5647         pSMB->Flags = 0;
5648         pSMB->Timeout = 0;
5649         pSMB->Reserved2 = 0;
5650         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5651         offset = param_offset + params;
5652
5653         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5654
5655         count = 1;
5656         pSMB->MaxParameterCount = cpu_to_le16(2);
5657         /* BB find max SMB PDU from sess */
5658         pSMB->MaxDataCount = cpu_to_le16(1000);
5659         pSMB->SetupCount = 1;
5660         pSMB->Reserved3 = 0;
5661         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5662         byte_count = 3 /* pad */  + params + count;
5663         pSMB->DataCount = cpu_to_le16(count);
5664         pSMB->ParameterCount = cpu_to_le16(params);
5665         pSMB->TotalDataCount = pSMB->DataCount;
5666         pSMB->TotalParameterCount = pSMB->ParameterCount;
5667         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5668         pSMB->DataOffset = cpu_to_le16(offset);
5669         pSMB->Fid = fid;
5670         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5671         pSMB->Reserved4 = 0;
5672         inc_rfc1001_len(pSMB, byte_count);
5673         pSMB->ByteCount = cpu_to_le16(byte_count);
5674         *data_offset = delete_file ? 1 : 0;
5675         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5676         if (rc)
5677                 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5678
5679         return rc;
5680 }
5681
5682 int
5683 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5684                    const char *fileName, const FILE_BASIC_INFO *data,
5685                    const struct nls_table *nls_codepage, int remap)
5686 {
5687         TRANSACTION2_SPI_REQ *pSMB = NULL;
5688         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5689         int name_len;
5690         int rc = 0;
5691         int bytes_returned = 0;
5692         char *data_offset;
5693         __u16 params, param_offset, offset, byte_count, count;
5694
5695         cifs_dbg(FYI, "In SetTimes\n");
5696
5697 SetTimesRetry:
5698         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5699                       (void **) &pSMBr);
5700         if (rc)
5701                 return rc;
5702
5703         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5704                 name_len =
5705                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5706                                        PATH_MAX, nls_codepage, remap);
5707                 name_len++;     /* trailing null */
5708                 name_len *= 2;
5709         } else {        /* BB improve the check for buffer overruns BB */
5710                 name_len = strnlen(fileName, PATH_MAX);
5711                 name_len++;     /* trailing null */
5712                 strncpy(pSMB->FileName, fileName, name_len);
5713         }
5714
5715         params = 6 + name_len;
5716         count = sizeof(FILE_BASIC_INFO);
5717         pSMB->MaxParameterCount = cpu_to_le16(2);
5718         /* BB find max SMB PDU from sess structure BB */
5719         pSMB->MaxDataCount = cpu_to_le16(1000);
5720         pSMB->MaxSetupCount = 0;
5721         pSMB->Reserved = 0;
5722         pSMB->Flags = 0;
5723         pSMB->Timeout = 0;
5724         pSMB->Reserved2 = 0;
5725         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5726                                 InformationLevel) - 4;
5727         offset = param_offset + params;
5728         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5729         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5730         pSMB->DataOffset = cpu_to_le16(offset);
5731         pSMB->SetupCount = 1;
5732         pSMB->Reserved3 = 0;
5733         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5734         byte_count = 3 /* pad */  + params + count;
5735
5736         pSMB->DataCount = cpu_to_le16(count);
5737         pSMB->ParameterCount = cpu_to_le16(params);
5738         pSMB->TotalDataCount = pSMB->DataCount;
5739         pSMB->TotalParameterCount = pSMB->ParameterCount;
5740         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5741                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5742         else
5743                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5744         pSMB->Reserved4 = 0;
5745         inc_rfc1001_len(pSMB, byte_count);
5746         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5747         pSMB->ByteCount = cpu_to_le16(byte_count);
5748         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5749                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5750         if (rc)
5751                 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5752
5753         cifs_buf_release(pSMB);
5754
5755         if (rc == -EAGAIN)
5756                 goto SetTimesRetry;
5757
5758         return rc;
5759 }
5760
5761 /* Can not be used to set time stamps yet (due to old DOS time format) */
5762 /* Can be used to set attributes */
5763 #if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
5764           handling it anyway and NT4 was what we thought it would be needed for
5765           Do not delete it until we prove whether needed for Win9x though */
5766 int
5767 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5768                 __u16 dos_attrs, const struct nls_table *nls_codepage)
5769 {
5770         SETATTR_REQ *pSMB = NULL;
5771         SETATTR_RSP *pSMBr = NULL;
5772         int rc = 0;
5773         int bytes_returned;
5774         int name_len;
5775
5776         cifs_dbg(FYI, "In SetAttrLegacy\n");
5777
5778 SetAttrLgcyRetry:
5779         rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5780                       (void **) &pSMBr);
5781         if (rc)
5782                 return rc;
5783
5784         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5785                 name_len =
5786                         ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5787                                        PATH_MAX, nls_codepage);
5788                 name_len++;     /* trailing null */
5789                 name_len *= 2;
5790         } else {        /* BB improve the check for buffer overruns BB */
5791                 name_len = strnlen(fileName, PATH_MAX);
5792                 name_len++;     /* trailing null */
5793                 strncpy(pSMB->fileName, fileName, name_len);
5794         }
5795         pSMB->attr = cpu_to_le16(dos_attrs);
5796         pSMB->BufferFormat = 0x04;
5797         inc_rfc1001_len(pSMB, name_len + 1);
5798         pSMB->ByteCount = cpu_to_le16(name_len + 1);
5799         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5800                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5801         if (rc)
5802                 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
5803
5804         cifs_buf_release(pSMB);
5805
5806         if (rc == -EAGAIN)
5807                 goto SetAttrLgcyRetry;
5808
5809         return rc;
5810 }
5811 #endif /* temporarily unneeded SetAttr legacy function */
5812
5813 static void
5814 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5815                         const struct cifs_unix_set_info_args *args)
5816 {
5817         u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5818         u64 mode = args->mode;
5819
5820         if (uid_valid(args->uid))
5821                 uid = from_kuid(&init_user_ns, args->uid);
5822         if (gid_valid(args->gid))
5823                 gid = from_kgid(&init_user_ns, args->gid);
5824
5825         /*
5826          * Samba server ignores set of file size to zero due to bugs in some
5827          * older clients, but we should be precise - we use SetFileSize to
5828          * set file size and do not want to truncate file size to zero
5829          * accidentally as happened on one Samba server beta by putting
5830          * zero instead of -1 here
5831          */
5832         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5833         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5834         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5835         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5836         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5837         data_offset->Uid = cpu_to_le64(uid);
5838         data_offset->Gid = cpu_to_le64(gid);
5839         /* better to leave device as zero when it is  */
5840         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5841         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5842         data_offset->Permissions = cpu_to_le64(mode);
5843
5844         if (S_ISREG(mode))
5845                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5846         else if (S_ISDIR(mode))
5847                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5848         else if (S_ISLNK(mode))
5849                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5850         else if (S_ISCHR(mode))
5851                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5852         else if (S_ISBLK(mode))
5853                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5854         else if (S_ISFIFO(mode))
5855                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5856         else if (S_ISSOCK(mode))
5857                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5858 }
5859
5860 int
5861 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5862                        const struct cifs_unix_set_info_args *args,
5863                        u16 fid, u32 pid_of_opener)
5864 {
5865         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5866         char *data_offset;
5867         int rc = 0;
5868         u16 params, param_offset, offset, byte_count, count;
5869
5870         cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5871         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5872
5873         if (rc)
5874                 return rc;
5875
5876         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5877         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5878
5879         params = 6;
5880         pSMB->MaxSetupCount = 0;
5881         pSMB->Reserved = 0;
5882         pSMB->Flags = 0;
5883         pSMB->Timeout = 0;
5884         pSMB->Reserved2 = 0;
5885         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5886         offset = param_offset + params;
5887
5888         data_offset = (char *)pSMB +
5889                         offsetof(struct smb_hdr, Protocol) + offset;
5890
5891         count = sizeof(FILE_UNIX_BASIC_INFO);
5892
5893         pSMB->MaxParameterCount = cpu_to_le16(2);
5894         /* BB find max SMB PDU from sess */
5895         pSMB->MaxDataCount = cpu_to_le16(1000);
5896         pSMB->SetupCount = 1;
5897         pSMB->Reserved3 = 0;
5898         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5899         byte_count = 3 /* pad */  + params + count;
5900         pSMB->DataCount = cpu_to_le16(count);
5901         pSMB->ParameterCount = cpu_to_le16(params);
5902         pSMB->TotalDataCount = pSMB->DataCount;
5903         pSMB->TotalParameterCount = pSMB->ParameterCount;
5904         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5905         pSMB->DataOffset = cpu_to_le16(offset);
5906         pSMB->Fid = fid;
5907         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5908         pSMB->Reserved4 = 0;
5909         inc_rfc1001_len(pSMB, byte_count);
5910         pSMB->ByteCount = cpu_to_le16(byte_count);
5911
5912         cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5913
5914         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5915         if (rc)
5916                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5917                          rc);
5918
5919         /* Note: On -EAGAIN error only caller can retry on handle based calls
5920                 since file handle passed in no longer valid */
5921
5922         return rc;
5923 }
5924
5925 int
5926 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5927                        const char *file_name,
5928                        const struct cifs_unix_set_info_args *args,
5929                        const struct nls_table *nls_codepage, int remap)
5930 {
5931         TRANSACTION2_SPI_REQ *pSMB = NULL;
5932         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5933         int name_len;
5934         int rc = 0;
5935         int bytes_returned = 0;
5936         FILE_UNIX_BASIC_INFO *data_offset;
5937         __u16 params, param_offset, offset, count, byte_count;
5938
5939         cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5940 setPermsRetry:
5941         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5942                       (void **) &pSMBr);
5943         if (rc)
5944                 return rc;
5945
5946         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5947                 name_len =
5948                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5949                                        PATH_MAX, nls_codepage, remap);
5950                 name_len++;     /* trailing null */
5951                 name_len *= 2;
5952         } else {        /* BB improve the check for buffer overruns BB */
5953                 name_len = strnlen(file_name, PATH_MAX);
5954                 name_len++;     /* trailing null */
5955                 strncpy(pSMB->FileName, file_name, name_len);
5956         }
5957
5958         params = 6 + name_len;
5959         count = sizeof(FILE_UNIX_BASIC_INFO);
5960         pSMB->MaxParameterCount = cpu_to_le16(2);
5961         /* BB find max SMB PDU from sess structure BB */
5962         pSMB->MaxDataCount = cpu_to_le16(1000);
5963         pSMB->MaxSetupCount = 0;
5964         pSMB->Reserved = 0;
5965         pSMB->Flags = 0;
5966         pSMB->Timeout = 0;
5967         pSMB->Reserved2 = 0;
5968         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5969                                 InformationLevel) - 4;
5970         offset = param_offset + params;
5971         data_offset =
5972             (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
5973                                       offset);
5974         memset(data_offset, 0, count);
5975         pSMB->DataOffset = cpu_to_le16(offset);
5976         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5977         pSMB->SetupCount = 1;
5978         pSMB->Reserved3 = 0;
5979         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5980         byte_count = 3 /* pad */  + params + count;
5981         pSMB->ParameterCount = cpu_to_le16(params);
5982         pSMB->DataCount = cpu_to_le16(count);
5983         pSMB->TotalParameterCount = pSMB->ParameterCount;
5984         pSMB->TotalDataCount = pSMB->DataCount;
5985         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5986         pSMB->Reserved4 = 0;
5987         inc_rfc1001_len(pSMB, byte_count);
5988
5989         cifs_fill_unix_set_info(data_offset, args);
5990
5991         pSMB->ByteCount = cpu_to_le16(byte_count);
5992         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5993                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5994         if (rc)
5995                 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5996
5997         cifs_buf_release(pSMB);
5998         if (rc == -EAGAIN)
5999                 goto setPermsRetry;
6000         return rc;
6001 }
6002
6003 #ifdef CONFIG_CIFS_XATTR
6004 /*
6005  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6006  * function used by listxattr and getxattr type calls. When ea_name is set,
6007  * it looks for that attribute name and stuffs that value into the EAData
6008  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6009  * buffer. In both cases, the return value is either the length of the
6010  * resulting data or a negative error code. If EAData is a NULL pointer then
6011  * the data isn't copied to it, but the length is returned.
6012  */
6013 ssize_t
6014 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6015                 const unsigned char *searchName, const unsigned char *ea_name,
6016                 char *EAData, size_t buf_size,
6017                 const struct nls_table *nls_codepage, int remap)
6018 {
6019                 /* BB assumes one setup word */
6020         TRANSACTION2_QPI_REQ *pSMB = NULL;
6021         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6022         int rc = 0;
6023         int bytes_returned;
6024         int list_len;
6025         struct fealist *ea_response_data;
6026         struct fea *temp_fea;
6027         char *temp_ptr;
6028         char *end_of_smb;
6029         __u16 params, byte_count, data_offset;
6030         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6031
6032         cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6033 QAllEAsRetry:
6034         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6035                       (void **) &pSMBr);
6036         if (rc)
6037                 return rc;
6038
6039         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6040                 list_len =
6041                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6042                                        PATH_MAX, nls_codepage, remap);
6043                 list_len++;     /* trailing null */
6044                 list_len *= 2;
6045         } else {        /* BB improve the check for buffer overruns BB */
6046                 list_len = strnlen(searchName, PATH_MAX);
6047                 list_len++;     /* trailing null */
6048                 strncpy(pSMB->FileName, searchName, list_len);
6049         }
6050
6051         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6052         pSMB->TotalDataCount = 0;
6053         pSMB->MaxParameterCount = cpu_to_le16(2);
6054         /* BB find exact max SMB PDU from sess structure BB */
6055         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6056         pSMB->MaxSetupCount = 0;
6057         pSMB->Reserved = 0;
6058         pSMB->Flags = 0;
6059         pSMB->Timeout = 0;
6060         pSMB->Reserved2 = 0;
6061         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6062         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6063         pSMB->DataCount = 0;
6064         pSMB->DataOffset = 0;
6065         pSMB->SetupCount = 1;
6066         pSMB->Reserved3 = 0;
6067         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6068         byte_count = params + 1 /* pad */ ;
6069         pSMB->TotalParameterCount = cpu_to_le16(params);
6070         pSMB->ParameterCount = pSMB->TotalParameterCount;
6071         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6072         pSMB->Reserved4 = 0;
6073         inc_rfc1001_len(pSMB, byte_count);
6074         pSMB->ByteCount = cpu_to_le16(byte_count);
6075
6076         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6077                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6078         if (rc) {
6079                 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6080                 goto QAllEAsOut;
6081         }
6082
6083
6084         /* BB also check enough total bytes returned */
6085         /* BB we need to improve the validity checking
6086         of these trans2 responses */
6087
6088         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6089         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6090                 rc = -EIO;      /* bad smb */
6091                 goto QAllEAsOut;
6092         }
6093
6094         /* check that length of list is not more than bcc */
6095         /* check that each entry does not go beyond length
6096            of list */
6097         /* check that each element of each entry does not
6098            go beyond end of list */
6099         /* validate_trans2_offsets() */
6100         /* BB check if start of smb + data_offset > &bcc+ bcc */
6101
6102         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6103         ea_response_data = (struct fealist *)
6104                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6105
6106         list_len = le32_to_cpu(ea_response_data->list_len);
6107         cifs_dbg(FYI, "ea length %d\n", list_len);
6108         if (list_len <= 8) {
6109                 cifs_dbg(FYI, "empty EA list returned from server\n");
6110                 goto QAllEAsOut;
6111         }
6112
6113         /* make sure list_len doesn't go past end of SMB */
6114         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6115         if ((char *)ea_response_data + list_len > end_of_smb) {
6116                 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6117                 rc = -EIO;
6118                 goto QAllEAsOut;
6119         }
6120
6121         /* account for ea list len */
6122         list_len -= 4;
6123         temp_fea = ea_response_data->list;
6124         temp_ptr = (char *)temp_fea;
6125         while (list_len > 0) {
6126                 unsigned int name_len;
6127                 __u16 value_len;
6128
6129                 list_len -= 4;
6130                 temp_ptr += 4;
6131                 /* make sure we can read name_len and value_len */
6132                 if (list_len < 0) {
6133                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6134                         rc = -EIO;
6135                         goto QAllEAsOut;
6136                 }
6137
6138                 name_len = temp_fea->name_len;
6139                 value_len = le16_to_cpu(temp_fea->value_len);
6140                 list_len -= name_len + 1 + value_len;
6141                 if (list_len < 0) {
6142                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6143                         rc = -EIO;
6144                         goto QAllEAsOut;
6145                 }
6146
6147                 if (ea_name) {
6148                         if (ea_name_len == name_len &&
6149                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6150                                 temp_ptr += name_len + 1;
6151                                 rc = value_len;
6152                                 if (buf_size == 0)
6153                                         goto QAllEAsOut;
6154                                 if ((size_t)value_len > buf_size) {
6155                                         rc = -ERANGE;
6156                                         goto QAllEAsOut;
6157                                 }
6158                                 memcpy(EAData, temp_ptr, value_len);
6159                                 goto QAllEAsOut;
6160                         }
6161                 } else {
6162                         /* account for prefix user. and trailing null */
6163                         rc += (5 + 1 + name_len);
6164                         if (rc < (int) buf_size) {
6165                                 memcpy(EAData, "user.", 5);
6166                                 EAData += 5;
6167                                 memcpy(EAData, temp_ptr, name_len);
6168                                 EAData += name_len;
6169                                 /* null terminate name */
6170                                 *EAData = 0;
6171                                 ++EAData;
6172                         } else if (buf_size == 0) {
6173                                 /* skip copy - calc size only */
6174                         } else {
6175                                 /* stop before overrun buffer */
6176                                 rc = -ERANGE;
6177                                 break;
6178                         }
6179                 }
6180                 temp_ptr += name_len + 1 + value_len;
6181                 temp_fea = (struct fea *)temp_ptr;
6182         }
6183
6184         /* didn't find the named attribute */
6185         if (ea_name)
6186                 rc = -ENODATA;
6187
6188 QAllEAsOut:
6189         cifs_buf_release(pSMB);
6190         if (rc == -EAGAIN)
6191                 goto QAllEAsRetry;
6192
6193         return (ssize_t)rc;
6194 }
6195
6196 int
6197 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6198              const char *fileName, const char *ea_name, const void *ea_value,
6199              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6200              int remap)
6201 {
6202         struct smb_com_transaction2_spi_req *pSMB = NULL;
6203         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6204         struct fealist *parm_data;
6205         int name_len;
6206         int rc = 0;
6207         int bytes_returned = 0;
6208         __u16 params, param_offset, byte_count, offset, count;
6209
6210         cifs_dbg(FYI, "In SetEA\n");
6211 SetEARetry:
6212         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6213                       (void **) &pSMBr);
6214         if (rc)
6215                 return rc;
6216
6217         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6218                 name_len =
6219                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6220                                        PATH_MAX, nls_codepage, remap);
6221                 name_len++;     /* trailing null */
6222                 name_len *= 2;
6223         } else {        /* BB improve the check for buffer overruns BB */
6224                 name_len = strnlen(fileName, PATH_MAX);
6225                 name_len++;     /* trailing null */
6226                 strncpy(pSMB->FileName, fileName, name_len);
6227         }
6228
6229         params = 6 + name_len;
6230
6231         /* done calculating parms using name_len of file name,
6232         now use name_len to calculate length of ea name
6233         we are going to create in the inode xattrs */
6234         if (ea_name == NULL)
6235                 name_len = 0;
6236         else
6237                 name_len = strnlen(ea_name, 255);
6238
6239         count = sizeof(*parm_data) + ea_value_len + name_len;
6240         pSMB->MaxParameterCount = cpu_to_le16(2);
6241         /* BB find max SMB PDU from sess */
6242         pSMB->MaxDataCount = cpu_to_le16(1000);
6243         pSMB->MaxSetupCount = 0;
6244         pSMB->Reserved = 0;
6245         pSMB->Flags = 0;
6246         pSMB->Timeout = 0;
6247         pSMB->Reserved2 = 0;
6248         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6249                                 InformationLevel) - 4;
6250         offset = param_offset + params;
6251         pSMB->InformationLevel =
6252                 cpu_to_le16(SMB_SET_FILE_EA);
6253
6254         parm_data =
6255                 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6256                                        offset);
6257         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6258         pSMB->DataOffset = cpu_to_le16(offset);
6259         pSMB->SetupCount = 1;
6260         pSMB->Reserved3 = 0;
6261         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6262         byte_count = 3 /* pad */  + params + count;
6263         pSMB->DataCount = cpu_to_le16(count);
6264         parm_data->list_len = cpu_to_le32(count);
6265         parm_data->list[0].EA_flags = 0;
6266         /* we checked above that name len is less than 255 */
6267         parm_data->list[0].name_len = (__u8)name_len;
6268         /* EA names are always ASCII */
6269         if (ea_name)
6270                 strncpy(parm_data->list[0].name, ea_name, name_len);
6271         parm_data->list[0].name[name_len] = 0;
6272         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6273         /* caller ensures that ea_value_len is less than 64K but
6274         we need to ensure that it fits within the smb */
6275
6276         /*BB add length check to see if it would fit in
6277              negotiated SMB buffer size BB */
6278         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6279         if (ea_value_len)
6280                 memcpy(parm_data->list[0].name+name_len+1,
6281                        ea_value, ea_value_len);
6282
6283         pSMB->TotalDataCount = pSMB->DataCount;
6284         pSMB->ParameterCount = cpu_to_le16(params);
6285         pSMB->TotalParameterCount = pSMB->ParameterCount;
6286         pSMB->Reserved4 = 0;
6287         inc_rfc1001_len(pSMB, byte_count);
6288         pSMB->ByteCount = cpu_to_le16(byte_count);
6289         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6290                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6291         if (rc)
6292                 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6293
6294         cifs_buf_release(pSMB);
6295
6296         if (rc == -EAGAIN)
6297                 goto SetEARetry;
6298
6299         return rc;
6300 }
6301 #endif
6302
6303 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6304 /*
6305  *      Years ago the kernel added a "dnotify" function for Samba server,
6306  *      to allow network clients (such as Windows) to display updated
6307  *      lists of files in directory listings automatically when
6308  *      files are added by one user when another user has the
6309  *      same directory open on their desktop.  The Linux cifs kernel
6310  *      client hooked into the kernel side of this interface for
6311  *      the same reason, but ironically when the VFS moved from
6312  *      "dnotify" to "inotify" it became harder to plug in Linux
6313  *      network file system clients (the most obvious use case
6314  *      for notify interfaces is when multiple users can update
6315  *      the contents of the same directory - exactly what network
6316  *      file systems can do) although the server (Samba) could
6317  *      still use it.  For the short term we leave the worker
6318  *      function ifdeffed out (below) until inotify is fixed
6319  *      in the VFS to make it easier to plug in network file
6320  *      system clients.  If inotify turns out to be permanently
6321  *      incompatible for network fs clients, we could instead simply
6322  *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
6323  */
6324 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6325                   const int notify_subdirs, const __u16 netfid,
6326                   __u32 filter, struct file *pfile, int multishot,
6327                   const struct nls_table *nls_codepage)
6328 {
6329         int rc = 0;
6330         struct smb_com_transaction_change_notify_req *pSMB = NULL;
6331         struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6332         struct dir_notify_req *dnotify_req;
6333         int bytes_returned;
6334
6335         cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6336         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6337                       (void **) &pSMBr);
6338         if (rc)
6339                 return rc;
6340
6341         pSMB->TotalParameterCount = 0 ;
6342         pSMB->TotalDataCount = 0;
6343         pSMB->MaxParameterCount = cpu_to_le32(2);
6344         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6345         pSMB->MaxSetupCount = 4;
6346         pSMB->Reserved = 0;
6347         pSMB->ParameterOffset = 0;
6348         pSMB->DataCount = 0;
6349         pSMB->DataOffset = 0;
6350         pSMB->SetupCount = 4; /* single byte does not need le conversion */
6351         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6352         pSMB->ParameterCount = pSMB->TotalParameterCount;
6353         if (notify_subdirs)
6354                 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6355         pSMB->Reserved2 = 0;
6356         pSMB->CompletionFilter = cpu_to_le32(filter);
6357         pSMB->Fid = netfid; /* file handle always le */
6358         pSMB->ByteCount = 0;
6359
6360         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6361                          (struct smb_hdr *)pSMBr, &bytes_returned,
6362                          CIFS_ASYNC_OP);
6363         if (rc) {
6364                 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6365         } else {
6366                 /* Add file to outstanding requests */
6367                 /* BB change to kmem cache alloc */
6368                 dnotify_req = kmalloc(
6369                                                 sizeof(struct dir_notify_req),
6370                                                  GFP_KERNEL);
6371                 if (dnotify_req) {
6372                         dnotify_req->Pid = pSMB->hdr.Pid;
6373                         dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6374                         dnotify_req->Mid = pSMB->hdr.Mid;
6375                         dnotify_req->Tid = pSMB->hdr.Tid;
6376                         dnotify_req->Uid = pSMB->hdr.Uid;
6377                         dnotify_req->netfid = netfid;
6378                         dnotify_req->pfile = pfile;
6379                         dnotify_req->filter = filter;
6380                         dnotify_req->multishot = multishot;
6381                         spin_lock(&GlobalMid_Lock);
6382                         list_add_tail(&dnotify_req->lhead,
6383                                         &GlobalDnotifyReqList);
6384                         spin_unlock(&GlobalMid_Lock);
6385                 } else
6386                         rc = -ENOMEM;
6387         }
6388         cifs_buf_release(pSMB);
6389         return rc;
6390 }
6391 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */