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