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