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