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