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