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