Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / fs / cifs / cifssmb.c
1 /*
2  *   fs/cifs/cifssmb.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2010
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   Contains the routines for constructing the SMB PDUs themselves
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23
24  /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c   */
25  /* These are mostly routines that operate on a pathname, or on a tree id     */
26  /* (mounted volume), but there are eight handle based routines which must be */
27  /* treated slightly differently for reconnection purposes since we never     */
28  /* want to reuse a stale file handle and only the caller knows the file info */
29
30 #include <linux/fs.h>
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <linux/slab.h>
34 #include <linux/posix_acl_xattr.h>
35 #include <linux/pagemap.h>
36 #include <linux/swap.h>
37 #include <linux/task_io_accounting_ops.h>
38 #include <asm/uaccess.h>
39 #include "cifspdu.h"
40 #include "cifsglob.h"
41 #include "cifsacl.h"
42 #include "cifsproto.h"
43 #include "cifs_unicode.h"
44 #include "cifs_debug.h"
45 #include "fscache.h"
46
47 #ifdef CONFIG_CIFS_POSIX
48 static struct {
49         int index;
50         char *name;
51 } protocols[] = {
52 #ifdef CONFIG_CIFS_WEAK_PW_HASH
53         {LANMAN_PROT, "\2LM1.2X002"},
54         {LANMAN2_PROT, "\2LANMAN2.1"},
55 #endif /* weak password hashing for legacy clients */
56         {CIFS_PROT, "\2NT LM 0.12"},
57         {POSIX_PROT, "\2POSIX 2"},
58         {BAD_PROT, "\2"}
59 };
60 #else
61 static struct {
62         int index;
63         char *name;
64 } protocols[] = {
65 #ifdef CONFIG_CIFS_WEAK_PW_HASH
66         {LANMAN_PROT, "\2LM1.2X002"},
67         {LANMAN2_PROT, "\2LANMAN2.1"},
68 #endif /* weak password hashing for legacy clients */
69         {CIFS_PROT, "\2NT LM 0.12"},
70         {BAD_PROT, "\2"}
71 };
72 #endif
73
74 /* define the number of elements in the cifs dialect array */
75 #ifdef CONFIG_CIFS_POSIX
76 #ifdef CONFIG_CIFS_WEAK_PW_HASH
77 #define CIFS_NUM_PROT 4
78 #else
79 #define CIFS_NUM_PROT 2
80 #endif /* CIFS_WEAK_PW_HASH */
81 #else /* not posix */
82 #ifdef CONFIG_CIFS_WEAK_PW_HASH
83 #define CIFS_NUM_PROT 3
84 #else
85 #define CIFS_NUM_PROT 1
86 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
87 #endif /* CIFS_POSIX */
88
89 /* Forward declarations */
90 static void cifs_readv_complete(struct work_struct *work);
91
92 #ifdef CONFIG_HIGHMEM
93 /*
94  * On arches that have high memory, kmap address space is limited. By
95  * serializing the kmap operations on those arches, we ensure that we don't
96  * end up with a bunch of threads in writeback with partially mapped page
97  * arrays, stuck waiting for kmap to come back. That situation prevents
98  * progress and can deadlock.
99  */
100 static DEFINE_MUTEX(cifs_kmap_mutex);
101
102 static inline void
103 cifs_kmap_lock(void)
104 {
105         mutex_lock(&cifs_kmap_mutex);
106 }
107
108 static inline void
109 cifs_kmap_unlock(void)
110 {
111         mutex_unlock(&cifs_kmap_mutex);
112 }
113 #else /* !CONFIG_HIGHMEM */
114 #define cifs_kmap_lock() do { ; } while(0)
115 #define cifs_kmap_unlock() do { ; } while(0)
116 #endif /* CONFIG_HIGHMEM */
117
118 /* Mark as invalid, all open files on tree connections since they
119    were closed when session to server was lost */
120 static void mark_open_files_invalid(struct cifs_tcon *pTcon)
121 {
122         struct cifsFileInfo *open_file = NULL;
123         struct list_head *tmp;
124         struct list_head *tmp1;
125
126 /* list all files open on tree connection and mark them invalid */
127         spin_lock(&cifs_file_list_lock);
128         list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
129                 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
130                 open_file->invalidHandle = true;
131                 open_file->oplock_break_cancelled = true;
132         }
133         spin_unlock(&cifs_file_list_lock);
134         /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
135            to this tcon */
136 }
137
138 /* reconnect the socket, tcon, and smb session if needed */
139 static int
140 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
141 {
142         int rc;
143         struct cifs_ses *ses;
144         struct TCP_Server_Info *server;
145         struct nls_table *nls_codepage;
146
147         /*
148          * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
149          * tcp and smb session status done differently for those three - in the
150          * calling routine
151          */
152         if (!tcon)
153                 return 0;
154
155         ses = tcon->ses;
156         server = ses->server;
157
158         /*
159          * only tree disconnect, open, and write, (and ulogoff which does not
160          * have tcon) are allowed as we start force umount
161          */
162         if (tcon->tidStatus == CifsExiting) {
163                 if (smb_command != SMB_COM_WRITE_ANDX &&
164                     smb_command != SMB_COM_OPEN_ANDX &&
165                     smb_command != SMB_COM_TREE_DISCONNECT) {
166                         cFYI(1, "can not send cmd %d while umounting",
167                                 smb_command);
168                         return -ENODEV;
169                 }
170         }
171
172         /*
173          * Give demultiplex thread up to 10 seconds to reconnect, should be
174          * greater than cifs socket timeout which is 7 seconds
175          */
176         while (server->tcpStatus == CifsNeedReconnect) {
177                 wait_event_interruptible_timeout(server->response_q,
178                         (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
179
180                 /* are we still trying to reconnect? */
181                 if (server->tcpStatus != CifsNeedReconnect)
182                         break;
183
184                 /*
185                  * on "soft" mounts we wait once. Hard mounts keep
186                  * retrying until process is killed or server comes
187                  * back on-line
188                  */
189                 if (!tcon->retry) {
190                         cFYI(1, "gave up waiting on reconnect in smb_init");
191                         return -EHOSTDOWN;
192                 }
193         }
194
195         if (!ses->need_reconnect && !tcon->need_reconnect)
196                 return 0;
197
198         nls_codepage = load_nls_default();
199
200         /*
201          * need to prevent multiple threads trying to simultaneously
202          * reconnect the same SMB session
203          */
204         mutex_lock(&ses->session_mutex);
205         rc = cifs_negotiate_protocol(0, ses);
206         if (rc == 0 && ses->need_reconnect)
207                 rc = cifs_setup_session(0, ses, nls_codepage);
208
209         /* do we need to reconnect tcon? */
210         if (rc || !tcon->need_reconnect) {
211                 mutex_unlock(&ses->session_mutex);
212                 goto out;
213         }
214
215         mark_open_files_invalid(tcon);
216         rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
217         mutex_unlock(&ses->session_mutex);
218         cFYI(1, "reconnect tcon rc = %d", rc);
219
220         if (rc)
221                 goto out;
222
223         /*
224          * FIXME: check if wsize needs updated due to negotiated smb buffer
225          *        size shrinking
226          */
227         atomic_inc(&tconInfoReconnectCount);
228
229         /* tell server Unix caps we support */
230         if (ses->capabilities & CAP_UNIX)
231                 reset_cifs_unix_caps(0, tcon, NULL, NULL);
232
233         /*
234          * Removed call to reopen open files here. It is safer (and faster) to
235          * reopen files one at a time as needed in read and write.
236          *
237          * FIXME: what about file locks? don't we need to reclaim them ASAP?
238          */
239
240 out:
241         /*
242          * Check if handle based operation so we know whether we can continue
243          * or not without returning to caller to reset file handle
244          */
245         switch (smb_command) {
246         case SMB_COM_READ_ANDX:
247         case SMB_COM_WRITE_ANDX:
248         case SMB_COM_CLOSE:
249         case SMB_COM_FIND_CLOSE2:
250         case SMB_COM_LOCKING_ANDX:
251                 rc = -EAGAIN;
252         }
253
254         unload_nls(nls_codepage);
255         return rc;
256 }
257
258 /* Allocate and return pointer to an SMB request buffer, and set basic
259    SMB information in the SMB header.  If the return code is zero, this
260    function must have filled in request_buf pointer */
261 static int
262 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
263                 void **request_buf)
264 {
265         int rc;
266
267         rc = cifs_reconnect_tcon(tcon, smb_command);
268         if (rc)
269                 return rc;
270
271         *request_buf = cifs_small_buf_get();
272         if (*request_buf == NULL) {
273                 /* BB should we add a retry in here if not a writepage? */
274                 return -ENOMEM;
275         }
276
277         header_assemble((struct smb_hdr *) *request_buf, smb_command,
278                         tcon, wct);
279
280         if (tcon != NULL)
281                 cifs_stats_inc(&tcon->num_smbs_sent);
282
283         return 0;
284 }
285
286 int
287 small_smb_init_no_tc(const int smb_command, const int wct,
288                      struct cifs_ses *ses, void **request_buf)
289 {
290         int rc;
291         struct smb_hdr *buffer;
292
293         rc = small_smb_init(smb_command, wct, NULL, request_buf);
294         if (rc)
295                 return rc;
296
297         buffer = (struct smb_hdr *)*request_buf;
298         buffer->Mid = GetNextMid(ses->server);
299         if (ses->capabilities & CAP_UNICODE)
300                 buffer->Flags2 |= SMBFLG2_UNICODE;
301         if (ses->capabilities & CAP_STATUS32)
302                 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
303
304         /* uid, tid can stay at zero as set in header assemble */
305
306         /* BB add support for turning on the signing when
307         this function is used after 1st of session setup requests */
308
309         return rc;
310 }
311
312 /* If the return code is zero, this function must fill in request_buf pointer */
313 static int
314 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
315                         void **request_buf, void **response_buf)
316 {
317         *request_buf = cifs_buf_get();
318         if (*request_buf == NULL) {
319                 /* BB should we add a retry in here if not a writepage? */
320                 return -ENOMEM;
321         }
322     /* Although the original thought was we needed the response buf for  */
323     /* potential retries of smb operations it turns out we can determine */
324     /* from the mid flags when the request buffer can be resent without  */
325     /* having to use a second distinct buffer for the response */
326         if (response_buf)
327                 *response_buf = *request_buf;
328
329         header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
330                         wct);
331
332         if (tcon != NULL)
333                 cifs_stats_inc(&tcon->num_smbs_sent);
334
335         return 0;
336 }
337
338 /* If the return code is zero, this function must fill in request_buf pointer */
339 static int
340 smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
341          void **request_buf, void **response_buf)
342 {
343         int rc;
344
345         rc = cifs_reconnect_tcon(tcon, smb_command);
346         if (rc)
347                 return rc;
348
349         return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
350 }
351
352 static int
353 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
354                         void **request_buf, void **response_buf)
355 {
356         if (tcon->ses->need_reconnect || tcon->need_reconnect)
357                 return -EHOSTDOWN;
358
359         return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
360 }
361
362 static int validate_t2(struct smb_t2_rsp *pSMB)
363 {
364         unsigned int total_size;
365
366         /* check for plausible wct */
367         if (pSMB->hdr.WordCount < 10)
368                 goto vt2_err;
369
370         /* check for parm and data offset going beyond end of smb */
371         if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
372             get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
373                 goto vt2_err;
374
375         total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
376         if (total_size >= 512)
377                 goto vt2_err;
378
379         /* check that bcc is at least as big as parms + data, and that it is
380          * less than negotiated smb buffer
381          */
382         total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
383         if (total_size > get_bcc(&pSMB->hdr) ||
384             total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
385                 goto vt2_err;
386
387         return 0;
388 vt2_err:
389         cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
390                 sizeof(struct smb_t2_rsp) + 16);
391         return -EINVAL;
392 }
393
394 static inline void inc_rfc1001_len(void *pSMB, int count)
395 {
396         struct smb_hdr *hdr = (struct smb_hdr *)pSMB;
397
398         be32_add_cpu(&hdr->smb_buf_length, count);
399 }
400
401 int
402 CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
403 {
404         NEGOTIATE_REQ *pSMB;
405         NEGOTIATE_RSP *pSMBr;
406         int rc = 0;
407         int bytes_returned;
408         int i;
409         struct TCP_Server_Info *server;
410         u16 count;
411         unsigned int secFlags;
412
413         if (ses->server)
414                 server = ses->server;
415         else {
416                 rc = -EIO;
417                 return rc;
418         }
419         rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
420                       (void **) &pSMB, (void **) &pSMBr);
421         if (rc)
422                 return rc;
423
424         /* if any of auth flags (ie not sign or seal) are overriden use them */
425         if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
426                 secFlags = ses->overrideSecFlg;  /* BB FIXME fix sign flags? */
427         else /* if override flags set only sign/seal OR them with global auth */
428                 secFlags = global_secflags | ses->overrideSecFlg;
429
430         cFYI(1, "secFlags 0x%x", secFlags);
431
432         pSMB->hdr.Mid = GetNextMid(server);
433         pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
434
435         if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
436                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
437         else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
438                 cFYI(1, "Kerberos only mechanism, enable extended security");
439                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
440         } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
441                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
442         else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
443                 cFYI(1, "NTLMSSP only mechanism, enable extended security");
444                 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
445         }
446
447         count = 0;
448         for (i = 0; i < CIFS_NUM_PROT; i++) {
449                 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
450                 count += strlen(protocols[i].name) + 1;
451                 /* null at end of source and target buffers anyway */
452         }
453         inc_rfc1001_len(pSMB, count);
454         pSMB->ByteCount = cpu_to_le16(count);
455
456         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
457                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
458         if (rc != 0)
459                 goto neg_err_exit;
460
461         server->dialect = le16_to_cpu(pSMBr->DialectIndex);
462         cFYI(1, "Dialect: %d", server->dialect);
463         /* Check wct = 1 error case */
464         if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
465                 /* core returns wct = 1, but we do not ask for core - otherwise
466                 small wct just comes when dialect index is -1 indicating we
467                 could not negotiate a common dialect */
468                 rc = -EOPNOTSUPP;
469                 goto neg_err_exit;
470 #ifdef CONFIG_CIFS_WEAK_PW_HASH
471         } else if ((pSMBr->hdr.WordCount == 13)
472                         && ((server->dialect == LANMAN_PROT)
473                                 || (server->dialect == LANMAN2_PROT))) {
474                 __s16 tmp;
475                 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
476
477                 if ((secFlags & CIFSSEC_MAY_LANMAN) ||
478                         (secFlags & CIFSSEC_MAY_PLNTXT))
479                         server->secType = LANMAN;
480                 else {
481                         cERROR(1, "mount failed weak security disabled"
482                                    " in /proc/fs/cifs/SecurityFlags");
483                         rc = -EOPNOTSUPP;
484                         goto neg_err_exit;
485                 }
486                 server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
487                 server->maxReq = min_t(unsigned int,
488                                        le16_to_cpu(rsp->MaxMpxCount),
489                                        cifs_max_pending);
490                 server->oplocks = server->maxReq > 1 ? enable_oplocks : false;
491                 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
492                 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
493                 /* even though we do not use raw we might as well set this
494                 accurately, in case we ever find a need for it */
495                 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
496                         server->max_rw = 0xFF00;
497                         server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
498                 } else {
499                         server->max_rw = 0;/* do not need to use raw anyway */
500                         server->capabilities = CAP_MPX_MODE;
501                 }
502                 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
503                 if (tmp == -1) {
504                         /* OS/2 often does not set timezone therefore
505                          * we must use server time to calc time zone.
506                          * Could deviate slightly from the right zone.
507                          * Smallest defined timezone difference is 15 minutes
508                          * (i.e. Nepal).  Rounding up/down is done to match
509                          * this requirement.
510                          */
511                         int val, seconds, remain, result;
512                         struct timespec ts, utc;
513                         utc = CURRENT_TIME;
514                         ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
515                                             rsp->SrvTime.Time, 0);
516                         cFYI(1, "SrvTime %d sec since 1970 (utc: %d) diff: %d",
517                                 (int)ts.tv_sec, (int)utc.tv_sec,
518                                 (int)(utc.tv_sec - ts.tv_sec));
519                         val = (int)(utc.tv_sec - ts.tv_sec);
520                         seconds = abs(val);
521                         result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
522                         remain = seconds % MIN_TZ_ADJ;
523                         if (remain >= (MIN_TZ_ADJ / 2))
524                                 result += MIN_TZ_ADJ;
525                         if (val < 0)
526                                 result = -result;
527                         server->timeAdj = result;
528                 } else {
529                         server->timeAdj = (int)tmp;
530                         server->timeAdj *= 60; /* also in seconds */
531                 }
532                 cFYI(1, "server->timeAdj: %d seconds", server->timeAdj);
533
534
535                 /* BB get server time for time conversions and add
536                 code to use it and timezone since this is not UTC */
537
538                 if (rsp->EncryptionKeyLength ==
539                                 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
540                         memcpy(ses->server->cryptkey, rsp->EncryptionKey,
541                                 CIFS_CRYPTO_KEY_SIZE);
542                 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
543                         rc = -EIO; /* need cryptkey unless plain text */
544                         goto neg_err_exit;
545                 }
546
547                 cFYI(1, "LANMAN negotiated");
548                 /* we will not end up setting signing flags - as no signing
549                 was in LANMAN and server did not return the flags on */
550                 goto signing_check;
551 #else /* weak security disabled */
552         } else if (pSMBr->hdr.WordCount == 13) {
553                 cERROR(1, "mount failed, cifs module not built "
554                           "with CIFS_WEAK_PW_HASH support");
555                 rc = -EOPNOTSUPP;
556 #endif /* WEAK_PW_HASH */
557                 goto neg_err_exit;
558         } else if (pSMBr->hdr.WordCount != 17) {
559                 /* unknown wct */
560                 rc = -EOPNOTSUPP;
561                 goto neg_err_exit;
562         }
563         /* else wct == 17 NTLM */
564         server->sec_mode = pSMBr->SecurityMode;
565         if ((server->sec_mode & SECMODE_USER) == 0)
566                 cFYI(1, "share mode security");
567
568         if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
569 #ifdef CONFIG_CIFS_WEAK_PW_HASH
570                 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
571 #endif /* CIFS_WEAK_PW_HASH */
572                         cERROR(1, "Server requests plain text password"
573                                   " but client support disabled");
574
575         if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
576                 server->secType = NTLMv2;
577         else if (secFlags & CIFSSEC_MAY_NTLM)
578                 server->secType = NTLM;
579         else if (secFlags & CIFSSEC_MAY_NTLMV2)
580                 server->secType = NTLMv2;
581         else if (secFlags & CIFSSEC_MAY_KRB5)
582                 server->secType = Kerberos;
583         else if (secFlags & CIFSSEC_MAY_NTLMSSP)
584                 server->secType = RawNTLMSSP;
585         else if (secFlags & CIFSSEC_MAY_LANMAN)
586                 server->secType = LANMAN;
587         else {
588                 rc = -EOPNOTSUPP;
589                 cERROR(1, "Invalid security type");
590                 goto neg_err_exit;
591         }
592         /* else ... any others ...? */
593
594         /* one byte, so no need to convert this or EncryptionKeyLen from
595            little endian */
596         server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
597                                cifs_max_pending);
598         server->oplocks = server->maxReq > 1 ? enable_oplocks : false;
599         /* probably no need to store and check maxvcs */
600         server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
601         server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
602         cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);
603         server->capabilities = le32_to_cpu(pSMBr->Capabilities);
604         server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
605         server->timeAdj *= 60;
606         if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
607                 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
608                        CIFS_CRYPTO_KEY_SIZE);
609         } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
610                         server->capabilities & CAP_EXTENDED_SECURITY) &&
611                                 (pSMBr->EncryptionKeyLength == 0)) {
612                 /* decode security blob */
613                 count = get_bcc(&pSMBr->hdr);
614                 if (count < 16) {
615                         rc = -EIO;
616                         goto neg_err_exit;
617                 }
618                 spin_lock(&cifs_tcp_ses_lock);
619                 if (server->srv_count > 1) {
620                         spin_unlock(&cifs_tcp_ses_lock);
621                         if (memcmp(server->server_GUID,
622                                    pSMBr->u.extended_response.
623                                    GUID, 16) != 0) {
624                                 cFYI(1, "server UID changed");
625                                 memcpy(server->server_GUID,
626                                         pSMBr->u.extended_response.GUID,
627                                         16);
628                         }
629                 } else {
630                         spin_unlock(&cifs_tcp_ses_lock);
631                         memcpy(server->server_GUID,
632                                pSMBr->u.extended_response.GUID, 16);
633                 }
634
635                 if (count == 16) {
636                         server->secType = RawNTLMSSP;
637                 } else {
638                         rc = decode_negTokenInit(pSMBr->u.extended_response.
639                                                  SecurityBlob, count - 16,
640                                                  server);
641                         if (rc == 1)
642                                 rc = 0;
643                         else
644                                 rc = -EINVAL;
645                         if (server->secType == Kerberos) {
646                                 if (!server->sec_kerberos &&
647                                                 !server->sec_mskerberos)
648                                         rc = -EOPNOTSUPP;
649                         } else if (server->secType == RawNTLMSSP) {
650                                 if (!server->sec_ntlmssp)
651                                         rc = -EOPNOTSUPP;
652                         } else
653                                         rc = -EOPNOTSUPP;
654                 }
655         } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
656                 rc = -EIO; /* no crypt key only if plain text pwd */
657                 goto neg_err_exit;
658         } else
659                 server->capabilities &= ~CAP_EXTENDED_SECURITY;
660
661 #ifdef CONFIG_CIFS_WEAK_PW_HASH
662 signing_check:
663 #endif
664         if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
665                 /* MUST_SIGN already includes the MAY_SIGN FLAG
666                    so if this is zero it means that signing is disabled */
667                 cFYI(1, "Signing disabled");
668                 if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
669                         cERROR(1, "Server requires "
670                                    "packet signing to be enabled in "
671                                    "/proc/fs/cifs/SecurityFlags.");
672                         rc = -EOPNOTSUPP;
673                 }
674                 server->sec_mode &=
675                         ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
676         } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
677                 /* signing required */
678                 cFYI(1, "Must sign - secFlags 0x%x", secFlags);
679                 if ((server->sec_mode &
680                         (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
681                         cERROR(1, "signing required but server lacks support");
682                         rc = -EOPNOTSUPP;
683                 } else
684                         server->sec_mode |= SECMODE_SIGN_REQUIRED;
685         } else {
686                 /* signing optional ie CIFSSEC_MAY_SIGN */
687                 if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
688                         server->sec_mode &=
689                                 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
690         }
691
692 neg_err_exit:
693         cifs_buf_release(pSMB);
694
695         cFYI(1, "negprot rc %d", rc);
696         return rc;
697 }
698
699 int
700 CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
701 {
702         struct smb_hdr *smb_buffer;
703         int rc = 0;
704
705         cFYI(1, "In tree disconnect");
706
707         /* BB: do we need to check this? These should never be NULL. */
708         if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
709                 return -EIO;
710
711         /*
712          * No need to return error on this operation if tid invalidated and
713          * closed on server already e.g. due to tcp session crashing. Also,
714          * the tcon is no longer on the list, so no need to take lock before
715          * checking this.
716          */
717         if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
718                 return 0;
719
720         rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
721                             (void **)&smb_buffer);
722         if (rc)
723                 return rc;
724
725         rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
726         if (rc)
727                 cFYI(1, "Tree disconnect failed %d", rc);
728
729         /* No need to return error on this operation if tid invalidated and
730            closed on server already e.g. due to tcp session crashing */
731         if (rc == -EAGAIN)
732                 rc = 0;
733
734         return rc;
735 }
736
737 /*
738  * This is a no-op for now. We're not really interested in the reply, but
739  * rather in the fact that the server sent one and that server->lstrp
740  * gets updated.
741  *
742  * FIXME: maybe we should consider checking that the reply matches request?
743  */
744 static void
745 cifs_echo_callback(struct mid_q_entry *mid)
746 {
747         struct TCP_Server_Info *server = mid->callback_data;
748
749         DeleteMidQEntry(mid);
750         atomic_dec(&server->inFlight);
751         wake_up(&server->request_q);
752 }
753
754 int
755 CIFSSMBEcho(struct TCP_Server_Info *server)
756 {
757         ECHO_REQ *smb;
758         int rc = 0;
759         struct kvec iov;
760
761         cFYI(1, "In echo request");
762
763         rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
764         if (rc)
765                 return rc;
766
767         /* 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         void *pSMBr;
3910
3911 setCifsAclRetry:
3912         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3913         if (rc)
3914                 return rc;
3915
3916         pSMB->MaxSetupCount = 0;
3917         pSMB->Reserved = 0;
3918
3919         param_count = 8;
3920         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3921         data_count = acllen;
3922         data_offset = param_offset + param_count;
3923         byte_count = 3 /* pad */  + param_count;
3924
3925         pSMB->DataCount = cpu_to_le32(data_count);
3926         pSMB->TotalDataCount = pSMB->DataCount;
3927         pSMB->MaxParameterCount = cpu_to_le32(4);
3928         pSMB->MaxDataCount = cpu_to_le32(16384);
3929         pSMB->ParameterCount = cpu_to_le32(param_count);
3930         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3931         pSMB->TotalParameterCount = pSMB->ParameterCount;
3932         pSMB->DataOffset = cpu_to_le32(data_offset);
3933         pSMB->SetupCount = 0;
3934         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3935         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3936
3937         pSMB->Fid = fid; /* file handle always le */
3938         pSMB->Reserved2 = 0;
3939         pSMB->AclFlags = cpu_to_le32(aclflag);
3940
3941         if (pntsd && acllen) {
3942                 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3943                                 data_offset, pntsd, acllen);
3944                 inc_rfc1001_len(pSMB, byte_count + data_count);
3945         } else
3946                 inc_rfc1001_len(pSMB, byte_count);
3947
3948         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3949                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3950
3951         cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
3952         if (rc)
3953                 cFYI(1, "Set CIFS ACL returned %d", rc);
3954         cifs_buf_release(pSMB);
3955
3956         if (rc == -EAGAIN)
3957                 goto setCifsAclRetry;
3958
3959         return (rc);
3960 }
3961
3962 #endif /* CONFIG_CIFS_ACL */
3963
3964 /* Legacy Query Path Information call for lookup to old servers such
3965    as Win9x/WinME */
3966 int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3967                         const unsigned char *searchName,
3968                         FILE_ALL_INFO *pFinfo,
3969                         const struct nls_table *nls_codepage, int remap)
3970 {
3971         QUERY_INFORMATION_REQ *pSMB;
3972         QUERY_INFORMATION_RSP *pSMBr;
3973         int rc = 0;
3974         int bytes_returned;
3975         int name_len;
3976
3977         cFYI(1, "In SMBQPath path %s", searchName);
3978 QInfRetry:
3979         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3980                       (void **) &pSMBr);
3981         if (rc)
3982                 return rc;
3983
3984         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3985                 name_len =
3986                         cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3987                                         PATH_MAX, nls_codepage, remap);
3988                 name_len++;     /* trailing null */
3989                 name_len *= 2;
3990         } else {
3991                 name_len = strnlen(searchName, PATH_MAX);
3992                 name_len++;     /* trailing null */
3993                 strncpy(pSMB->FileName, searchName, name_len);
3994         }
3995         pSMB->BufferFormat = 0x04;
3996         name_len++; /* account for buffer type byte */
3997         inc_rfc1001_len(pSMB, (__u16)name_len);
3998         pSMB->ByteCount = cpu_to_le16(name_len);
3999
4000         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4001                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4002         if (rc) {
4003                 cFYI(1, "Send error in QueryInfo = %d", rc);
4004         } else if (pFinfo) {
4005                 struct timespec ts;
4006                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
4007
4008                 /* decode response */
4009                 /* BB FIXME - add time zone adjustment BB */
4010                 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
4011                 ts.tv_nsec = 0;
4012                 ts.tv_sec = time;
4013                 /* decode time fields */
4014                 pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4015                 pFinfo->LastWriteTime = pFinfo->ChangeTime;
4016                 pFinfo->LastAccessTime = 0;
4017                 pFinfo->AllocationSize =
4018                         cpu_to_le64(le32_to_cpu(pSMBr->size));
4019                 pFinfo->EndOfFile = pFinfo->AllocationSize;
4020                 pFinfo->Attributes =
4021                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
4022         } else
4023                 rc = -EIO; /* bad buffer passed in */
4024
4025         cifs_buf_release(pSMB);
4026
4027         if (rc == -EAGAIN)
4028                 goto QInfRetry;
4029
4030         return rc;
4031 }
4032
4033 int
4034 CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
4035                  u16 netfid, FILE_ALL_INFO *pFindData)
4036 {
4037         struct smb_t2_qfi_req *pSMB = NULL;
4038         struct smb_t2_qfi_rsp *pSMBr = NULL;
4039         int rc = 0;
4040         int bytes_returned;
4041         __u16 params, byte_count;
4042
4043 QFileInfoRetry:
4044         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4045                       (void **) &pSMBr);
4046         if (rc)
4047                 return rc;
4048
4049         params = 2 /* level */ + 2 /* fid */;
4050         pSMB->t2.TotalDataCount = 0;
4051         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4052         /* BB find exact max data count below from sess structure BB */
4053         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4054         pSMB->t2.MaxSetupCount = 0;
4055         pSMB->t2.Reserved = 0;
4056         pSMB->t2.Flags = 0;
4057         pSMB->t2.Timeout = 0;
4058         pSMB->t2.Reserved2 = 0;
4059         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4060                                                Fid) - 4);
4061         pSMB->t2.DataCount = 0;
4062         pSMB->t2.DataOffset = 0;
4063         pSMB->t2.SetupCount = 1;
4064         pSMB->t2.Reserved3 = 0;
4065         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4066         byte_count = params + 1 /* pad */ ;
4067         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4068         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4069         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4070         pSMB->Pad = 0;
4071         pSMB->Fid = netfid;
4072         inc_rfc1001_len(pSMB, byte_count);
4073
4074         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4075                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4076         if (rc) {
4077                 cFYI(1, "Send error in QPathInfo = %d", rc);
4078         } else {                /* decode response */
4079                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4080
4081                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4082                         rc = -EIO;
4083                 else if (get_bcc(&pSMBr->hdr) < 40)
4084                         rc = -EIO;      /* bad smb */
4085                 else if (pFindData) {
4086                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4087                         memcpy((char *) pFindData,
4088                                (char *) &pSMBr->hdr.Protocol +
4089                                data_offset, sizeof(FILE_ALL_INFO));
4090                 } else
4091                     rc = -ENOMEM;
4092         }
4093         cifs_buf_release(pSMB);
4094         if (rc == -EAGAIN)
4095                 goto QFileInfoRetry;
4096
4097         return rc;
4098 }
4099
4100 int
4101 CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
4102                  const unsigned char *searchName,
4103                  FILE_ALL_INFO *pFindData,
4104                  int legacy /* old style infolevel */,
4105                  const struct nls_table *nls_codepage, int remap)
4106 {
4107 /* level 263 SMB_QUERY_FILE_ALL_INFO */
4108         TRANSACTION2_QPI_REQ *pSMB = NULL;
4109         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4110         int rc = 0;
4111         int bytes_returned;
4112         int name_len;
4113         __u16 params, byte_count;
4114
4115 /* cFYI(1, "In QPathInfo path %s", searchName); */
4116 QPathInfoRetry:
4117         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4118                       (void **) &pSMBr);
4119         if (rc)
4120                 return rc;
4121
4122         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4123                 name_len =
4124                     cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4125                                      PATH_MAX, nls_codepage, remap);
4126                 name_len++;     /* trailing null */
4127                 name_len *= 2;
4128         } else {        /* BB improve the check for buffer overruns BB */
4129                 name_len = strnlen(searchName, PATH_MAX);
4130                 name_len++;     /* trailing null */
4131                 strncpy(pSMB->FileName, searchName, name_len);
4132         }
4133
4134         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4135         pSMB->TotalDataCount = 0;
4136         pSMB->MaxParameterCount = cpu_to_le16(2);
4137         /* BB find exact max SMB PDU from sess structure BB */
4138         pSMB->MaxDataCount = cpu_to_le16(4000);
4139         pSMB->MaxSetupCount = 0;
4140         pSMB->Reserved = 0;
4141         pSMB->Flags = 0;
4142         pSMB->Timeout = 0;
4143         pSMB->Reserved2 = 0;
4144         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4145         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4146         pSMB->DataCount = 0;
4147         pSMB->DataOffset = 0;
4148         pSMB->SetupCount = 1;
4149         pSMB->Reserved3 = 0;
4150         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4151         byte_count = params + 1 /* pad */ ;
4152         pSMB->TotalParameterCount = cpu_to_le16(params);
4153         pSMB->ParameterCount = pSMB->TotalParameterCount;
4154         if (legacy)
4155                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4156         else
4157                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4158         pSMB->Reserved4 = 0;
4159         inc_rfc1001_len(pSMB, byte_count);
4160         pSMB->ByteCount = cpu_to_le16(byte_count);
4161
4162         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4163                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4164         if (rc) {
4165                 cFYI(1, "Send error in QPathInfo = %d", rc);
4166         } else {                /* decode response */
4167                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4168
4169                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4170                         rc = -EIO;
4171                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4172                         rc = -EIO;      /* bad smb */
4173                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4174                         rc = -EIO;  /* 24 or 26 expected but we do not read
4175                                         last field */
4176                 else if (pFindData) {
4177                         int size;
4178                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4179
4180                         /* On legacy responses we do not read the last field,
4181                         EAsize, fortunately since it varies by subdialect and
4182                         also note it differs on Set vs. Get, ie two bytes or 4
4183                         bytes depending but we don't care here */
4184                         if (legacy)
4185                                 size = sizeof(FILE_INFO_STANDARD);
4186                         else
4187                                 size = sizeof(FILE_ALL_INFO);
4188                         memcpy((char *) pFindData,
4189                                (char *) &pSMBr->hdr.Protocol +
4190                                data_offset, size);
4191                 } else
4192                     rc = -ENOMEM;
4193         }
4194         cifs_buf_release(pSMB);
4195         if (rc == -EAGAIN)
4196                 goto QPathInfoRetry;
4197
4198         return rc;
4199 }
4200
4201 int
4202 CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
4203                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4204 {
4205         struct smb_t2_qfi_req *pSMB = NULL;
4206         struct smb_t2_qfi_rsp *pSMBr = NULL;
4207         int rc = 0;
4208         int bytes_returned;
4209         __u16 params, byte_count;
4210
4211 UnixQFileInfoRetry:
4212         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4213                       (void **) &pSMBr);
4214         if (rc)
4215                 return rc;
4216
4217         params = 2 /* level */ + 2 /* fid */;
4218         pSMB->t2.TotalDataCount = 0;
4219         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4220         /* BB find exact max data count below from sess structure BB */
4221         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4222         pSMB->t2.MaxSetupCount = 0;
4223         pSMB->t2.Reserved = 0;
4224         pSMB->t2.Flags = 0;
4225         pSMB->t2.Timeout = 0;
4226         pSMB->t2.Reserved2 = 0;
4227         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4228                                                Fid) - 4);
4229         pSMB->t2.DataCount = 0;
4230         pSMB->t2.DataOffset = 0;
4231         pSMB->t2.SetupCount = 1;
4232         pSMB->t2.Reserved3 = 0;
4233         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4234         byte_count = params + 1 /* pad */ ;
4235         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4236         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4237         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4238         pSMB->Pad = 0;
4239         pSMB->Fid = netfid;
4240         inc_rfc1001_len(pSMB, byte_count);
4241
4242         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4243                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4244         if (rc) {
4245                 cFYI(1, "Send error in QPathInfo = %d", rc);
4246         } else {                /* decode response */
4247                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4248
4249                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4250                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4251                                    "Unix Extensions can be disabled on mount "
4252                                    "by specifying the nosfu mount option.");
4253                         rc = -EIO;      /* bad smb */
4254                 } else {
4255                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4256                         memcpy((char *) pFindData,
4257                                (char *) &pSMBr->hdr.Protocol +
4258                                data_offset,
4259                                sizeof(FILE_UNIX_BASIC_INFO));
4260                 }
4261         }
4262
4263         cifs_buf_release(pSMB);
4264         if (rc == -EAGAIN)
4265                 goto UnixQFileInfoRetry;
4266
4267         return rc;
4268 }
4269
4270 int
4271 CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
4272                      const unsigned char *searchName,
4273                      FILE_UNIX_BASIC_INFO *pFindData,
4274                      const struct nls_table *nls_codepage, int remap)
4275 {
4276 /* SMB_QUERY_FILE_UNIX_BASIC */
4277         TRANSACTION2_QPI_REQ *pSMB = NULL;
4278         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4279         int rc = 0;
4280         int bytes_returned = 0;
4281         int name_len;
4282         __u16 params, byte_count;
4283
4284         cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
4285 UnixQPathInfoRetry:
4286         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4287                       (void **) &pSMBr);
4288         if (rc)
4289                 return rc;
4290
4291         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4292                 name_len =
4293                     cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4294                                   PATH_MAX, nls_codepage, remap);
4295                 name_len++;     /* trailing null */
4296                 name_len *= 2;
4297         } else {        /* BB improve the check for buffer overruns BB */
4298                 name_len = strnlen(searchName, PATH_MAX);
4299                 name_len++;     /* trailing null */
4300                 strncpy(pSMB->FileName, searchName, name_len);
4301         }
4302
4303         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4304         pSMB->TotalDataCount = 0;
4305         pSMB->MaxParameterCount = cpu_to_le16(2);
4306         /* BB find exact max SMB PDU from sess structure BB */
4307         pSMB->MaxDataCount = cpu_to_le16(4000);
4308         pSMB->MaxSetupCount = 0;
4309         pSMB->Reserved = 0;
4310         pSMB->Flags = 0;
4311         pSMB->Timeout = 0;
4312         pSMB->Reserved2 = 0;
4313         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4314         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4315         pSMB->DataCount = 0;
4316         pSMB->DataOffset = 0;
4317         pSMB->SetupCount = 1;
4318         pSMB->Reserved3 = 0;
4319         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4320         byte_count = params + 1 /* pad */ ;
4321         pSMB->TotalParameterCount = cpu_to_le16(params);
4322         pSMB->ParameterCount = pSMB->TotalParameterCount;
4323         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4324         pSMB->Reserved4 = 0;
4325         inc_rfc1001_len(pSMB, byte_count);
4326         pSMB->ByteCount = cpu_to_le16(byte_count);
4327
4328         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4329                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4330         if (rc) {
4331                 cFYI(1, "Send error in QPathInfo = %d", rc);
4332         } else {                /* decode response */
4333                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4334
4335                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4336                         cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
4337                                    "Unix Extensions can be disabled on mount "
4338                                    "by specifying the nosfu mount option.");
4339                         rc = -EIO;      /* bad smb */
4340                 } else {
4341                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4342                         memcpy((char *) pFindData,
4343                                (char *) &pSMBr->hdr.Protocol +
4344                                data_offset,
4345                                sizeof(FILE_UNIX_BASIC_INFO));
4346                 }
4347         }
4348         cifs_buf_release(pSMB);
4349         if (rc == -EAGAIN)
4350                 goto UnixQPathInfoRetry;
4351
4352         return rc;
4353 }
4354
4355 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4356 int
4357 CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
4358               const char *searchName,
4359               const struct nls_table *nls_codepage,
4360               __u16 *pnetfid, __u16 search_flags,
4361               struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4362 {
4363 /* level 257 SMB_ */
4364         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4365         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4366         T2_FFIRST_RSP_PARMS *parms;
4367         int rc = 0;
4368         int bytes_returned = 0;
4369         int name_len;
4370         __u16 params, byte_count;
4371
4372         cFYI(1, "In FindFirst for %s", searchName);
4373
4374 findFirstRetry:
4375         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4376                       (void **) &pSMBr);
4377         if (rc)
4378                 return rc;
4379
4380         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4381                 name_len =
4382                     cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4383                                  PATH_MAX, nls_codepage, remap);
4384                 /* We can not add the asterik earlier in case
4385                 it got remapped to 0xF03A as if it were part of the
4386                 directory name instead of a wildcard */
4387                 name_len *= 2;
4388                 pSMB->FileName[name_len] = dirsep;
4389                 pSMB->FileName[name_len+1] = 0;
4390                 pSMB->FileName[name_len+2] = '*';
4391                 pSMB->FileName[name_len+3] = 0;
4392                 name_len += 4; /* now the trailing null */
4393                 pSMB->FileName[name_len] = 0; /* null terminate just in case */
4394                 pSMB->FileName[name_len+1] = 0;
4395                 name_len += 2;
4396         } else {        /* BB add check for overrun of SMB buf BB */
4397                 name_len = strnlen(searchName, PATH_MAX);
4398 /* BB fix here and in unicode clause above ie
4399                 if (name_len > buffersize-header)
4400                         free buffer exit; BB */
4401                 strncpy(pSMB->FileName, searchName, name_len);
4402                 pSMB->FileName[name_len] = dirsep;
4403                 pSMB->FileName[name_len+1] = '*';
4404                 pSMB->FileName[name_len+2] = 0;
4405                 name_len += 3;
4406         }
4407
4408         params = 12 + name_len /* includes null */ ;
4409         pSMB->TotalDataCount = 0;       /* no EAs */
4410         pSMB->MaxParameterCount = cpu_to_le16(10);
4411         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4412         pSMB->MaxSetupCount = 0;
4413         pSMB->Reserved = 0;
4414         pSMB->Flags = 0;
4415         pSMB->Timeout = 0;
4416         pSMB->Reserved2 = 0;
4417         byte_count = params + 1 /* pad */ ;
4418         pSMB->TotalParameterCount = cpu_to_le16(params);
4419         pSMB->ParameterCount = pSMB->TotalParameterCount;
4420         pSMB->ParameterOffset = cpu_to_le16(
4421               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4422                 - 4);
4423         pSMB->DataCount = 0;
4424         pSMB->DataOffset = 0;
4425         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4426         pSMB->Reserved3 = 0;
4427         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4428         pSMB->SearchAttributes =
4429             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4430                         ATTR_DIRECTORY);
4431         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4432         pSMB->SearchFlags = cpu_to_le16(search_flags);
4433         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4434
4435         /* BB what should we set StorageType to? Does it matter? BB */
4436         pSMB->SearchStorageType = 0;
4437         inc_rfc1001_len(pSMB, byte_count);
4438         pSMB->ByteCount = cpu_to_le16(byte_count);
4439
4440         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4441                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4442         cifs_stats_inc(&tcon->num_ffirst);
4443
4444         if (rc) {/* BB add logic to retry regular search if Unix search
4445                         rejected unexpectedly by server */
4446                 /* BB Add code to handle unsupported level rc */
4447                 cFYI(1, "Error in FindFirst = %d", rc);
4448
4449                 cifs_buf_release(pSMB);
4450
4451                 /* BB eventually could optimize out free and realloc of buf */
4452                 /*    for this case */
4453                 if (rc == -EAGAIN)
4454                         goto findFirstRetry;
4455         } else { /* decode response */
4456                 /* BB remember to free buffer if error BB */
4457                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4458                 if (rc == 0) {
4459                         unsigned int lnoff;
4460
4461                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4462                                 psrch_inf->unicode = true;
4463                         else
4464                                 psrch_inf->unicode = false;
4465
4466                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4467                         psrch_inf->smallBuf = 0;
4468                         psrch_inf->srch_entries_start =
4469                                 (char *) &pSMBr->hdr.Protocol +
4470                                         le16_to_cpu(pSMBr->t2.DataOffset);
4471                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4472                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4473
4474                         if (parms->EndofSearch)
4475                                 psrch_inf->endOfSearch = true;
4476                         else
4477                                 psrch_inf->endOfSearch = false;
4478
4479                         psrch_inf->entries_in_buffer =
4480                                         le16_to_cpu(parms->SearchCount);
4481                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4482                                 psrch_inf->entries_in_buffer;
4483                         lnoff = le16_to_cpu(parms->LastNameOffset);
4484                         if (CIFSMaxBufSize < lnoff) {
4485                                 cERROR(1, "ignoring corrupt resume name");
4486                                 psrch_inf->last_entry = NULL;
4487                                 return rc;
4488                         }
4489
4490                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4491                                                         lnoff;
4492
4493                         *pnetfid = parms->SearchHandle;
4494                 } else {
4495                         cifs_buf_release(pSMB);
4496                 }
4497         }
4498
4499         return rc;
4500 }
4501
4502 int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle,
4503                  __u16 search_flags, struct cifs_search_info *psrch_inf)
4504 {
4505         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4506         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4507         T2_FNEXT_RSP_PARMS *parms;
4508         char *response_data;
4509         int rc = 0;
4510         int bytes_returned;
4511         unsigned int name_len;
4512         __u16 params, byte_count;
4513
4514         cFYI(1, "In FindNext");
4515
4516         if (psrch_inf->endOfSearch)
4517                 return -ENOENT;
4518
4519         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4520                 (void **) &pSMBr);
4521         if (rc)
4522                 return rc;
4523
4524         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4525         byte_count = 0;
4526         pSMB->TotalDataCount = 0;       /* no EAs */
4527         pSMB->MaxParameterCount = cpu_to_le16(8);
4528         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4529         pSMB->MaxSetupCount = 0;
4530         pSMB->Reserved = 0;
4531         pSMB->Flags = 0;
4532         pSMB->Timeout = 0;
4533         pSMB->Reserved2 = 0;
4534         pSMB->ParameterOffset =  cpu_to_le16(
4535               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4536         pSMB->DataCount = 0;
4537         pSMB->DataOffset = 0;
4538         pSMB->SetupCount = 1;
4539         pSMB->Reserved3 = 0;
4540         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4541         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4542         pSMB->SearchCount =
4543                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4544         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4545         pSMB->ResumeKey = psrch_inf->resume_key;
4546         pSMB->SearchFlags = cpu_to_le16(search_flags);
4547
4548         name_len = psrch_inf->resume_name_len;
4549         params += name_len;
4550         if (name_len < PATH_MAX) {
4551                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4552                 byte_count += name_len;
4553                 /* 14 byte parm len above enough for 2 byte null terminator */
4554                 pSMB->ResumeFileName[name_len] = 0;
4555                 pSMB->ResumeFileName[name_len+1] = 0;
4556         } else {
4557                 rc = -EINVAL;
4558                 goto FNext2_err_exit;
4559         }
4560         byte_count = params + 1 /* pad */ ;
4561         pSMB->TotalParameterCount = cpu_to_le16(params);
4562         pSMB->ParameterCount = pSMB->TotalParameterCount;
4563         inc_rfc1001_len(pSMB, byte_count);
4564         pSMB->ByteCount = cpu_to_le16(byte_count);
4565
4566         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4567                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4568         cifs_stats_inc(&tcon->num_fnext);
4569         if (rc) {
4570                 if (rc == -EBADF) {
4571                         psrch_inf->endOfSearch = true;
4572                         cifs_buf_release(pSMB);
4573                         rc = 0; /* search probably was closed at end of search*/
4574                 } else
4575                         cFYI(1, "FindNext returned = %d", rc);
4576         } else {                /* decode response */
4577                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4578
4579                 if (rc == 0) {
4580                         unsigned int lnoff;
4581
4582                         /* BB fixme add lock for file (srch_info) struct here */
4583                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4584                                 psrch_inf->unicode = true;
4585                         else
4586                                 psrch_inf->unicode = false;
4587                         response_data = (char *) &pSMBr->hdr.Protocol +
4588                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4589                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4590                         response_data = (char *)&pSMBr->hdr.Protocol +
4591                                 le16_to_cpu(pSMBr->t2.DataOffset);
4592                         if (psrch_inf->smallBuf)
4593                                 cifs_small_buf_release(
4594                                         psrch_inf->ntwrk_buf_start);
4595                         else
4596                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4597                         psrch_inf->srch_entries_start = response_data;
4598                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4599                         psrch_inf->smallBuf = 0;
4600                         if (parms->EndofSearch)
4601                                 psrch_inf->endOfSearch = true;
4602                         else
4603                                 psrch_inf->endOfSearch = false;
4604                         psrch_inf->entries_in_buffer =
4605                                                 le16_to_cpu(parms->SearchCount);
4606                         psrch_inf->index_of_last_entry +=
4607                                 psrch_inf->entries_in_buffer;
4608                         lnoff = le16_to_cpu(parms->LastNameOffset);
4609                         if (CIFSMaxBufSize < lnoff) {
4610                                 cERROR(1, "ignoring corrupt resume name");
4611                                 psrch_inf->last_entry = NULL;
4612                                 return rc;
4613                         } else
4614                                 psrch_inf->last_entry =
4615                                         psrch_inf->srch_entries_start + lnoff;
4616
4617 /*  cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
4618             psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4619
4620                         /* BB fixme add unlock here */
4621                 }
4622
4623         }
4624
4625         /* BB On error, should we leave previous search buf (and count and
4626         last entry fields) intact or free the previous one? */
4627
4628         /* Note: On -EAGAIN error only caller can retry on handle based calls
4629         since file handle passed in no longer valid */
4630 FNext2_err_exit:
4631         if (rc != 0)
4632                 cifs_buf_release(pSMB);
4633         return rc;
4634 }
4635
4636 int
4637 CIFSFindClose(const int xid, struct cifs_tcon *tcon,
4638               const __u16 searchHandle)
4639 {
4640         int rc = 0;
4641         FINDCLOSE_REQ *pSMB = NULL;
4642
4643         cFYI(1, "In CIFSSMBFindClose");
4644         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4645
4646         /* no sense returning error if session restarted
4647                 as file handle has been closed */
4648         if (rc == -EAGAIN)
4649                 return 0;
4650         if (rc)
4651                 return rc;
4652
4653         pSMB->FileID = searchHandle;
4654         pSMB->ByteCount = 0;
4655         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4656         if (rc)
4657                 cERROR(1, "Send error in FindClose = %d", rc);
4658
4659         cifs_stats_inc(&tcon->num_fclose);
4660
4661         /* Since session is dead, search handle closed on server already */
4662         if (rc == -EAGAIN)
4663                 rc = 0;
4664
4665         return rc;
4666 }
4667
4668 int
4669 CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
4670                       const unsigned char *searchName,
4671                       __u64 *inode_number,
4672                       const struct nls_table *nls_codepage, int remap)
4673 {
4674         int rc = 0;
4675         TRANSACTION2_QPI_REQ *pSMB = NULL;
4676         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4677         int name_len, bytes_returned;
4678         __u16 params, byte_count;
4679
4680         cFYI(1, "In GetSrvInodeNum for %s", searchName);
4681         if (tcon == NULL)
4682                 return -ENODEV;
4683
4684 GetInodeNumberRetry:
4685         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4686                       (void **) &pSMBr);
4687         if (rc)
4688                 return rc;
4689
4690         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4691                 name_len =
4692                         cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4693                                          PATH_MAX, nls_codepage, remap);
4694                 name_len++;     /* trailing null */
4695                 name_len *= 2;
4696         } else {        /* BB improve the check for buffer overruns BB */
4697                 name_len = strnlen(searchName, PATH_MAX);
4698                 name_len++;     /* trailing null */
4699                 strncpy(pSMB->FileName, searchName, name_len);
4700         }
4701
4702         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4703         pSMB->TotalDataCount = 0;
4704         pSMB->MaxParameterCount = cpu_to_le16(2);
4705         /* BB find exact max data count below from sess structure BB */
4706         pSMB->MaxDataCount = cpu_to_le16(4000);
4707         pSMB->MaxSetupCount = 0;
4708         pSMB->Reserved = 0;
4709         pSMB->Flags = 0;
4710         pSMB->Timeout = 0;
4711         pSMB->Reserved2 = 0;
4712         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4713                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4714         pSMB->DataCount = 0;
4715         pSMB->DataOffset = 0;
4716         pSMB->SetupCount = 1;
4717         pSMB->Reserved3 = 0;
4718         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4719         byte_count = params + 1 /* pad */ ;
4720         pSMB->TotalParameterCount = cpu_to_le16(params);
4721         pSMB->ParameterCount = pSMB->TotalParameterCount;
4722         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4723         pSMB->Reserved4 = 0;
4724         inc_rfc1001_len(pSMB, byte_count);
4725         pSMB->ByteCount = cpu_to_le16(byte_count);
4726
4727         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4728                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4729         if (rc) {
4730                 cFYI(1, "error %d in QueryInternalInfo", rc);
4731         } else {
4732                 /* decode response */
4733                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4734                 /* BB also check enough total bytes returned */
4735                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4736                         /* If rc should we check for EOPNOSUPP and
4737                         disable the srvino flag? or in caller? */
4738                         rc = -EIO;      /* bad smb */
4739                 else {
4740                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4741                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4742                         struct file_internal_info *pfinfo;
4743                         /* BB Do we need a cast or hash here ? */
4744                         if (count < 8) {
4745                                 cFYI(1, "Illegal size ret in QryIntrnlInf");
4746                                 rc = -EIO;
4747                                 goto GetInodeNumOut;
4748                         }
4749                         pfinfo = (struct file_internal_info *)
4750                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4751                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4752                 }
4753         }
4754 GetInodeNumOut:
4755         cifs_buf_release(pSMB);
4756         if (rc == -EAGAIN)
4757                 goto GetInodeNumberRetry;
4758         return rc;
4759 }
4760
4761 /* parses DFS refferal V3 structure
4762  * caller is responsible for freeing target_nodes
4763  * returns:
4764  *      on success - 0
4765  *      on failure - errno
4766  */
4767 static int
4768 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4769                 unsigned int *num_of_nodes,
4770                 struct dfs_info3_param **target_nodes,
4771                 const struct nls_table *nls_codepage, int remap,
4772                 const char *searchName)
4773 {
4774         int i, rc = 0;
4775         char *data_end;
4776         bool is_unicode;
4777         struct dfs_referral_level_3 *ref;
4778
4779         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4780                 is_unicode = true;
4781         else
4782                 is_unicode = false;
4783         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4784
4785         if (*num_of_nodes < 1) {
4786                 cERROR(1, "num_referrals: must be at least > 0,"
4787                         "but we get num_referrals = %d\n", *num_of_nodes);
4788                 rc = -EINVAL;
4789                 goto parse_DFS_referrals_exit;
4790         }
4791
4792         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4793         if (ref->VersionNumber != cpu_to_le16(3)) {
4794                 cERROR(1, "Referrals of V%d version are not supported,"
4795                         "should be V3", le16_to_cpu(ref->VersionNumber));
4796                 rc = -EINVAL;
4797                 goto parse_DFS_referrals_exit;
4798         }
4799
4800         /* get the upper boundary of the resp buffer */
4801         data_end = (char *)(&(pSMBr->PathConsumed)) +
4802                                 le16_to_cpu(pSMBr->t2.DataCount);
4803
4804         cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
4805                         *num_of_nodes,
4806                         le32_to_cpu(pSMBr->DFSFlags));
4807
4808         *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
4809                         *num_of_nodes, GFP_KERNEL);
4810         if (*target_nodes == NULL) {
4811                 cERROR(1, "Failed to allocate buffer for target_nodes\n");
4812                 rc = -ENOMEM;
4813                 goto parse_DFS_referrals_exit;
4814         }
4815
4816         /* collect necessary data from referrals */
4817         for (i = 0; i < *num_of_nodes; i++) {
4818                 char *temp;
4819                 int max_len;
4820                 struct dfs_info3_param *node = (*target_nodes)+i;
4821
4822                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4823                 if (is_unicode) {
4824                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4825                                                 GFP_KERNEL);
4826                         if (tmp == NULL) {
4827                                 rc = -ENOMEM;
4828                                 goto parse_DFS_referrals_exit;
4829                         }
4830                         cifsConvertToUCS((__le16 *) tmp, searchName,
4831                                         PATH_MAX, nls_codepage, remap);
4832                         node->path_consumed = cifs_ucs2_bytes(tmp,
4833                                         le16_to_cpu(pSMBr->PathConsumed),
4834                                         nls_codepage);
4835                         kfree(tmp);
4836                 } else
4837                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4838
4839                 node->server_type = le16_to_cpu(ref->ServerType);
4840                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4841
4842                 /* copy DfsPath */
4843                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4844                 max_len = data_end - temp;
4845                 node->path_name = cifs_strndup_from_ucs(temp, max_len,
4846                                                       is_unicode, nls_codepage);
4847                 if (!node->path_name) {
4848                         rc = -ENOMEM;
4849                         goto parse_DFS_referrals_exit;
4850                 }
4851
4852                 /* copy link target UNC */
4853                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4854                 max_len = data_end - temp;
4855                 node->node_name = cifs_strndup_from_ucs(temp, max_len,
4856                                                       is_unicode, nls_codepage);
4857                 if (!node->node_name) {
4858                         rc = -ENOMEM;
4859                         goto parse_DFS_referrals_exit;
4860                 }
4861
4862                 ref++;
4863         }
4864
4865 parse_DFS_referrals_exit:
4866         if (rc) {
4867                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4868                 *target_nodes = NULL;
4869                 *num_of_nodes = 0;
4870         }
4871         return rc;
4872 }
4873
4874 int
4875 CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4876                 const unsigned char *searchName,
4877                 struct dfs_info3_param **target_nodes,
4878                 unsigned int *num_of_nodes,
4879                 const struct nls_table *nls_codepage, int remap)
4880 {
4881 /* TRANS2_GET_DFS_REFERRAL */
4882         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4883         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4884         int rc = 0;
4885         int bytes_returned;
4886         int name_len;
4887         __u16 params, byte_count;
4888         *num_of_nodes = 0;
4889         *target_nodes = NULL;
4890
4891         cFYI(1, "In GetDFSRefer the path %s", searchName);
4892         if (ses == NULL)
4893                 return -ENODEV;
4894 getDFSRetry:
4895         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4896                       (void **) &pSMBr);
4897         if (rc)
4898                 return rc;
4899
4900         /* server pointer checked in called function,
4901         but should never be null here anyway */
4902         pSMB->hdr.Mid = GetNextMid(ses->server);
4903         pSMB->hdr.Tid = ses->ipc_tid;
4904         pSMB->hdr.Uid = ses->Suid;
4905         if (ses->capabilities & CAP_STATUS32)
4906                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4907         if (ses->capabilities & CAP_DFS)
4908                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4909
4910         if (ses->capabilities & CAP_UNICODE) {
4911                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4912                 name_len =
4913                     cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
4914                                      searchName, PATH_MAX, nls_codepage, remap);
4915                 name_len++;     /* trailing null */
4916                 name_len *= 2;
4917         } else {        /* BB improve the check for buffer overruns BB */
4918                 name_len = strnlen(searchName, PATH_MAX);
4919                 name_len++;     /* trailing null */
4920                 strncpy(pSMB->RequestFileName, searchName, name_len);
4921         }
4922
4923         if (ses->server) {
4924                 if (ses->server->sec_mode &
4925                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4926                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4927         }
4928
4929         pSMB->hdr.Uid = ses->Suid;
4930
4931         params = 2 /* level */  + name_len /*includes null */ ;
4932         pSMB->TotalDataCount = 0;
4933         pSMB->DataCount = 0;
4934         pSMB->DataOffset = 0;
4935         pSMB->MaxParameterCount = 0;
4936         /* BB find exact max SMB PDU from sess structure BB */
4937         pSMB->MaxDataCount = cpu_to_le16(4000);
4938         pSMB->MaxSetupCount = 0;
4939         pSMB->Reserved = 0;
4940         pSMB->Flags = 0;
4941         pSMB->Timeout = 0;
4942         pSMB->Reserved2 = 0;
4943         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4944           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4945         pSMB->SetupCount = 1;
4946         pSMB->Reserved3 = 0;
4947         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4948         byte_count = params + 3 /* pad */ ;
4949         pSMB->ParameterCount = cpu_to_le16(params);
4950         pSMB->TotalParameterCount = pSMB->ParameterCount;
4951         pSMB->MaxReferralLevel = cpu_to_le16(3);
4952         inc_rfc1001_len(pSMB, byte_count);
4953         pSMB->ByteCount = cpu_to_le16(byte_count);
4954
4955         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4956                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4957         if (rc) {
4958                 cFYI(1, "Send error in GetDFSRefer = %d", rc);
4959                 goto GetDFSRefExit;
4960         }
4961         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4962
4963         /* BB Also check if enough total bytes returned? */
4964         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4965                 rc = -EIO;      /* bad smb */
4966                 goto GetDFSRefExit;
4967         }
4968
4969         cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
4970                                 get_bcc(&pSMBr->hdr),
4971                                 le16_to_cpu(pSMBr->t2.DataOffset));
4972
4973         /* parse returned result into more usable form */
4974         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4975                                  target_nodes, nls_codepage, remap,
4976                                  searchName);
4977
4978 GetDFSRefExit:
4979         cifs_buf_release(pSMB);
4980
4981         if (rc == -EAGAIN)
4982                 goto getDFSRetry;
4983
4984         return rc;
4985 }
4986
4987 /* Query File System Info such as free space to old servers such as Win 9x */
4988 int
4989 SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4990 {
4991 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4992         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4993         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4994         FILE_SYSTEM_ALLOC_INFO *response_data;
4995         int rc = 0;
4996         int bytes_returned = 0;
4997         __u16 params, byte_count;
4998
4999         cFYI(1, "OldQFSInfo");
5000 oldQFSInfoRetry:
5001         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5002                 (void **) &pSMBr);
5003         if (rc)
5004                 return rc;
5005
5006         params = 2;     /* level */
5007         pSMB->TotalDataCount = 0;
5008         pSMB->MaxParameterCount = cpu_to_le16(2);
5009         pSMB->MaxDataCount = cpu_to_le16(1000);
5010         pSMB->MaxSetupCount = 0;
5011         pSMB->Reserved = 0;
5012         pSMB->Flags = 0;
5013         pSMB->Timeout = 0;
5014         pSMB->Reserved2 = 0;
5015         byte_count = params + 1 /* pad */ ;
5016         pSMB->TotalParameterCount = cpu_to_le16(params);
5017         pSMB->ParameterCount = pSMB->TotalParameterCount;
5018         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5019         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5020         pSMB->DataCount = 0;
5021         pSMB->DataOffset = 0;
5022         pSMB->SetupCount = 1;
5023         pSMB->Reserved3 = 0;
5024         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5025         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5026         inc_rfc1001_len(pSMB, byte_count);
5027         pSMB->ByteCount = cpu_to_le16(byte_count);
5028
5029         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5030                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5031         if (rc) {
5032                 cFYI(1, "Send error in QFSInfo = %d", rc);
5033         } else {                /* decode response */
5034                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5035
5036                 if (rc || get_bcc(&pSMBr->hdr) < 18)
5037                         rc = -EIO;      /* bad smb */
5038                 else {
5039                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5040                         cFYI(1, "qfsinf resp BCC: %d  Offset %d",
5041                                  get_bcc(&pSMBr->hdr), data_offset);
5042
5043                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
5044                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
5045                         FSData->f_bsize =
5046                                 le16_to_cpu(response_data->BytesPerSector) *
5047                                 le32_to_cpu(response_data->
5048                                         SectorsPerAllocationUnit);
5049                         FSData->f_blocks =
5050                                le32_to_cpu(response_data->TotalAllocationUnits);
5051                         FSData->f_bfree = FSData->f_bavail =
5052                                 le32_to_cpu(response_data->FreeAllocationUnits);
5053                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5054                              (unsigned long long)FSData->f_blocks,
5055                              (unsigned long long)FSData->f_bfree,
5056                              FSData->f_bsize);
5057                 }
5058         }
5059         cifs_buf_release(pSMB);
5060
5061         if (rc == -EAGAIN)
5062                 goto oldQFSInfoRetry;
5063
5064         return rc;
5065 }
5066
5067 int
5068 CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
5069 {
5070 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5071         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5072         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5073         FILE_SYSTEM_INFO *response_data;
5074         int rc = 0;
5075         int bytes_returned = 0;
5076         __u16 params, byte_count;
5077
5078         cFYI(1, "In QFSInfo");
5079 QFSInfoRetry:
5080         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5081                       (void **) &pSMBr);
5082         if (rc)
5083                 return rc;
5084
5085         params = 2;     /* level */
5086         pSMB->TotalDataCount = 0;
5087         pSMB->MaxParameterCount = cpu_to_le16(2);
5088         pSMB->MaxDataCount = cpu_to_le16(1000);
5089         pSMB->MaxSetupCount = 0;
5090         pSMB->Reserved = 0;
5091         pSMB->Flags = 0;
5092         pSMB->Timeout = 0;
5093         pSMB->Reserved2 = 0;
5094         byte_count = params + 1 /* pad */ ;
5095         pSMB->TotalParameterCount = cpu_to_le16(params);
5096         pSMB->ParameterCount = pSMB->TotalParameterCount;
5097         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5098                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5099         pSMB->DataCount = 0;
5100         pSMB->DataOffset = 0;
5101         pSMB->SetupCount = 1;
5102         pSMB->Reserved3 = 0;
5103         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5104         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5105         inc_rfc1001_len(pSMB, byte_count);
5106         pSMB->ByteCount = cpu_to_le16(byte_count);
5107
5108         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5109                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5110         if (rc) {
5111                 cFYI(1, "Send error in QFSInfo = %d", rc);
5112         } else {                /* decode response */
5113                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5114
5115                 if (rc || get_bcc(&pSMBr->hdr) < 24)
5116                         rc = -EIO;      /* bad smb */
5117                 else {
5118                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5119
5120                         response_data =
5121                             (FILE_SYSTEM_INFO
5122                              *) (((char *) &pSMBr->hdr.Protocol) +
5123                                  data_offset);
5124                         FSData->f_bsize =
5125                             le32_to_cpu(response_data->BytesPerSector) *
5126                             le32_to_cpu(response_data->
5127                                         SectorsPerAllocationUnit);
5128                         FSData->f_blocks =
5129                             le64_to_cpu(response_data->TotalAllocationUnits);
5130                         FSData->f_bfree = FSData->f_bavail =
5131                             le64_to_cpu(response_data->FreeAllocationUnits);
5132                         cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
5133                              (unsigned long long)FSData->f_blocks,
5134                              (unsigned long long)FSData->f_bfree,
5135                              FSData->f_bsize);
5136                 }
5137         }
5138         cifs_buf_release(pSMB);
5139
5140         if (rc == -EAGAIN)
5141                 goto QFSInfoRetry;
5142
5143         return rc;
5144 }
5145
5146 int
5147 CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
5148 {
5149 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5150         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5151         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5152         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5153         int rc = 0;
5154         int bytes_returned = 0;
5155         __u16 params, byte_count;
5156
5157         cFYI(1, "In QFSAttributeInfo");
5158 QFSAttributeRetry:
5159         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5160                       (void **) &pSMBr);
5161         if (rc)
5162                 return rc;
5163
5164         params = 2;     /* level */
5165         pSMB->TotalDataCount = 0;
5166         pSMB->MaxParameterCount = cpu_to_le16(2);
5167         /* BB find exact max SMB PDU from sess structure BB */
5168         pSMB->MaxDataCount = cpu_to_le16(1000);
5169         pSMB->MaxSetupCount = 0;
5170         pSMB->Reserved = 0;
5171         pSMB->Flags = 0;
5172         pSMB->Timeout = 0;
5173         pSMB->Reserved2 = 0;
5174         byte_count = params + 1 /* pad */ ;
5175         pSMB->TotalParameterCount = cpu_to_le16(params);
5176         pSMB->ParameterCount = pSMB->TotalParameterCount;
5177         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5178                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5179         pSMB->DataCount = 0;
5180         pSMB->DataOffset = 0;
5181         pSMB->SetupCount = 1;
5182         pSMB->Reserved3 = 0;
5183         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5184         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5185         inc_rfc1001_len(pSMB, byte_count);
5186         pSMB->ByteCount = cpu_to_le16(byte_count);
5187
5188         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5189                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5190         if (rc) {
5191                 cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
5192         } else {                /* decode response */
5193                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5194
5195                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5196                         /* BB also check if enough bytes returned */
5197                         rc = -EIO;      /* bad smb */
5198                 } else {
5199                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5200                         response_data =
5201                             (FILE_SYSTEM_ATTRIBUTE_INFO
5202                              *) (((char *) &pSMBr->hdr.Protocol) +
5203                                  data_offset);
5204                         memcpy(&tcon->fsAttrInfo, response_data,
5205                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5206                 }
5207         }
5208         cifs_buf_release(pSMB);
5209
5210         if (rc == -EAGAIN)
5211                 goto QFSAttributeRetry;
5212
5213         return rc;
5214 }
5215
5216 int
5217 CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
5218 {
5219 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5220         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5221         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5222         FILE_SYSTEM_DEVICE_INFO *response_data;
5223         int rc = 0;
5224         int bytes_returned = 0;
5225         __u16 params, byte_count;
5226
5227         cFYI(1, "In QFSDeviceInfo");
5228 QFSDeviceRetry:
5229         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5230                       (void **) &pSMBr);
5231         if (rc)
5232                 return rc;
5233
5234         params = 2;     /* level */
5235         pSMB->TotalDataCount = 0;
5236         pSMB->MaxParameterCount = cpu_to_le16(2);
5237         /* BB find exact max SMB PDU from sess structure BB */
5238         pSMB->MaxDataCount = cpu_to_le16(1000);
5239         pSMB->MaxSetupCount = 0;
5240         pSMB->Reserved = 0;
5241         pSMB->Flags = 0;
5242         pSMB->Timeout = 0;
5243         pSMB->Reserved2 = 0;
5244         byte_count = params + 1 /* pad */ ;
5245         pSMB->TotalParameterCount = cpu_to_le16(params);
5246         pSMB->ParameterCount = pSMB->TotalParameterCount;
5247         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5248                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5249
5250         pSMB->DataCount = 0;
5251         pSMB->DataOffset = 0;
5252         pSMB->SetupCount = 1;
5253         pSMB->Reserved3 = 0;
5254         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5255         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5256         inc_rfc1001_len(pSMB, byte_count);
5257         pSMB->ByteCount = cpu_to_le16(byte_count);
5258
5259         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5260                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5261         if (rc) {
5262                 cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
5263         } else {                /* decode response */
5264                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5265
5266                 if (rc || get_bcc(&pSMBr->hdr) <
5267                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5268                         rc = -EIO;      /* bad smb */
5269                 else {
5270                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5271                         response_data =
5272                             (FILE_SYSTEM_DEVICE_INFO *)
5273                                 (((char *) &pSMBr->hdr.Protocol) +
5274                                  data_offset);
5275                         memcpy(&tcon->fsDevInfo, response_data,
5276                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5277                 }
5278         }
5279         cifs_buf_release(pSMB);
5280
5281         if (rc == -EAGAIN)
5282                 goto QFSDeviceRetry;
5283
5284         return rc;
5285 }
5286
5287 int
5288 CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
5289 {
5290 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5291         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5292         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5293         FILE_SYSTEM_UNIX_INFO *response_data;
5294         int rc = 0;
5295         int bytes_returned = 0;
5296         __u16 params, byte_count;
5297
5298         cFYI(1, "In QFSUnixInfo");
5299 QFSUnixRetry:
5300         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5301                                    (void **) &pSMB, (void **) &pSMBr);
5302         if (rc)
5303                 return rc;
5304
5305         params = 2;     /* level */
5306         pSMB->TotalDataCount = 0;
5307         pSMB->DataCount = 0;
5308         pSMB->DataOffset = 0;
5309         pSMB->MaxParameterCount = cpu_to_le16(2);
5310         /* BB find exact max SMB PDU from sess structure BB */
5311         pSMB->MaxDataCount = cpu_to_le16(100);
5312         pSMB->MaxSetupCount = 0;
5313         pSMB->Reserved = 0;
5314         pSMB->Flags = 0;
5315         pSMB->Timeout = 0;
5316         pSMB->Reserved2 = 0;
5317         byte_count = params + 1 /* pad */ ;
5318         pSMB->ParameterCount = cpu_to_le16(params);
5319         pSMB->TotalParameterCount = pSMB->ParameterCount;
5320         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5321                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5322         pSMB->SetupCount = 1;
5323         pSMB->Reserved3 = 0;
5324         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5325         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5326         inc_rfc1001_len(pSMB, byte_count);
5327         pSMB->ByteCount = cpu_to_le16(byte_count);
5328
5329         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5330                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5331         if (rc) {
5332                 cERROR(1, "Send error in QFSUnixInfo = %d", rc);
5333         } else {                /* decode response */
5334                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5335
5336                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5337                         rc = -EIO;      /* bad smb */
5338                 } else {
5339                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5340                         response_data =
5341                             (FILE_SYSTEM_UNIX_INFO
5342                              *) (((char *) &pSMBr->hdr.Protocol) +
5343                                  data_offset);
5344                         memcpy(&tcon->fsUnixInfo, response_data,
5345                                sizeof(FILE_SYSTEM_UNIX_INFO));
5346                 }
5347         }
5348         cifs_buf_release(pSMB);
5349
5350         if (rc == -EAGAIN)
5351                 goto QFSUnixRetry;
5352
5353
5354         return rc;
5355 }
5356
5357 int
5358 CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
5359 {
5360 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5361         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5362         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5363         int rc = 0;
5364         int bytes_returned = 0;
5365         __u16 params, param_offset, offset, byte_count;
5366
5367         cFYI(1, "In SETFSUnixInfo");
5368 SETFSUnixRetry:
5369         /* BB switch to small buf init to save memory */
5370         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5371                                         (void **) &pSMB, (void **) &pSMBr);
5372         if (rc)
5373                 return rc;
5374
5375         params = 4;     /* 2 bytes zero followed by info level. */
5376         pSMB->MaxSetupCount = 0;
5377         pSMB->Reserved = 0;
5378         pSMB->Flags = 0;
5379         pSMB->Timeout = 0;
5380         pSMB->Reserved2 = 0;
5381         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5382                                 - 4;
5383         offset = param_offset + params;
5384
5385         pSMB->MaxParameterCount = cpu_to_le16(4);
5386         /* BB find exact max SMB PDU from sess structure BB */
5387         pSMB->MaxDataCount = cpu_to_le16(100);
5388         pSMB->SetupCount = 1;
5389         pSMB->Reserved3 = 0;
5390         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5391         byte_count = 1 /* pad */ + params + 12;
5392
5393         pSMB->DataCount = cpu_to_le16(12);
5394         pSMB->ParameterCount = cpu_to_le16(params);
5395         pSMB->TotalDataCount = pSMB->DataCount;
5396         pSMB->TotalParameterCount = pSMB->ParameterCount;
5397         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5398         pSMB->DataOffset = cpu_to_le16(offset);
5399
5400         /* Params. */
5401         pSMB->FileNum = 0;
5402         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5403
5404         /* Data. */
5405         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5406         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5407         pSMB->ClientUnixCap = cpu_to_le64(cap);
5408
5409         inc_rfc1001_len(pSMB, byte_count);
5410         pSMB->ByteCount = cpu_to_le16(byte_count);
5411
5412         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5413                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5414         if (rc) {
5415                 cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
5416         } else {                /* decode response */
5417                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5418                 if (rc)
5419                         rc = -EIO;      /* bad smb */
5420         }
5421         cifs_buf_release(pSMB);
5422
5423         if (rc == -EAGAIN)
5424                 goto SETFSUnixRetry;
5425
5426         return rc;
5427 }
5428
5429
5430
5431 int
5432 CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
5433                    struct kstatfs *FSData)
5434 {
5435 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5436         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5437         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5438         FILE_SYSTEM_POSIX_INFO *response_data;
5439         int rc = 0;
5440         int bytes_returned = 0;
5441         __u16 params, byte_count;
5442
5443         cFYI(1, "In QFSPosixInfo");
5444 QFSPosixRetry:
5445         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5446                       (void **) &pSMBr);
5447         if (rc)
5448                 return rc;
5449
5450         params = 2;     /* level */
5451         pSMB->TotalDataCount = 0;
5452         pSMB->DataCount = 0;
5453         pSMB->DataOffset = 0;
5454         pSMB->MaxParameterCount = cpu_to_le16(2);
5455         /* BB find exact max SMB PDU from sess structure BB */
5456         pSMB->MaxDataCount = cpu_to_le16(100);
5457         pSMB->MaxSetupCount = 0;
5458         pSMB->Reserved = 0;
5459         pSMB->Flags = 0;
5460         pSMB->Timeout = 0;
5461         pSMB->Reserved2 = 0;
5462         byte_count = params + 1 /* pad */ ;
5463         pSMB->ParameterCount = cpu_to_le16(params);
5464         pSMB->TotalParameterCount = pSMB->ParameterCount;
5465         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5466                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5467         pSMB->SetupCount = 1;
5468         pSMB->Reserved3 = 0;
5469         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5470         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5471         inc_rfc1001_len(pSMB, byte_count);
5472         pSMB->ByteCount = cpu_to_le16(byte_count);
5473
5474         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5475                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5476         if (rc) {
5477                 cFYI(1, "Send error in QFSUnixInfo = %d", rc);
5478         } else {                /* decode response */
5479                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5480
5481                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5482                         rc = -EIO;      /* bad smb */
5483                 } else {
5484                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5485                         response_data =
5486                             (FILE_SYSTEM_POSIX_INFO
5487                              *) (((char *) &pSMBr->hdr.Protocol) +
5488                                  data_offset);
5489                         FSData->f_bsize =
5490                                         le32_to_cpu(response_data->BlockSize);
5491                         FSData->f_blocks =
5492                                         le64_to_cpu(response_data->TotalBlocks);
5493                         FSData->f_bfree =
5494                             le64_to_cpu(response_data->BlocksAvail);
5495                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5496                                 FSData->f_bavail = FSData->f_bfree;
5497                         } else {
5498                                 FSData->f_bavail =
5499                                     le64_to_cpu(response_data->UserBlocksAvail);
5500                         }
5501                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5502                                 FSData->f_files =
5503                                      le64_to_cpu(response_data->TotalFileNodes);
5504                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5505                                 FSData->f_ffree =
5506                                       le64_to_cpu(response_data->FreeFileNodes);
5507                 }
5508         }
5509         cifs_buf_release(pSMB);
5510
5511         if (rc == -EAGAIN)
5512                 goto QFSPosixRetry;
5513
5514         return rc;
5515 }
5516
5517
5518 /* We can not use write of zero bytes trick to
5519    set file size due to need for large file support.  Also note that
5520    this SetPathInfo is preferred to SetFileInfo based method in next
5521    routine which is only needed to work around a sharing violation bug
5522    in Samba which this routine can run into */
5523
5524 int
5525 CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
5526               __u64 size, bool SetAllocation,
5527               const struct nls_table *nls_codepage, int remap)
5528 {
5529         struct smb_com_transaction2_spi_req *pSMB = NULL;
5530         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5531         struct file_end_of_file_info *parm_data;
5532         int name_len;
5533         int rc = 0;
5534         int bytes_returned = 0;
5535         __u16 params, byte_count, data_count, param_offset, offset;
5536
5537         cFYI(1, "In SetEOF");
5538 SetEOFRetry:
5539         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5540                       (void **) &pSMBr);
5541         if (rc)
5542                 return rc;
5543
5544         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5545                 name_len =
5546                     cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5547                                      PATH_MAX, nls_codepage, remap);
5548                 name_len++;     /* trailing null */
5549                 name_len *= 2;
5550         } else {        /* BB improve the check for buffer overruns BB */
5551                 name_len = strnlen(fileName, PATH_MAX);
5552                 name_len++;     /* trailing null */
5553                 strncpy(pSMB->FileName, fileName, name_len);
5554         }
5555         params = 6 + name_len;
5556         data_count = sizeof(struct file_end_of_file_info);
5557         pSMB->MaxParameterCount = cpu_to_le16(2);
5558         pSMB->MaxDataCount = cpu_to_le16(4100);
5559         pSMB->MaxSetupCount = 0;
5560         pSMB->Reserved = 0;
5561         pSMB->Flags = 0;
5562         pSMB->Timeout = 0;
5563         pSMB->Reserved2 = 0;
5564         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5565                                 InformationLevel) - 4;
5566         offset = param_offset + params;
5567         if (SetAllocation) {
5568                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5569                         pSMB->InformationLevel =
5570                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5571                 else
5572                         pSMB->InformationLevel =
5573                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5574         } else /* Set File Size */  {
5575             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5576                     pSMB->InformationLevel =
5577                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5578             else
5579                     pSMB->InformationLevel =
5580                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5581         }
5582
5583         parm_data =
5584             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5585                                        offset);
5586         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5587         pSMB->DataOffset = cpu_to_le16(offset);
5588         pSMB->SetupCount = 1;
5589         pSMB->Reserved3 = 0;
5590         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5591         byte_count = 3 /* pad */  + params + data_count;
5592         pSMB->DataCount = cpu_to_le16(data_count);
5593         pSMB->TotalDataCount = pSMB->DataCount;
5594         pSMB->ParameterCount = cpu_to_le16(params);
5595         pSMB->TotalParameterCount = pSMB->ParameterCount;
5596         pSMB->Reserved4 = 0;
5597         inc_rfc1001_len(pSMB, byte_count);
5598         parm_data->FileSize = cpu_to_le64(size);
5599         pSMB->ByteCount = cpu_to_le16(byte_count);
5600         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5601                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5602         if (rc)
5603                 cFYI(1, "SetPathInfo (file size) returned %d", rc);
5604
5605         cifs_buf_release(pSMB);
5606
5607         if (rc == -EAGAIN)
5608                 goto SetEOFRetry;
5609
5610         return rc;
5611 }
5612
5613 int
5614 CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5615                    __u16 fid, __u32 pid_of_opener, bool SetAllocation)
5616 {
5617         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5618         struct file_end_of_file_info *parm_data;
5619         int rc = 0;
5620         __u16 params, param_offset, offset, byte_count, count;
5621
5622         cFYI(1, "SetFileSize (via SetFileInfo) %lld",
5623                         (long long)size);
5624         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5625
5626         if (rc)
5627                 return rc;
5628
5629         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5630         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5631
5632         params = 6;
5633         pSMB->MaxSetupCount = 0;
5634         pSMB->Reserved = 0;
5635         pSMB->Flags = 0;
5636         pSMB->Timeout = 0;
5637         pSMB->Reserved2 = 0;
5638         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5639         offset = param_offset + params;
5640
5641         count = sizeof(struct file_end_of_file_info);
5642         pSMB->MaxParameterCount = cpu_to_le16(2);
5643         /* BB find exact max SMB PDU from sess structure BB */
5644         pSMB->MaxDataCount = cpu_to_le16(1000);
5645         pSMB->SetupCount = 1;
5646         pSMB->Reserved3 = 0;
5647         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5648         byte_count = 3 /* pad */  + params + count;
5649         pSMB->DataCount = cpu_to_le16(count);
5650         pSMB->ParameterCount = cpu_to_le16(params);
5651         pSMB->TotalDataCount = pSMB->DataCount;
5652         pSMB->TotalParameterCount = pSMB->ParameterCount;
5653         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5654         parm_data =
5655                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5656                                 + offset);
5657         pSMB->DataOffset = cpu_to_le16(offset);
5658         parm_data->FileSize = cpu_to_le64(size);
5659         pSMB->Fid = fid;
5660         if (SetAllocation) {
5661                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5662                         pSMB->InformationLevel =
5663                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5664                 else
5665                         pSMB->InformationLevel =
5666                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5667         } else /* Set File Size */  {
5668             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5669                     pSMB->InformationLevel =
5670                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5671             else
5672                     pSMB->InformationLevel =
5673                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5674         }
5675         pSMB->Reserved4 = 0;
5676         inc_rfc1001_len(pSMB, byte_count);
5677         pSMB->ByteCount = cpu_to_le16(byte_count);
5678         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5679         if (rc) {
5680                 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5681         }
5682
5683         /* Note: On -EAGAIN error only caller can retry on handle based calls
5684                 since file handle passed in no longer valid */
5685
5686         return rc;
5687 }
5688
5689 /* Some legacy servers such as NT4 require that the file times be set on
5690    an open handle, rather than by pathname - this is awkward due to
5691    potential access conflicts on the open, but it is unavoidable for these
5692    old servers since the only other choice is to go from 100 nanosecond DCE
5693    time and resort to the original setpathinfo level which takes the ancient
5694    DOS time format with 2 second granularity */
5695 int
5696 CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5697                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5698 {
5699         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5700         char *data_offset;
5701         int rc = 0;
5702         __u16 params, param_offset, offset, byte_count, count;
5703
5704         cFYI(1, "Set Times (via SetFileInfo)");
5705         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5706
5707         if (rc)
5708                 return rc;
5709
5710         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5711         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5712
5713         params = 6;
5714         pSMB->MaxSetupCount = 0;
5715         pSMB->Reserved = 0;
5716         pSMB->Flags = 0;
5717         pSMB->Timeout = 0;
5718         pSMB->Reserved2 = 0;
5719         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5720         offset = param_offset + params;
5721
5722         data_offset = (char *)pSMB +
5723                         offsetof(struct smb_hdr, Protocol) + offset;
5724
5725         count = sizeof(FILE_BASIC_INFO);
5726         pSMB->MaxParameterCount = cpu_to_le16(2);
5727         /* BB find max SMB PDU from sess */
5728         pSMB->MaxDataCount = cpu_to_le16(1000);
5729         pSMB->SetupCount = 1;
5730         pSMB->Reserved3 = 0;
5731         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5732         byte_count = 3 /* pad */  + params + count;
5733         pSMB->DataCount = cpu_to_le16(count);
5734         pSMB->ParameterCount = cpu_to_le16(params);
5735         pSMB->TotalDataCount = pSMB->DataCount;
5736         pSMB->TotalParameterCount = pSMB->ParameterCount;
5737         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5738         pSMB->DataOffset = cpu_to_le16(offset);
5739         pSMB->Fid = fid;
5740         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5741                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5742         else
5743                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5744         pSMB->Reserved4 = 0;
5745         inc_rfc1001_len(pSMB, byte_count);
5746         pSMB->ByteCount = cpu_to_le16(byte_count);
5747         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5748         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5749         if (rc)
5750                 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5751
5752         /* Note: On -EAGAIN error only caller can retry on handle based calls
5753                 since file handle passed in no longer valid */
5754
5755         return rc;
5756 }
5757
5758 int
5759 CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5760                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5761 {
5762         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5763         char *data_offset;
5764         int rc = 0;
5765         __u16 params, param_offset, offset, byte_count, count;
5766
5767         cFYI(1, "Set File Disposition (via SetFileInfo)");
5768         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5769
5770         if (rc)
5771                 return rc;
5772
5773         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5774         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5775
5776         params = 6;
5777         pSMB->MaxSetupCount = 0;
5778         pSMB->Reserved = 0;
5779         pSMB->Flags = 0;
5780         pSMB->Timeout = 0;
5781         pSMB->Reserved2 = 0;
5782         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5783         offset = param_offset + params;
5784
5785         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5786
5787         count = 1;
5788         pSMB->MaxParameterCount = cpu_to_le16(2);
5789         /* BB find max SMB PDU from sess */
5790         pSMB->MaxDataCount = cpu_to_le16(1000);
5791         pSMB->SetupCount = 1;
5792         pSMB->Reserved3 = 0;
5793         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5794         byte_count = 3 /* pad */  + params + count;
5795         pSMB->DataCount = cpu_to_le16(count);
5796         pSMB->ParameterCount = cpu_to_le16(params);
5797         pSMB->TotalDataCount = pSMB->DataCount;
5798         pSMB->TotalParameterCount = pSMB->ParameterCount;
5799         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5800         pSMB->DataOffset = cpu_to_le16(offset);
5801         pSMB->Fid = fid;
5802         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5803         pSMB->Reserved4 = 0;
5804         inc_rfc1001_len(pSMB, byte_count);
5805         pSMB->ByteCount = cpu_to_le16(byte_count);
5806         *data_offset = delete_file ? 1 : 0;
5807         rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5808         if (rc)
5809                 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5810
5811         return rc;
5812 }
5813
5814 int
5815 CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5816                    const char *fileName, const FILE_BASIC_INFO *data,
5817                    const struct nls_table *nls_codepage, int remap)
5818 {
5819         TRANSACTION2_SPI_REQ *pSMB = NULL;
5820         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5821         int name_len;
5822         int rc = 0;
5823         int bytes_returned = 0;
5824         char *data_offset;
5825         __u16 params, param_offset, offset, byte_count, count;
5826
5827         cFYI(1, "In SetTimes");
5828
5829 SetTimesRetry:
5830         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5831                       (void **) &pSMBr);
5832         if (rc)
5833                 return rc;
5834
5835         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5836                 name_len =
5837                     cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5838                                      PATH_MAX, nls_codepage, remap);
5839                 name_len++;     /* trailing null */
5840                 name_len *= 2;
5841         } else {        /* BB improve the check for buffer overruns BB */
5842                 name_len = strnlen(fileName, PATH_MAX);
5843                 name_len++;     /* trailing null */
5844                 strncpy(pSMB->FileName, fileName, name_len);
5845         }
5846
5847         params = 6 + name_len;
5848         count = sizeof(FILE_BASIC_INFO);
5849         pSMB->MaxParameterCount = cpu_to_le16(2);
5850         /* BB find max SMB PDU from sess structure BB */
5851         pSMB->MaxDataCount = cpu_to_le16(1000);
5852         pSMB->MaxSetupCount = 0;
5853         pSMB->Reserved = 0;
5854         pSMB->Flags = 0;
5855         pSMB->Timeout = 0;
5856         pSMB->Reserved2 = 0;
5857         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5858                                 InformationLevel) - 4;
5859         offset = param_offset + params;
5860         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5861         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5862         pSMB->DataOffset = cpu_to_le16(offset);
5863         pSMB->SetupCount = 1;
5864         pSMB->Reserved3 = 0;
5865         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5866         byte_count = 3 /* pad */  + params + count;
5867
5868         pSMB->DataCount = cpu_to_le16(count);
5869         pSMB->ParameterCount = cpu_to_le16(params);
5870         pSMB->TotalDataCount = pSMB->DataCount;
5871         pSMB->TotalParameterCount = pSMB->ParameterCount;
5872         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5873                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5874         else
5875                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5876         pSMB->Reserved4 = 0;
5877         inc_rfc1001_len(pSMB, byte_count);
5878         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5879         pSMB->ByteCount = cpu_to_le16(byte_count);
5880         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5881                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5882         if (rc)
5883                 cFYI(1, "SetPathInfo (times) returned %d", rc);
5884
5885         cifs_buf_release(pSMB);
5886
5887         if (rc == -EAGAIN)
5888                 goto SetTimesRetry;
5889
5890         return rc;
5891 }
5892
5893 /* Can not be used to set time stamps yet (due to old DOS time format) */
5894 /* Can be used to set attributes */
5895 #if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
5896           handling it anyway and NT4 was what we thought it would be needed for
5897           Do not delete it until we prove whether needed for Win9x though */
5898 int
5899 CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5900                 __u16 dos_attrs, const struct nls_table *nls_codepage)
5901 {
5902         SETATTR_REQ *pSMB = NULL;
5903         SETATTR_RSP *pSMBr = NULL;
5904         int rc = 0;
5905         int bytes_returned;
5906         int name_len;
5907
5908         cFYI(1, "In SetAttrLegacy");
5909
5910 SetAttrLgcyRetry:
5911         rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5912                       (void **) &pSMBr);
5913         if (rc)
5914                 return rc;
5915
5916         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5917                 name_len =
5918                         ConvertToUCS((__le16 *) pSMB->fileName, fileName,
5919                                 PATH_MAX, nls_codepage);
5920                 name_len++;     /* trailing null */
5921                 name_len *= 2;
5922         } else {        /* BB improve the check for buffer overruns BB */
5923                 name_len = strnlen(fileName, PATH_MAX);
5924                 name_len++;     /* trailing null */
5925                 strncpy(pSMB->fileName, fileName, name_len);
5926         }
5927         pSMB->attr = cpu_to_le16(dos_attrs);
5928         pSMB->BufferFormat = 0x04;
5929         inc_rfc1001_len(pSMB, name_len + 1);
5930         pSMB->ByteCount = cpu_to_le16(name_len + 1);
5931         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5932                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5933         if (rc)
5934                 cFYI(1, "Error in LegacySetAttr = %d", rc);
5935
5936         cifs_buf_release(pSMB);
5937
5938         if (rc == -EAGAIN)
5939                 goto SetAttrLgcyRetry;
5940
5941         return rc;
5942 }
5943 #endif /* temporarily unneeded SetAttr legacy function */
5944
5945 static void
5946 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5947                         const struct cifs_unix_set_info_args *args)
5948 {
5949         u64 mode = args->mode;
5950
5951         /*
5952          * Samba server ignores set of file size to zero due to bugs in some
5953          * older clients, but we should be precise - we use SetFileSize to
5954          * set file size and do not want to truncate file size to zero
5955          * accidentally as happened on one Samba server beta by putting
5956          * zero instead of -1 here
5957          */
5958         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5959         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5960         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5961         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5962         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5963         data_offset->Uid = cpu_to_le64(args->uid);
5964         data_offset->Gid = cpu_to_le64(args->gid);
5965         /* better to leave device as zero when it is  */
5966         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5967         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5968         data_offset->Permissions = cpu_to_le64(mode);
5969
5970         if (S_ISREG(mode))
5971                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5972         else if (S_ISDIR(mode))
5973                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5974         else if (S_ISLNK(mode))
5975                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5976         else if (S_ISCHR(mode))
5977                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5978         else if (S_ISBLK(mode))
5979                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5980         else if (S_ISFIFO(mode))
5981                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5982         else if (S_ISSOCK(mode))
5983                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5984 }
5985
5986 int
5987 CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5988                        const struct cifs_unix_set_info_args *args,
5989                        u16 fid, u32 pid_of_opener)
5990 {
5991         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5992         char *data_offset;
5993         int rc = 0;
5994         u16 params, param_offset, offset, byte_count, count;
5995
5996         cFYI(1, "Set Unix Info (via SetFileInfo)");
5997         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5998
5999         if (rc)
6000                 return rc;
6001
6002         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6003         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6004
6005         params = 6;
6006         pSMB->MaxSetupCount = 0;
6007         pSMB->Reserved = 0;
6008         pSMB->Flags = 0;
6009         pSMB->Timeout = 0;
6010         pSMB->Reserved2 = 0;
6011         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
6012         offset = param_offset + params;
6013
6014         data_offset = (char *)pSMB +
6015                         offsetof(struct smb_hdr, Protocol) + offset;
6016
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((FILE_UNIX_BASIC_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 */