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