Merge remote-tracking branch 'lsk/v3.10/topic/gator' into linux-linaro-lsk
[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                 cifs_acl->default_entry_count = __constant_cpu_to_le16(0xFFFF);
3312         } else if (acl_type == ACL_TYPE_DEFAULT) {
3313                 cifs_acl->default_entry_count = cpu_to_le16(count);
3314                 cifs_acl->access_entry_count = __constant_cpu_to_le16(0xFFFF);
3315         } else {
3316                 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3317                 return 0;
3318         }
3319         for (i = 0; i < count; i++) {
3320                 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
3321                                         &local_acl->a_entries[i]);
3322                 if (rc != 0) {
3323                         /* ACE not converted */
3324                         break;
3325                 }
3326         }
3327         if (rc == 0) {
3328                 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3329                 rc += sizeof(struct cifs_posix_acl);
3330                 /* BB add check to make sure ACL does not overflow SMB */
3331         }
3332         return rc;
3333 }
3334
3335 int
3336 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3337                    const unsigned char *searchName,
3338                    char *acl_inf, const int buflen, const int acl_type,
3339                    const struct nls_table *nls_codepage, int remap)
3340 {
3341 /* SMB_QUERY_POSIX_ACL */
3342         TRANSACTION2_QPI_REQ *pSMB = NULL;
3343         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3344         int rc = 0;
3345         int bytes_returned;
3346         int name_len;
3347         __u16 params, byte_count;
3348
3349         cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3350
3351 queryAclRetry:
3352         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3353                 (void **) &pSMBr);
3354         if (rc)
3355                 return rc;
3356
3357         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3358                 name_len =
3359                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3360                                            searchName, PATH_MAX, nls_codepage,
3361                                            remap);
3362                 name_len++;     /* trailing null */
3363                 name_len *= 2;
3364                 pSMB->FileName[name_len] = 0;
3365                 pSMB->FileName[name_len+1] = 0;
3366         } else {        /* BB improve the check for buffer overruns BB */
3367                 name_len = strnlen(searchName, PATH_MAX);
3368                 name_len++;     /* trailing null */
3369                 strncpy(pSMB->FileName, searchName, name_len);
3370         }
3371
3372         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3373         pSMB->TotalDataCount = 0;
3374         pSMB->MaxParameterCount = cpu_to_le16(2);
3375         /* BB find exact max data count below from sess structure BB */
3376         pSMB->MaxDataCount = cpu_to_le16(4000);
3377         pSMB->MaxSetupCount = 0;
3378         pSMB->Reserved = 0;
3379         pSMB->Flags = 0;
3380         pSMB->Timeout = 0;
3381         pSMB->Reserved2 = 0;
3382         pSMB->ParameterOffset = cpu_to_le16(
3383                 offsetof(struct smb_com_transaction2_qpi_req,
3384                          InformationLevel) - 4);
3385         pSMB->DataCount = 0;
3386         pSMB->DataOffset = 0;
3387         pSMB->SetupCount = 1;
3388         pSMB->Reserved3 = 0;
3389         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3390         byte_count = params + 1 /* pad */ ;
3391         pSMB->TotalParameterCount = cpu_to_le16(params);
3392         pSMB->ParameterCount = pSMB->TotalParameterCount;
3393         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3394         pSMB->Reserved4 = 0;
3395         inc_rfc1001_len(pSMB, byte_count);
3396         pSMB->ByteCount = cpu_to_le16(byte_count);
3397
3398         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3399                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3400         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3401         if (rc) {
3402                 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3403         } else {
3404                 /* decode response */
3405
3406                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3407                 /* BB also check enough total bytes returned */
3408                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3409                         rc = -EIO;      /* bad smb */
3410                 else {
3411                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3412                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3413                         rc = cifs_copy_posix_acl(acl_inf,
3414                                 (char *)&pSMBr->hdr.Protocol+data_offset,
3415                                 buflen, acl_type, count);
3416                 }
3417         }
3418         cifs_buf_release(pSMB);
3419         if (rc == -EAGAIN)
3420                 goto queryAclRetry;
3421         return rc;
3422 }
3423
3424 int
3425 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3426                    const unsigned char *fileName,
3427                    const char *local_acl, const int buflen,
3428                    const int acl_type,
3429                    const struct nls_table *nls_codepage, int remap)
3430 {
3431         struct smb_com_transaction2_spi_req *pSMB = NULL;
3432         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3433         char *parm_data;
3434         int name_len;
3435         int rc = 0;
3436         int bytes_returned = 0;
3437         __u16 params, byte_count, data_count, param_offset, offset;
3438
3439         cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3440 setAclRetry:
3441         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3442                       (void **) &pSMBr);
3443         if (rc)
3444                 return rc;
3445         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3446                 name_len =
3447                         cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3448                                            PATH_MAX, nls_codepage, remap);
3449                 name_len++;     /* trailing null */
3450                 name_len *= 2;
3451         } else {        /* BB improve the check for buffer overruns BB */
3452                 name_len = strnlen(fileName, PATH_MAX);
3453                 name_len++;     /* trailing null */
3454                 strncpy(pSMB->FileName, fileName, name_len);
3455         }
3456         params = 6 + name_len;
3457         pSMB->MaxParameterCount = cpu_to_le16(2);
3458         /* BB find max SMB size from sess */
3459         pSMB->MaxDataCount = cpu_to_le16(1000);
3460         pSMB->MaxSetupCount = 0;
3461         pSMB->Reserved = 0;
3462         pSMB->Flags = 0;
3463         pSMB->Timeout = 0;
3464         pSMB->Reserved2 = 0;
3465         param_offset = offsetof(struct smb_com_transaction2_spi_req,
3466                                 InformationLevel) - 4;
3467         offset = param_offset + params;
3468         parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3469         pSMB->ParameterOffset = cpu_to_le16(param_offset);
3470
3471         /* convert to on the wire format for POSIX ACL */
3472         data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3473
3474         if (data_count == 0) {
3475                 rc = -EOPNOTSUPP;
3476                 goto setACLerrorExit;
3477         }
3478         pSMB->DataOffset = cpu_to_le16(offset);
3479         pSMB->SetupCount = 1;
3480         pSMB->Reserved3 = 0;
3481         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3482         pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3483         byte_count = 3 /* pad */  + params + data_count;
3484         pSMB->DataCount = cpu_to_le16(data_count);
3485         pSMB->TotalDataCount = pSMB->DataCount;
3486         pSMB->ParameterCount = cpu_to_le16(params);
3487         pSMB->TotalParameterCount = pSMB->ParameterCount;
3488         pSMB->Reserved4 = 0;
3489         inc_rfc1001_len(pSMB, byte_count);
3490         pSMB->ByteCount = cpu_to_le16(byte_count);
3491         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3492                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3493         if (rc)
3494                 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3495
3496 setACLerrorExit:
3497         cifs_buf_release(pSMB);
3498         if (rc == -EAGAIN)
3499                 goto setAclRetry;
3500         return rc;
3501 }
3502
3503 /* BB fix tabs in this function FIXME BB */
3504 int
3505 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3506                const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3507 {
3508         int rc = 0;
3509         struct smb_t2_qfi_req *pSMB = NULL;
3510         struct smb_t2_qfi_rsp *pSMBr = NULL;
3511         int bytes_returned;
3512         __u16 params, byte_count;
3513
3514         cifs_dbg(FYI, "In GetExtAttr\n");
3515         if (tcon == NULL)
3516                 return -ENODEV;
3517
3518 GetExtAttrRetry:
3519         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3520                         (void **) &pSMBr);
3521         if (rc)
3522                 return rc;
3523
3524         params = 2 /* level */ + 2 /* fid */;
3525         pSMB->t2.TotalDataCount = 0;
3526         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3527         /* BB find exact max data count below from sess structure BB */
3528         pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3529         pSMB->t2.MaxSetupCount = 0;
3530         pSMB->t2.Reserved = 0;
3531         pSMB->t2.Flags = 0;
3532         pSMB->t2.Timeout = 0;
3533         pSMB->t2.Reserved2 = 0;
3534         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3535                                                Fid) - 4);
3536         pSMB->t2.DataCount = 0;
3537         pSMB->t2.DataOffset = 0;
3538         pSMB->t2.SetupCount = 1;
3539         pSMB->t2.Reserved3 = 0;
3540         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3541         byte_count = params + 1 /* pad */ ;
3542         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3543         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3544         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3545         pSMB->Pad = 0;
3546         pSMB->Fid = netfid;
3547         inc_rfc1001_len(pSMB, byte_count);
3548         pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3549
3550         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3551                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3552         if (rc) {
3553                 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3554         } else {
3555                 /* decode response */
3556                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3557                 /* BB also check enough total bytes returned */
3558                 if (rc || get_bcc(&pSMBr->hdr) < 2)
3559                         /* If rc should we check for EOPNOSUPP and
3560                            disable the srvino flag? or in caller? */
3561                         rc = -EIO;      /* bad smb */
3562                 else {
3563                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3564                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3565                         struct file_chattr_info *pfinfo;
3566                         /* BB Do we need a cast or hash here ? */
3567                         if (count != 16) {
3568                                 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
3569                                 rc = -EIO;
3570                                 goto GetExtAttrOut;
3571                         }
3572                         pfinfo = (struct file_chattr_info *)
3573                                  (data_offset + (char *) &pSMBr->hdr.Protocol);
3574                         *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3575                         *pMask = le64_to_cpu(pfinfo->mask);
3576                 }
3577         }
3578 GetExtAttrOut:
3579         cifs_buf_release(pSMB);
3580         if (rc == -EAGAIN)
3581                 goto GetExtAttrRetry;
3582         return rc;
3583 }
3584
3585 #endif /* CONFIG_POSIX */
3586
3587 #ifdef CONFIG_CIFS_ACL
3588 /*
3589  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3590  * all NT TRANSACTS that we init here have total parm and data under about 400
3591  * bytes (to fit in small cifs buffer size), which is the case so far, it
3592  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3593  * returned setup area) and MaxParameterCount (returned parms size) must be set
3594  * by caller
3595  */
3596 static int
3597 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3598                    const int parm_len, struct cifs_tcon *tcon,
3599                    void **ret_buf)
3600 {
3601         int rc;
3602         __u32 temp_offset;
3603         struct smb_com_ntransact_req *pSMB;
3604
3605         rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3606                                 (void **)&pSMB);
3607         if (rc)
3608                 return rc;
3609         *ret_buf = (void *)pSMB;
3610         pSMB->Reserved = 0;
3611         pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3612         pSMB->TotalDataCount  = 0;
3613         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3614         pSMB->ParameterCount = pSMB->TotalParameterCount;
3615         pSMB->DataCount  = pSMB->TotalDataCount;
3616         temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3617                         (setup_count * 2) - 4 /* for rfc1001 length itself */;
3618         pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3619         pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3620         pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3621         pSMB->SubCommand = cpu_to_le16(sub_command);
3622         return 0;
3623 }
3624
3625 static int
3626 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3627                    __u32 *pparmlen, __u32 *pdatalen)
3628 {
3629         char *end_of_smb;
3630         __u32 data_count, data_offset, parm_count, parm_offset;
3631         struct smb_com_ntransact_rsp *pSMBr;
3632         u16 bcc;
3633
3634         *pdatalen = 0;
3635         *pparmlen = 0;
3636
3637         if (buf == NULL)
3638                 return -EINVAL;
3639
3640         pSMBr = (struct smb_com_ntransact_rsp *)buf;
3641
3642         bcc = get_bcc(&pSMBr->hdr);
3643         end_of_smb = 2 /* sizeof byte count */ + bcc +
3644                         (char *)&pSMBr->ByteCount;
3645
3646         data_offset = le32_to_cpu(pSMBr->DataOffset);
3647         data_count = le32_to_cpu(pSMBr->DataCount);
3648         parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3649         parm_count = le32_to_cpu(pSMBr->ParameterCount);
3650
3651         *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3652         *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3653
3654         /* should we also check that parm and data areas do not overlap? */
3655         if (*ppparm > end_of_smb) {
3656                 cifs_dbg(FYI, "parms start after end of smb\n");
3657                 return -EINVAL;
3658         } else if (parm_count + *ppparm > end_of_smb) {
3659                 cifs_dbg(FYI, "parm end after end of smb\n");
3660                 return -EINVAL;
3661         } else if (*ppdata > end_of_smb) {
3662                 cifs_dbg(FYI, "data starts after end of smb\n");
3663                 return -EINVAL;
3664         } else if (data_count + *ppdata > end_of_smb) {
3665                 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3666                          *ppdata, data_count, (data_count + *ppdata),
3667                          end_of_smb, pSMBr);
3668                 return -EINVAL;
3669         } else if (parm_count + data_count > bcc) {
3670                 cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3671                 return -EINVAL;
3672         }
3673         *pdatalen = data_count;
3674         *pparmlen = parm_count;
3675         return 0;
3676 }
3677
3678 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3679 int
3680 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3681                   struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3682 {
3683         int rc = 0;
3684         int buf_type = 0;
3685         QUERY_SEC_DESC_REQ *pSMB;
3686         struct kvec iov[1];
3687
3688         cifs_dbg(FYI, "GetCifsACL\n");
3689
3690         *pbuflen = 0;
3691         *acl_inf = NULL;
3692
3693         rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3694                         8 /* parm len */, tcon, (void **) &pSMB);
3695         if (rc)
3696                 return rc;
3697
3698         pSMB->MaxParameterCount = cpu_to_le32(4);
3699         /* BB TEST with big acls that might need to be e.g. larger than 16K */
3700         pSMB->MaxSetupCount = 0;
3701         pSMB->Fid = fid; /* file handle always le */
3702         pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3703                                      CIFS_ACL_DACL);
3704         pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3705         inc_rfc1001_len(pSMB, 11);
3706         iov[0].iov_base = (char *)pSMB;
3707         iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3708
3709         rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3710                          0);
3711         cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3712         if (rc) {
3713                 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3714         } else {                /* decode response */
3715                 __le32 *parm;
3716                 __u32 parm_len;
3717                 __u32 acl_len;
3718                 struct smb_com_ntransact_rsp *pSMBr;
3719                 char *pdata;
3720
3721 /* validate_nttransact */
3722                 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3723                                         &pdata, &parm_len, pbuflen);
3724                 if (rc)
3725                         goto qsec_out;
3726                 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3727
3728                 cifs_dbg(FYI, "smb %p parm %p data %p\n",
3729                          pSMBr, parm, *acl_inf);
3730
3731                 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3732                         rc = -EIO;      /* bad smb */
3733                         *pbuflen = 0;
3734                         goto qsec_out;
3735                 }
3736
3737 /* BB check that data area is minimum length and as big as acl_len */
3738
3739                 acl_len = le32_to_cpu(*parm);
3740                 if (acl_len != *pbuflen) {
3741                         cifs_dbg(VFS, "acl length %d does not match %d\n",
3742                                  acl_len, *pbuflen);
3743                         if (*pbuflen > acl_len)
3744                                 *pbuflen = acl_len;
3745                 }
3746
3747                 /* check if buffer is big enough for the acl
3748                    header followed by the smallest SID */
3749                 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3750                     (*pbuflen >= 64 * 1024)) {
3751                         cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3752                         rc = -EINVAL;
3753                         *pbuflen = 0;
3754                 } else {
3755                         *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3756                         if (*acl_inf == NULL) {
3757                                 *pbuflen = 0;
3758                                 rc = -ENOMEM;
3759                         }
3760                 }
3761         }
3762 qsec_out:
3763         if (buf_type == CIFS_SMALL_BUFFER)
3764                 cifs_small_buf_release(iov[0].iov_base);
3765         else if (buf_type == CIFS_LARGE_BUFFER)
3766                 cifs_buf_release(iov[0].iov_base);
3767 /*      cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3768         return rc;
3769 }
3770
3771 int
3772 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3773                         struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3774 {
3775         __u16 byte_count, param_count, data_count, param_offset, data_offset;
3776         int rc = 0;
3777         int bytes_returned = 0;
3778         SET_SEC_DESC_REQ *pSMB = NULL;
3779         void *pSMBr;
3780
3781 setCifsAclRetry:
3782         rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3783         if (rc)
3784                 return rc;
3785
3786         pSMB->MaxSetupCount = 0;
3787         pSMB->Reserved = 0;
3788
3789         param_count = 8;
3790         param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3791         data_count = acllen;
3792         data_offset = param_offset + param_count;
3793         byte_count = 3 /* pad */  + param_count;
3794
3795         pSMB->DataCount = cpu_to_le32(data_count);
3796         pSMB->TotalDataCount = pSMB->DataCount;
3797         pSMB->MaxParameterCount = cpu_to_le32(4);
3798         pSMB->MaxDataCount = cpu_to_le32(16384);
3799         pSMB->ParameterCount = cpu_to_le32(param_count);
3800         pSMB->ParameterOffset = cpu_to_le32(param_offset);
3801         pSMB->TotalParameterCount = pSMB->ParameterCount;
3802         pSMB->DataOffset = cpu_to_le32(data_offset);
3803         pSMB->SetupCount = 0;
3804         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3805         pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3806
3807         pSMB->Fid = fid; /* file handle always le */
3808         pSMB->Reserved2 = 0;
3809         pSMB->AclFlags = cpu_to_le32(aclflag);
3810
3811         if (pntsd && acllen) {
3812                 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3813                                 data_offset, pntsd, acllen);
3814                 inc_rfc1001_len(pSMB, byte_count + data_count);
3815         } else
3816                 inc_rfc1001_len(pSMB, byte_count);
3817
3818         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3819                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3820
3821         cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3822                  bytes_returned, rc);
3823         if (rc)
3824                 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3825         cifs_buf_release(pSMB);
3826
3827         if (rc == -EAGAIN)
3828                 goto setCifsAclRetry;
3829
3830         return (rc);
3831 }
3832
3833 #endif /* CONFIG_CIFS_ACL */
3834
3835 /* Legacy Query Path Information call for lookup to old servers such
3836    as Win9x/WinME */
3837 int
3838 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3839                     const char *search_name, FILE_ALL_INFO *data,
3840                     const struct nls_table *nls_codepage, int remap)
3841 {
3842         QUERY_INFORMATION_REQ *pSMB;
3843         QUERY_INFORMATION_RSP *pSMBr;
3844         int rc = 0;
3845         int bytes_returned;
3846         int name_len;
3847
3848         cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3849 QInfRetry:
3850         rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3851                       (void **) &pSMBr);
3852         if (rc)
3853                 return rc;
3854
3855         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3856                 name_len =
3857                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
3858                                            search_name, PATH_MAX, nls_codepage,
3859                                            remap);
3860                 name_len++;     /* trailing null */
3861                 name_len *= 2;
3862         } else {
3863                 name_len = strnlen(search_name, PATH_MAX);
3864                 name_len++;     /* trailing null */
3865                 strncpy(pSMB->FileName, search_name, name_len);
3866         }
3867         pSMB->BufferFormat = 0x04;
3868         name_len++; /* account for buffer type byte */
3869         inc_rfc1001_len(pSMB, (__u16)name_len);
3870         pSMB->ByteCount = cpu_to_le16(name_len);
3871
3872         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3873                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3874         if (rc) {
3875                 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3876         } else if (data) {
3877                 struct timespec ts;
3878                 __u32 time = le32_to_cpu(pSMBr->last_write_time);
3879
3880                 /* decode response */
3881                 /* BB FIXME - add time zone adjustment BB */
3882                 memset(data, 0, sizeof(FILE_ALL_INFO));
3883                 ts.tv_nsec = 0;
3884                 ts.tv_sec = time;
3885                 /* decode time fields */
3886                 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3887                 data->LastWriteTime = data->ChangeTime;
3888                 data->LastAccessTime = 0;
3889                 data->AllocationSize =
3890                         cpu_to_le64(le32_to_cpu(pSMBr->size));
3891                 data->EndOfFile = data->AllocationSize;
3892                 data->Attributes =
3893                         cpu_to_le32(le16_to_cpu(pSMBr->attr));
3894         } else
3895                 rc = -EIO; /* bad buffer passed in */
3896
3897         cifs_buf_release(pSMB);
3898
3899         if (rc == -EAGAIN)
3900                 goto QInfRetry;
3901
3902         return rc;
3903 }
3904
3905 int
3906 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3907                  u16 netfid, FILE_ALL_INFO *pFindData)
3908 {
3909         struct smb_t2_qfi_req *pSMB = NULL;
3910         struct smb_t2_qfi_rsp *pSMBr = NULL;
3911         int rc = 0;
3912         int bytes_returned;
3913         __u16 params, byte_count;
3914
3915 QFileInfoRetry:
3916         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3917                       (void **) &pSMBr);
3918         if (rc)
3919                 return rc;
3920
3921         params = 2 /* level */ + 2 /* fid */;
3922         pSMB->t2.TotalDataCount = 0;
3923         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3924         /* BB find exact max data count below from sess structure BB */
3925         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3926         pSMB->t2.MaxSetupCount = 0;
3927         pSMB->t2.Reserved = 0;
3928         pSMB->t2.Flags = 0;
3929         pSMB->t2.Timeout = 0;
3930         pSMB->t2.Reserved2 = 0;
3931         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3932                                                Fid) - 4);
3933         pSMB->t2.DataCount = 0;
3934         pSMB->t2.DataOffset = 0;
3935         pSMB->t2.SetupCount = 1;
3936         pSMB->t2.Reserved3 = 0;
3937         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3938         byte_count = params + 1 /* pad */ ;
3939         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3940         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3941         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3942         pSMB->Pad = 0;
3943         pSMB->Fid = netfid;
3944         inc_rfc1001_len(pSMB, byte_count);
3945
3946         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3947                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3948         if (rc) {
3949                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3950         } else {                /* decode response */
3951                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3952
3953                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3954                         rc = -EIO;
3955                 else if (get_bcc(&pSMBr->hdr) < 40)
3956                         rc = -EIO;      /* bad smb */
3957                 else if (pFindData) {
3958                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3959                         memcpy((char *) pFindData,
3960                                (char *) &pSMBr->hdr.Protocol +
3961                                data_offset, sizeof(FILE_ALL_INFO));
3962                 } else
3963                     rc = -ENOMEM;
3964         }
3965         cifs_buf_release(pSMB);
3966         if (rc == -EAGAIN)
3967                 goto QFileInfoRetry;
3968
3969         return rc;
3970 }
3971
3972 int
3973 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3974                  const char *search_name, FILE_ALL_INFO *data,
3975                  int legacy /* old style infolevel */,
3976                  const struct nls_table *nls_codepage, int remap)
3977 {
3978         /* level 263 SMB_QUERY_FILE_ALL_INFO */
3979         TRANSACTION2_QPI_REQ *pSMB = NULL;
3980         TRANSACTION2_QPI_RSP *pSMBr = NULL;
3981         int rc = 0;
3982         int bytes_returned;
3983         int name_len;
3984         __u16 params, byte_count;
3985
3986         /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3987 QPathInfoRetry:
3988         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3989                       (void **) &pSMBr);
3990         if (rc)
3991                 return rc;
3992
3993         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3994                 name_len =
3995                     cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3996                                        PATH_MAX, nls_codepage, remap);
3997                 name_len++;     /* trailing null */
3998                 name_len *= 2;
3999         } else {        /* BB improve the check for buffer overruns BB */
4000                 name_len = strnlen(search_name, PATH_MAX);
4001                 name_len++;     /* trailing null */
4002                 strncpy(pSMB->FileName, search_name, name_len);
4003         }
4004
4005         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4006         pSMB->TotalDataCount = 0;
4007         pSMB->MaxParameterCount = cpu_to_le16(2);
4008         /* BB find exact max SMB PDU from sess structure BB */
4009         pSMB->MaxDataCount = cpu_to_le16(4000);
4010         pSMB->MaxSetupCount = 0;
4011         pSMB->Reserved = 0;
4012         pSMB->Flags = 0;
4013         pSMB->Timeout = 0;
4014         pSMB->Reserved2 = 0;
4015         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4016         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4017         pSMB->DataCount = 0;
4018         pSMB->DataOffset = 0;
4019         pSMB->SetupCount = 1;
4020         pSMB->Reserved3 = 0;
4021         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4022         byte_count = params + 1 /* pad */ ;
4023         pSMB->TotalParameterCount = cpu_to_le16(params);
4024         pSMB->ParameterCount = pSMB->TotalParameterCount;
4025         if (legacy)
4026                 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4027         else
4028                 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4029         pSMB->Reserved4 = 0;
4030         inc_rfc1001_len(pSMB, byte_count);
4031         pSMB->ByteCount = cpu_to_le16(byte_count);
4032
4033         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4034                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4035         if (rc) {
4036                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4037         } else {                /* decode response */
4038                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4039
4040                 if (rc) /* BB add auto retry on EOPNOTSUPP? */
4041                         rc = -EIO;
4042                 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4043                         rc = -EIO;      /* bad smb */
4044                 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4045                         rc = -EIO;  /* 24 or 26 expected but we do not read
4046                                         last field */
4047                 else if (data) {
4048                         int size;
4049                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4050
4051                         /*
4052                          * On legacy responses we do not read the last field,
4053                          * EAsize, fortunately since it varies by subdialect and
4054                          * also note it differs on Set vs Get, ie two bytes or 4
4055                          * bytes depending but we don't care here.
4056                          */
4057                         if (legacy)
4058                                 size = sizeof(FILE_INFO_STANDARD);
4059                         else
4060                                 size = sizeof(FILE_ALL_INFO);
4061                         memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4062                                data_offset, size);
4063                 } else
4064                     rc = -ENOMEM;
4065         }
4066         cifs_buf_release(pSMB);
4067         if (rc == -EAGAIN)
4068                 goto QPathInfoRetry;
4069
4070         return rc;
4071 }
4072
4073 int
4074 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4075                  u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4076 {
4077         struct smb_t2_qfi_req *pSMB = NULL;
4078         struct smb_t2_qfi_rsp *pSMBr = NULL;
4079         int rc = 0;
4080         int bytes_returned;
4081         __u16 params, byte_count;
4082
4083 UnixQFileInfoRetry:
4084         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4085                       (void **) &pSMBr);
4086         if (rc)
4087                 return rc;
4088
4089         params = 2 /* level */ + 2 /* fid */;
4090         pSMB->t2.TotalDataCount = 0;
4091         pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4092         /* BB find exact max data count below from sess structure BB */
4093         pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4094         pSMB->t2.MaxSetupCount = 0;
4095         pSMB->t2.Reserved = 0;
4096         pSMB->t2.Flags = 0;
4097         pSMB->t2.Timeout = 0;
4098         pSMB->t2.Reserved2 = 0;
4099         pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4100                                                Fid) - 4);
4101         pSMB->t2.DataCount = 0;
4102         pSMB->t2.DataOffset = 0;
4103         pSMB->t2.SetupCount = 1;
4104         pSMB->t2.Reserved3 = 0;
4105         pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4106         byte_count = params + 1 /* pad */ ;
4107         pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4108         pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4109         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4110         pSMB->Pad = 0;
4111         pSMB->Fid = netfid;
4112         inc_rfc1001_len(pSMB, byte_count);
4113
4114         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4115                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4116         if (rc) {
4117                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4118         } else {                /* decode response */
4119                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4120
4121                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4122                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4123                         rc = -EIO;      /* bad smb */
4124                 } else {
4125                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4126                         memcpy((char *) pFindData,
4127                                (char *) &pSMBr->hdr.Protocol +
4128                                data_offset,
4129                                sizeof(FILE_UNIX_BASIC_INFO));
4130                 }
4131         }
4132
4133         cifs_buf_release(pSMB);
4134         if (rc == -EAGAIN)
4135                 goto UnixQFileInfoRetry;
4136
4137         return rc;
4138 }
4139
4140 int
4141 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4142                      const unsigned char *searchName,
4143                      FILE_UNIX_BASIC_INFO *pFindData,
4144                      const struct nls_table *nls_codepage, int remap)
4145 {
4146 /* SMB_QUERY_FILE_UNIX_BASIC */
4147         TRANSACTION2_QPI_REQ *pSMB = NULL;
4148         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4149         int rc = 0;
4150         int bytes_returned = 0;
4151         int name_len;
4152         __u16 params, byte_count;
4153
4154         cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4155 UnixQPathInfoRetry:
4156         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4157                       (void **) &pSMBr);
4158         if (rc)
4159                 return rc;
4160
4161         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4162                 name_len =
4163                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4164                                        PATH_MAX, nls_codepage, remap);
4165                 name_len++;     /* trailing null */
4166                 name_len *= 2;
4167         } else {        /* BB improve the check for buffer overruns BB */
4168                 name_len = strnlen(searchName, PATH_MAX);
4169                 name_len++;     /* trailing null */
4170                 strncpy(pSMB->FileName, searchName, name_len);
4171         }
4172
4173         params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4174         pSMB->TotalDataCount = 0;
4175         pSMB->MaxParameterCount = cpu_to_le16(2);
4176         /* BB find exact max SMB PDU from sess structure BB */
4177         pSMB->MaxDataCount = cpu_to_le16(4000);
4178         pSMB->MaxSetupCount = 0;
4179         pSMB->Reserved = 0;
4180         pSMB->Flags = 0;
4181         pSMB->Timeout = 0;
4182         pSMB->Reserved2 = 0;
4183         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4184         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4185         pSMB->DataCount = 0;
4186         pSMB->DataOffset = 0;
4187         pSMB->SetupCount = 1;
4188         pSMB->Reserved3 = 0;
4189         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4190         byte_count = params + 1 /* pad */ ;
4191         pSMB->TotalParameterCount = cpu_to_le16(params);
4192         pSMB->ParameterCount = pSMB->TotalParameterCount;
4193         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4194         pSMB->Reserved4 = 0;
4195         inc_rfc1001_len(pSMB, byte_count);
4196         pSMB->ByteCount = cpu_to_le16(byte_count);
4197
4198         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4199                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4200         if (rc) {
4201                 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4202         } else {                /* decode response */
4203                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4204
4205                 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4206                         cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4207                         rc = -EIO;      /* bad smb */
4208                 } else {
4209                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4210                         memcpy((char *) pFindData,
4211                                (char *) &pSMBr->hdr.Protocol +
4212                                data_offset,
4213                                sizeof(FILE_UNIX_BASIC_INFO));
4214                 }
4215         }
4216         cifs_buf_release(pSMB);
4217         if (rc == -EAGAIN)
4218                 goto UnixQPathInfoRetry;
4219
4220         return rc;
4221 }
4222
4223 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4224 int
4225 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4226               const char *searchName, struct cifs_sb_info *cifs_sb,
4227               __u16 *pnetfid, __u16 search_flags,
4228               struct cifs_search_info *psrch_inf, bool msearch)
4229 {
4230 /* level 257 SMB_ */
4231         TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4232         TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4233         T2_FFIRST_RSP_PARMS *parms;
4234         int rc = 0;
4235         int bytes_returned = 0;
4236         int name_len, remap;
4237         __u16 params, byte_count;
4238         struct nls_table *nls_codepage;
4239
4240         cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4241
4242 findFirstRetry:
4243         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4244                       (void **) &pSMBr);
4245         if (rc)
4246                 return rc;
4247
4248         nls_codepage = cifs_sb->local_nls;
4249         remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
4250
4251         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4252                 name_len =
4253                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4254                                        PATH_MAX, nls_codepage, remap);
4255                 /* We can not add the asterik earlier in case
4256                 it got remapped to 0xF03A as if it were part of the
4257                 directory name instead of a wildcard */
4258                 name_len *= 2;
4259                 if (msearch) {
4260                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4261                         pSMB->FileName[name_len+1] = 0;
4262                         pSMB->FileName[name_len+2] = '*';
4263                         pSMB->FileName[name_len+3] = 0;
4264                         name_len += 4; /* now the trailing null */
4265                         /* null terminate just in case */
4266                         pSMB->FileName[name_len] = 0;
4267                         pSMB->FileName[name_len+1] = 0;
4268                         name_len += 2;
4269                 }
4270         } else {        /* BB add check for overrun of SMB buf BB */
4271                 name_len = strnlen(searchName, PATH_MAX);
4272 /* BB fix here and in unicode clause above ie
4273                 if (name_len > buffersize-header)
4274                         free buffer exit; BB */
4275                 strncpy(pSMB->FileName, searchName, name_len);
4276                 if (msearch) {
4277                         pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4278                         pSMB->FileName[name_len+1] = '*';
4279                         pSMB->FileName[name_len+2] = 0;
4280                         name_len += 3;
4281                 }
4282         }
4283
4284         params = 12 + name_len /* includes null */ ;
4285         pSMB->TotalDataCount = 0;       /* no EAs */
4286         pSMB->MaxParameterCount = cpu_to_le16(10);
4287         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4288         pSMB->MaxSetupCount = 0;
4289         pSMB->Reserved = 0;
4290         pSMB->Flags = 0;
4291         pSMB->Timeout = 0;
4292         pSMB->Reserved2 = 0;
4293         byte_count = params + 1 /* pad */ ;
4294         pSMB->TotalParameterCount = cpu_to_le16(params);
4295         pSMB->ParameterCount = pSMB->TotalParameterCount;
4296         pSMB->ParameterOffset = cpu_to_le16(
4297               offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4298                 - 4);
4299         pSMB->DataCount = 0;
4300         pSMB->DataOffset = 0;
4301         pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4302         pSMB->Reserved3 = 0;
4303         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4304         pSMB->SearchAttributes =
4305             cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4306                         ATTR_DIRECTORY);
4307         pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4308         pSMB->SearchFlags = cpu_to_le16(search_flags);
4309         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4310
4311         /* BB what should we set StorageType to? Does it matter? BB */
4312         pSMB->SearchStorageType = 0;
4313         inc_rfc1001_len(pSMB, byte_count);
4314         pSMB->ByteCount = cpu_to_le16(byte_count);
4315
4316         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4317                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4318         cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4319
4320         if (rc) {/* BB add logic to retry regular search if Unix search
4321                         rejected unexpectedly by server */
4322                 /* BB Add code to handle unsupported level rc */
4323                 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4324
4325                 cifs_buf_release(pSMB);
4326
4327                 /* BB eventually could optimize out free and realloc of buf */
4328                 /*    for this case */
4329                 if (rc == -EAGAIN)
4330                         goto findFirstRetry;
4331         } else { /* decode response */
4332                 /* BB remember to free buffer if error BB */
4333                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4334                 if (rc == 0) {
4335                         unsigned int lnoff;
4336
4337                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4338                                 psrch_inf->unicode = true;
4339                         else
4340                                 psrch_inf->unicode = false;
4341
4342                         psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4343                         psrch_inf->smallBuf = 0;
4344                         psrch_inf->srch_entries_start =
4345                                 (char *) &pSMBr->hdr.Protocol +
4346                                         le16_to_cpu(pSMBr->t2.DataOffset);
4347                         parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4348                                le16_to_cpu(pSMBr->t2.ParameterOffset));
4349
4350                         if (parms->EndofSearch)
4351                                 psrch_inf->endOfSearch = true;
4352                         else
4353                                 psrch_inf->endOfSearch = false;
4354
4355                         psrch_inf->entries_in_buffer =
4356                                         le16_to_cpu(parms->SearchCount);
4357                         psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4358                                 psrch_inf->entries_in_buffer;
4359                         lnoff = le16_to_cpu(parms->LastNameOffset);
4360                         if (CIFSMaxBufSize < lnoff) {
4361                                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4362                                 psrch_inf->last_entry = NULL;
4363                                 return rc;
4364                         }
4365
4366                         psrch_inf->last_entry = psrch_inf->srch_entries_start +
4367                                                         lnoff;
4368
4369                         if (pnetfid)
4370                                 *pnetfid = parms->SearchHandle;
4371                 } else {
4372                         cifs_buf_release(pSMB);
4373                 }
4374         }
4375
4376         return rc;
4377 }
4378
4379 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4380                  __u16 searchHandle, __u16 search_flags,
4381                  struct cifs_search_info *psrch_inf)
4382 {
4383         TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4384         TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4385         T2_FNEXT_RSP_PARMS *parms;
4386         char *response_data;
4387         int rc = 0;
4388         int bytes_returned;
4389         unsigned int name_len;
4390         __u16 params, byte_count;
4391
4392         cifs_dbg(FYI, "In FindNext\n");
4393
4394         if (psrch_inf->endOfSearch)
4395                 return -ENOENT;
4396
4397         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4398                 (void **) &pSMBr);
4399         if (rc)
4400                 return rc;
4401
4402         params = 14; /* includes 2 bytes of null string, converted to LE below*/
4403         byte_count = 0;
4404         pSMB->TotalDataCount = 0;       /* no EAs */
4405         pSMB->MaxParameterCount = cpu_to_le16(8);
4406         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4407         pSMB->MaxSetupCount = 0;
4408         pSMB->Reserved = 0;
4409         pSMB->Flags = 0;
4410         pSMB->Timeout = 0;
4411         pSMB->Reserved2 = 0;
4412         pSMB->ParameterOffset =  cpu_to_le16(
4413               offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4414         pSMB->DataCount = 0;
4415         pSMB->DataOffset = 0;
4416         pSMB->SetupCount = 1;
4417         pSMB->Reserved3 = 0;
4418         pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4419         pSMB->SearchHandle = searchHandle;      /* always kept as le */
4420         pSMB->SearchCount =
4421                 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4422         pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4423         pSMB->ResumeKey = psrch_inf->resume_key;
4424         pSMB->SearchFlags = cpu_to_le16(search_flags);
4425
4426         name_len = psrch_inf->resume_name_len;
4427         params += name_len;
4428         if (name_len < PATH_MAX) {
4429                 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4430                 byte_count += name_len;
4431                 /* 14 byte parm len above enough for 2 byte null terminator */
4432                 pSMB->ResumeFileName[name_len] = 0;
4433                 pSMB->ResumeFileName[name_len+1] = 0;
4434         } else {
4435                 rc = -EINVAL;
4436                 goto FNext2_err_exit;
4437         }
4438         byte_count = params + 1 /* pad */ ;
4439         pSMB->TotalParameterCount = cpu_to_le16(params);
4440         pSMB->ParameterCount = pSMB->TotalParameterCount;
4441         inc_rfc1001_len(pSMB, byte_count);
4442         pSMB->ByteCount = cpu_to_le16(byte_count);
4443
4444         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4445                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4446         cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4447         if (rc) {
4448                 if (rc == -EBADF) {
4449                         psrch_inf->endOfSearch = true;
4450                         cifs_buf_release(pSMB);
4451                         rc = 0; /* search probably was closed at end of search*/
4452                 } else
4453                         cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4454         } else {                /* decode response */
4455                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4456
4457                 if (rc == 0) {
4458                         unsigned int lnoff;
4459
4460                         /* BB fixme add lock for file (srch_info) struct here */
4461                         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4462                                 psrch_inf->unicode = true;
4463                         else
4464                                 psrch_inf->unicode = false;
4465                         response_data = (char *) &pSMBr->hdr.Protocol +
4466                                le16_to_cpu(pSMBr->t2.ParameterOffset);
4467                         parms = (T2_FNEXT_RSP_PARMS *)response_data;
4468                         response_data = (char *)&pSMBr->hdr.Protocol +
4469                                 le16_to_cpu(pSMBr->t2.DataOffset);
4470                         if (psrch_inf->smallBuf)
4471                                 cifs_small_buf_release(
4472                                         psrch_inf->ntwrk_buf_start);
4473                         else
4474                                 cifs_buf_release(psrch_inf->ntwrk_buf_start);
4475                         psrch_inf->srch_entries_start = response_data;
4476                         psrch_inf->ntwrk_buf_start = (char *)pSMB;
4477                         psrch_inf->smallBuf = 0;
4478                         if (parms->EndofSearch)
4479                                 psrch_inf->endOfSearch = true;
4480                         else
4481                                 psrch_inf->endOfSearch = false;
4482                         psrch_inf->entries_in_buffer =
4483                                                 le16_to_cpu(parms->SearchCount);
4484                         psrch_inf->index_of_last_entry +=
4485                                 psrch_inf->entries_in_buffer;
4486                         lnoff = le16_to_cpu(parms->LastNameOffset);
4487                         if (CIFSMaxBufSize < lnoff) {
4488                                 cifs_dbg(VFS, "ignoring corrupt resume name\n");
4489                                 psrch_inf->last_entry = NULL;
4490                                 return rc;
4491                         } else
4492                                 psrch_inf->last_entry =
4493                                         psrch_inf->srch_entries_start + lnoff;
4494
4495 /*  cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4496     psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4497
4498                         /* BB fixme add unlock here */
4499                 }
4500
4501         }
4502
4503         /* BB On error, should we leave previous search buf (and count and
4504         last entry fields) intact or free the previous one? */
4505
4506         /* Note: On -EAGAIN error only caller can retry on handle based calls
4507         since file handle passed in no longer valid */
4508 FNext2_err_exit:
4509         if (rc != 0)
4510                 cifs_buf_release(pSMB);
4511         return rc;
4512 }
4513
4514 int
4515 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4516               const __u16 searchHandle)
4517 {
4518         int rc = 0;
4519         FINDCLOSE_REQ *pSMB = NULL;
4520
4521         cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4522         rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4523
4524         /* no sense returning error if session restarted
4525                 as file handle has been closed */
4526         if (rc == -EAGAIN)
4527                 return 0;
4528         if (rc)
4529                 return rc;
4530
4531         pSMB->FileID = searchHandle;
4532         pSMB->ByteCount = 0;
4533         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4534         if (rc)
4535                 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4536
4537         cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4538
4539         /* Since session is dead, search handle closed on server already */
4540         if (rc == -EAGAIN)
4541                 rc = 0;
4542
4543         return rc;
4544 }
4545
4546 int
4547 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4548                       const char *search_name, __u64 *inode_number,
4549                       const struct nls_table *nls_codepage, int remap)
4550 {
4551         int rc = 0;
4552         TRANSACTION2_QPI_REQ *pSMB = NULL;
4553         TRANSACTION2_QPI_RSP *pSMBr = NULL;
4554         int name_len, bytes_returned;
4555         __u16 params, byte_count;
4556
4557         cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4558         if (tcon == NULL)
4559                 return -ENODEV;
4560
4561 GetInodeNumberRetry:
4562         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4563                       (void **) &pSMBr);
4564         if (rc)
4565                 return rc;
4566
4567         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4568                 name_len =
4569                         cifsConvertToUTF16((__le16 *) pSMB->FileName,
4570                                            search_name, PATH_MAX, nls_codepage,
4571                                            remap);
4572                 name_len++;     /* trailing null */
4573                 name_len *= 2;
4574         } else {        /* BB improve the check for buffer overruns BB */
4575                 name_len = strnlen(search_name, PATH_MAX);
4576                 name_len++;     /* trailing null */
4577                 strncpy(pSMB->FileName, search_name, name_len);
4578         }
4579
4580         params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4581         pSMB->TotalDataCount = 0;
4582         pSMB->MaxParameterCount = cpu_to_le16(2);
4583         /* BB find exact max data count below from sess structure BB */
4584         pSMB->MaxDataCount = cpu_to_le16(4000);
4585         pSMB->MaxSetupCount = 0;
4586         pSMB->Reserved = 0;
4587         pSMB->Flags = 0;
4588         pSMB->Timeout = 0;
4589         pSMB->Reserved2 = 0;
4590         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4591                 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4592         pSMB->DataCount = 0;
4593         pSMB->DataOffset = 0;
4594         pSMB->SetupCount = 1;
4595         pSMB->Reserved3 = 0;
4596         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4597         byte_count = params + 1 /* pad */ ;
4598         pSMB->TotalParameterCount = cpu_to_le16(params);
4599         pSMB->ParameterCount = pSMB->TotalParameterCount;
4600         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4601         pSMB->Reserved4 = 0;
4602         inc_rfc1001_len(pSMB, byte_count);
4603         pSMB->ByteCount = cpu_to_le16(byte_count);
4604
4605         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4606                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4607         if (rc) {
4608                 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4609         } else {
4610                 /* decode response */
4611                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4612                 /* BB also check enough total bytes returned */
4613                 if (rc || get_bcc(&pSMBr->hdr) < 2)
4614                         /* If rc should we check for EOPNOSUPP and
4615                         disable the srvino flag? or in caller? */
4616                         rc = -EIO;      /* bad smb */
4617                 else {
4618                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4619                         __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4620                         struct file_internal_info *pfinfo;
4621                         /* BB Do we need a cast or hash here ? */
4622                         if (count < 8) {
4623                                 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
4624                                 rc = -EIO;
4625                                 goto GetInodeNumOut;
4626                         }
4627                         pfinfo = (struct file_internal_info *)
4628                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
4629                         *inode_number = le64_to_cpu(pfinfo->UniqueId);
4630                 }
4631         }
4632 GetInodeNumOut:
4633         cifs_buf_release(pSMB);
4634         if (rc == -EAGAIN)
4635                 goto GetInodeNumberRetry;
4636         return rc;
4637 }
4638
4639 /* parses DFS refferal V3 structure
4640  * caller is responsible for freeing target_nodes
4641  * returns:
4642  *      on success - 0
4643  *      on failure - errno
4644  */
4645 static int
4646 parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4647                 unsigned int *num_of_nodes,
4648                 struct dfs_info3_param **target_nodes,
4649                 const struct nls_table *nls_codepage, int remap,
4650                 const char *searchName)
4651 {
4652         int i, rc = 0;
4653         char *data_end;
4654         bool is_unicode;
4655         struct dfs_referral_level_3 *ref;
4656
4657         if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4658                 is_unicode = true;
4659         else
4660                 is_unicode = false;
4661         *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
4662
4663         if (*num_of_nodes < 1) {
4664                 cifs_dbg(VFS, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
4665                          *num_of_nodes);
4666                 rc = -EINVAL;
4667                 goto parse_DFS_referrals_exit;
4668         }
4669
4670         ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
4671         if (ref->VersionNumber != cpu_to_le16(3)) {
4672                 cifs_dbg(VFS, "Referrals of V%d version are not supported, should be V3\n",
4673                          le16_to_cpu(ref->VersionNumber));
4674                 rc = -EINVAL;
4675                 goto parse_DFS_referrals_exit;
4676         }
4677
4678         /* get the upper boundary of the resp buffer */
4679         data_end = (char *)(&(pSMBr->PathConsumed)) +
4680                                 le16_to_cpu(pSMBr->t2.DataCount);
4681
4682         cifs_dbg(FYI, "num_referrals: %d dfs flags: 0x%x ...\n",
4683                  *num_of_nodes, le32_to_cpu(pSMBr->DFSFlags));
4684
4685         *target_nodes = kcalloc(*num_of_nodes, sizeof(struct dfs_info3_param),
4686                                 GFP_KERNEL);
4687         if (*target_nodes == NULL) {
4688                 rc = -ENOMEM;
4689                 goto parse_DFS_referrals_exit;
4690         }
4691
4692         /* collect necessary data from referrals */
4693         for (i = 0; i < *num_of_nodes; i++) {
4694                 char *temp;
4695                 int max_len;
4696                 struct dfs_info3_param *node = (*target_nodes)+i;
4697
4698                 node->flags = le32_to_cpu(pSMBr->DFSFlags);
4699                 if (is_unicode) {
4700                         __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
4701                                                 GFP_KERNEL);
4702                         if (tmp == NULL) {
4703                                 rc = -ENOMEM;
4704                                 goto parse_DFS_referrals_exit;
4705                         }
4706                         cifsConvertToUTF16((__le16 *) tmp, searchName,
4707                                            PATH_MAX, nls_codepage, remap);
4708                         node->path_consumed = cifs_utf16_bytes(tmp,
4709                                         le16_to_cpu(pSMBr->PathConsumed),
4710                                         nls_codepage);
4711                         kfree(tmp);
4712                 } else
4713                         node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
4714
4715                 node->server_type = le16_to_cpu(ref->ServerType);
4716                 node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
4717
4718                 /* copy DfsPath */
4719                 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4720                 max_len = data_end - temp;
4721                 node->path_name = cifs_strndup_from_utf16(temp, max_len,
4722                                                 is_unicode, nls_codepage);
4723                 if (!node->path_name) {
4724                         rc = -ENOMEM;
4725                         goto parse_DFS_referrals_exit;
4726                 }
4727
4728                 /* copy link target UNC */
4729                 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4730                 max_len = data_end - temp;
4731                 node->node_name = cifs_strndup_from_utf16(temp, max_len,
4732                                                 is_unicode, nls_codepage);
4733                 if (!node->node_name) {
4734                         rc = -ENOMEM;
4735                         goto parse_DFS_referrals_exit;
4736                 }
4737
4738                 ref++;
4739         }
4740
4741 parse_DFS_referrals_exit:
4742         if (rc) {
4743                 free_dfs_info_array(*target_nodes, *num_of_nodes);
4744                 *target_nodes = NULL;
4745                 *num_of_nodes = 0;
4746         }
4747         return rc;
4748 }
4749
4750 int
4751 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4752                 const char *search_name, struct dfs_info3_param **target_nodes,
4753                 unsigned int *num_of_nodes,
4754                 const struct nls_table *nls_codepage, int remap)
4755 {
4756 /* TRANS2_GET_DFS_REFERRAL */
4757         TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4758         TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4759         int rc = 0;
4760         int bytes_returned;
4761         int name_len;
4762         __u16 params, byte_count;
4763         *num_of_nodes = 0;
4764         *target_nodes = NULL;
4765
4766         cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4767         if (ses == NULL)
4768                 return -ENODEV;
4769 getDFSRetry:
4770         rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
4771                       (void **) &pSMBr);
4772         if (rc)
4773                 return rc;
4774
4775         /* server pointer checked in called function,
4776         but should never be null here anyway */
4777         pSMB->hdr.Mid = get_next_mid(ses->server);
4778         pSMB->hdr.Tid = ses->ipc_tid;
4779         pSMB->hdr.Uid = ses->Suid;
4780         if (ses->capabilities & CAP_STATUS32)
4781                 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4782         if (ses->capabilities & CAP_DFS)
4783                 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4784
4785         if (ses->capabilities & CAP_UNICODE) {
4786                 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4787                 name_len =
4788                     cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4789                                        search_name, PATH_MAX, nls_codepage,
4790                                        remap);
4791                 name_len++;     /* trailing null */
4792                 name_len *= 2;
4793         } else {        /* BB improve the check for buffer overruns BB */
4794                 name_len = strnlen(search_name, PATH_MAX);
4795                 name_len++;     /* trailing null */
4796                 strncpy(pSMB->RequestFileName, search_name, name_len);
4797         }
4798
4799         if (ses->server) {
4800                 if (ses->server->sec_mode &
4801                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4802                         pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4803         }
4804
4805         pSMB->hdr.Uid = ses->Suid;
4806
4807         params = 2 /* level */  + name_len /*includes null */ ;
4808         pSMB->TotalDataCount = 0;
4809         pSMB->DataCount = 0;
4810         pSMB->DataOffset = 0;
4811         pSMB->MaxParameterCount = 0;
4812         /* BB find exact max SMB PDU from sess structure BB */
4813         pSMB->MaxDataCount = cpu_to_le16(4000);
4814         pSMB->MaxSetupCount = 0;
4815         pSMB->Reserved = 0;
4816         pSMB->Flags = 0;
4817         pSMB->Timeout = 0;
4818         pSMB->Reserved2 = 0;
4819         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4820           struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4821         pSMB->SetupCount = 1;
4822         pSMB->Reserved3 = 0;
4823         pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4824         byte_count = params + 3 /* pad */ ;
4825         pSMB->ParameterCount = cpu_to_le16(params);
4826         pSMB->TotalParameterCount = pSMB->ParameterCount;
4827         pSMB->MaxReferralLevel = cpu_to_le16(3);
4828         inc_rfc1001_len(pSMB, byte_count);
4829         pSMB->ByteCount = cpu_to_le16(byte_count);
4830
4831         rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4832                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4833         if (rc) {
4834                 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4835                 goto GetDFSRefExit;
4836         }
4837         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4838
4839         /* BB Also check if enough total bytes returned? */
4840         if (rc || get_bcc(&pSMBr->hdr) < 17) {
4841                 rc = -EIO;      /* bad smb */
4842                 goto GetDFSRefExit;
4843         }
4844
4845         cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4846                  get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4847
4848         /* parse returned result into more usable form */
4849         rc = parse_DFS_referrals(pSMBr, num_of_nodes,
4850                                  target_nodes, nls_codepage, remap,
4851                                  search_name);
4852
4853 GetDFSRefExit:
4854         cifs_buf_release(pSMB);
4855
4856         if (rc == -EAGAIN)
4857                 goto getDFSRetry;
4858
4859         return rc;
4860 }
4861
4862 /* Query File System Info such as free space to old servers such as Win 9x */
4863 int
4864 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4865               struct kstatfs *FSData)
4866 {
4867 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4868         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4869         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4870         FILE_SYSTEM_ALLOC_INFO *response_data;
4871         int rc = 0;
4872         int bytes_returned = 0;
4873         __u16 params, byte_count;
4874
4875         cifs_dbg(FYI, "OldQFSInfo\n");
4876 oldQFSInfoRetry:
4877         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4878                 (void **) &pSMBr);
4879         if (rc)
4880                 return rc;
4881
4882         params = 2;     /* level */
4883         pSMB->TotalDataCount = 0;
4884         pSMB->MaxParameterCount = cpu_to_le16(2);
4885         pSMB->MaxDataCount = cpu_to_le16(1000);
4886         pSMB->MaxSetupCount = 0;
4887         pSMB->Reserved = 0;
4888         pSMB->Flags = 0;
4889         pSMB->Timeout = 0;
4890         pSMB->Reserved2 = 0;
4891         byte_count = params + 1 /* pad */ ;
4892         pSMB->TotalParameterCount = cpu_to_le16(params);
4893         pSMB->ParameterCount = pSMB->TotalParameterCount;
4894         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4895         struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4896         pSMB->DataCount = 0;
4897         pSMB->DataOffset = 0;
4898         pSMB->SetupCount = 1;
4899         pSMB->Reserved3 = 0;
4900         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4901         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4902         inc_rfc1001_len(pSMB, byte_count);
4903         pSMB->ByteCount = cpu_to_le16(byte_count);
4904
4905         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4906                 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4907         if (rc) {
4908                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4909         } else {                /* decode response */
4910                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4911
4912                 if (rc || get_bcc(&pSMBr->hdr) < 18)
4913                         rc = -EIO;      /* bad smb */
4914                 else {
4915                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4916                         cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
4917                                  get_bcc(&pSMBr->hdr), data_offset);
4918
4919                         response_data = (FILE_SYSTEM_ALLOC_INFO *)
4920                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4921                         FSData->f_bsize =
4922                                 le16_to_cpu(response_data->BytesPerSector) *
4923                                 le32_to_cpu(response_data->
4924                                         SectorsPerAllocationUnit);
4925                         FSData->f_blocks =
4926                                le32_to_cpu(response_data->TotalAllocationUnits);
4927                         FSData->f_bfree = FSData->f_bavail =
4928                                 le32_to_cpu(response_data->FreeAllocationUnits);
4929                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4930                                  (unsigned long long)FSData->f_blocks,
4931                                  (unsigned long long)FSData->f_bfree,
4932                                  FSData->f_bsize);
4933                 }
4934         }
4935         cifs_buf_release(pSMB);
4936
4937         if (rc == -EAGAIN)
4938                 goto oldQFSInfoRetry;
4939
4940         return rc;
4941 }
4942
4943 int
4944 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4945                struct kstatfs *FSData)
4946 {
4947 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4948         TRANSACTION2_QFSI_REQ *pSMB = NULL;
4949         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4950         FILE_SYSTEM_INFO *response_data;
4951         int rc = 0;
4952         int bytes_returned = 0;
4953         __u16 params, byte_count;
4954
4955         cifs_dbg(FYI, "In QFSInfo\n");
4956 QFSInfoRetry:
4957         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4958                       (void **) &pSMBr);
4959         if (rc)
4960                 return rc;
4961
4962         params = 2;     /* level */
4963         pSMB->TotalDataCount = 0;
4964         pSMB->MaxParameterCount = cpu_to_le16(2);
4965         pSMB->MaxDataCount = cpu_to_le16(1000);
4966         pSMB->MaxSetupCount = 0;
4967         pSMB->Reserved = 0;
4968         pSMB->Flags = 0;
4969         pSMB->Timeout = 0;
4970         pSMB->Reserved2 = 0;
4971         byte_count = params + 1 /* pad */ ;
4972         pSMB->TotalParameterCount = cpu_to_le16(params);
4973         pSMB->ParameterCount = pSMB->TotalParameterCount;
4974         pSMB->ParameterOffset = cpu_to_le16(offsetof(
4975                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4976         pSMB->DataCount = 0;
4977         pSMB->DataOffset = 0;
4978         pSMB->SetupCount = 1;
4979         pSMB->Reserved3 = 0;
4980         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4981         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4982         inc_rfc1001_len(pSMB, byte_count);
4983         pSMB->ByteCount = cpu_to_le16(byte_count);
4984
4985         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4986                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4987         if (rc) {
4988                 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4989         } else {                /* decode response */
4990                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4991
4992                 if (rc || get_bcc(&pSMBr->hdr) < 24)
4993                         rc = -EIO;      /* bad smb */
4994                 else {
4995                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4996
4997                         response_data =
4998                             (FILE_SYSTEM_INFO
4999                              *) (((char *) &pSMBr->hdr.Protocol) +
5000                                  data_offset);
5001                         FSData->f_bsize =
5002                             le32_to_cpu(response_data->BytesPerSector) *
5003                             le32_to_cpu(response_data->
5004                                         SectorsPerAllocationUnit);
5005                         FSData->f_blocks =
5006                             le64_to_cpu(response_data->TotalAllocationUnits);
5007                         FSData->f_bfree = FSData->f_bavail =
5008                             le64_to_cpu(response_data->FreeAllocationUnits);
5009                         cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
5010                                  (unsigned long long)FSData->f_blocks,
5011                                  (unsigned long long)FSData->f_bfree,
5012                                  FSData->f_bsize);
5013                 }
5014         }
5015         cifs_buf_release(pSMB);
5016
5017         if (rc == -EAGAIN)
5018                 goto QFSInfoRetry;
5019
5020         return rc;
5021 }
5022
5023 int
5024 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5025 {
5026 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5027         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5028         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5029         FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5030         int rc = 0;
5031         int bytes_returned = 0;
5032         __u16 params, byte_count;
5033
5034         cifs_dbg(FYI, "In QFSAttributeInfo\n");
5035 QFSAttributeRetry:
5036         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5037                       (void **) &pSMBr);
5038         if (rc)
5039                 return rc;
5040
5041         params = 2;     /* level */
5042         pSMB->TotalDataCount = 0;
5043         pSMB->MaxParameterCount = cpu_to_le16(2);
5044         /* BB find exact max SMB PDU from sess structure BB */
5045         pSMB->MaxDataCount = cpu_to_le16(1000);
5046         pSMB->MaxSetupCount = 0;
5047         pSMB->Reserved = 0;
5048         pSMB->Flags = 0;
5049         pSMB->Timeout = 0;
5050         pSMB->Reserved2 = 0;
5051         byte_count = params + 1 /* pad */ ;
5052         pSMB->TotalParameterCount = cpu_to_le16(params);
5053         pSMB->ParameterCount = pSMB->TotalParameterCount;
5054         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5055                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5056         pSMB->DataCount = 0;
5057         pSMB->DataOffset = 0;
5058         pSMB->SetupCount = 1;
5059         pSMB->Reserved3 = 0;
5060         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5061         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5062         inc_rfc1001_len(pSMB, byte_count);
5063         pSMB->ByteCount = cpu_to_le16(byte_count);
5064
5065         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5066                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5067         if (rc) {
5068                 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5069         } else {                /* decode response */
5070                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5071
5072                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5073                         /* BB also check if enough bytes returned */
5074                         rc = -EIO;      /* bad smb */
5075                 } else {
5076                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5077                         response_data =
5078                             (FILE_SYSTEM_ATTRIBUTE_INFO
5079                              *) (((char *) &pSMBr->hdr.Protocol) +
5080                                  data_offset);
5081                         memcpy(&tcon->fsAttrInfo, response_data,
5082                                sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5083                 }
5084         }
5085         cifs_buf_release(pSMB);
5086
5087         if (rc == -EAGAIN)
5088                 goto QFSAttributeRetry;
5089
5090         return rc;
5091 }
5092
5093 int
5094 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5095 {
5096 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5097         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5098         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5099         FILE_SYSTEM_DEVICE_INFO *response_data;
5100         int rc = 0;
5101         int bytes_returned = 0;
5102         __u16 params, byte_count;
5103
5104         cifs_dbg(FYI, "In QFSDeviceInfo\n");
5105 QFSDeviceRetry:
5106         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5107                       (void **) &pSMBr);
5108         if (rc)
5109                 return rc;
5110
5111         params = 2;     /* level */
5112         pSMB->TotalDataCount = 0;
5113         pSMB->MaxParameterCount = cpu_to_le16(2);
5114         /* BB find exact max SMB PDU from sess structure BB */
5115         pSMB->MaxDataCount = cpu_to_le16(1000);
5116         pSMB->MaxSetupCount = 0;
5117         pSMB->Reserved = 0;
5118         pSMB->Flags = 0;
5119         pSMB->Timeout = 0;
5120         pSMB->Reserved2 = 0;
5121         byte_count = params + 1 /* pad */ ;
5122         pSMB->TotalParameterCount = cpu_to_le16(params);
5123         pSMB->ParameterCount = pSMB->TotalParameterCount;
5124         pSMB->ParameterOffset = cpu_to_le16(offsetof(
5125                 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5126
5127         pSMB->DataCount = 0;
5128         pSMB->DataOffset = 0;
5129         pSMB->SetupCount = 1;
5130         pSMB->Reserved3 = 0;
5131         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5132         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5133         inc_rfc1001_len(pSMB, byte_count);
5134         pSMB->ByteCount = cpu_to_le16(byte_count);
5135
5136         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5137                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5138         if (rc) {
5139                 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5140         } else {                /* decode response */
5141                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5142
5143                 if (rc || get_bcc(&pSMBr->hdr) <
5144                           sizeof(FILE_SYSTEM_DEVICE_INFO))
5145                         rc = -EIO;      /* bad smb */
5146                 else {
5147                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5148                         response_data =
5149                             (FILE_SYSTEM_DEVICE_INFO *)
5150                                 (((char *) &pSMBr->hdr.Protocol) +
5151                                  data_offset);
5152                         memcpy(&tcon->fsDevInfo, response_data,
5153                                sizeof(FILE_SYSTEM_DEVICE_INFO));
5154                 }
5155         }
5156         cifs_buf_release(pSMB);
5157
5158         if (rc == -EAGAIN)
5159                 goto QFSDeviceRetry;
5160
5161         return rc;
5162 }
5163
5164 int
5165 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5166 {
5167 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5168         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5169         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5170         FILE_SYSTEM_UNIX_INFO *response_data;
5171         int rc = 0;
5172         int bytes_returned = 0;
5173         __u16 params, byte_count;
5174
5175         cifs_dbg(FYI, "In QFSUnixInfo\n");
5176 QFSUnixRetry:
5177         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5178                                    (void **) &pSMB, (void **) &pSMBr);
5179         if (rc)
5180                 return rc;
5181
5182         params = 2;     /* level */
5183         pSMB->TotalDataCount = 0;
5184         pSMB->DataCount = 0;
5185         pSMB->DataOffset = 0;
5186         pSMB->MaxParameterCount = cpu_to_le16(2);
5187         /* BB find exact max SMB PDU from sess structure BB */
5188         pSMB->MaxDataCount = cpu_to_le16(100);
5189         pSMB->MaxSetupCount = 0;
5190         pSMB->Reserved = 0;
5191         pSMB->Flags = 0;
5192         pSMB->Timeout = 0;
5193         pSMB->Reserved2 = 0;
5194         byte_count = params + 1 /* pad */ ;
5195         pSMB->ParameterCount = cpu_to_le16(params);
5196         pSMB->TotalParameterCount = pSMB->ParameterCount;
5197         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5198                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5199         pSMB->SetupCount = 1;
5200         pSMB->Reserved3 = 0;
5201         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5202         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5203         inc_rfc1001_len(pSMB, byte_count);
5204         pSMB->ByteCount = cpu_to_le16(byte_count);
5205
5206         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5207                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5208         if (rc) {
5209                 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5210         } else {                /* decode response */
5211                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5212
5213                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5214                         rc = -EIO;      /* bad smb */
5215                 } else {
5216                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5217                         response_data =
5218                             (FILE_SYSTEM_UNIX_INFO
5219                              *) (((char *) &pSMBr->hdr.Protocol) +
5220                                  data_offset);
5221                         memcpy(&tcon->fsUnixInfo, response_data,
5222                                sizeof(FILE_SYSTEM_UNIX_INFO));
5223                 }
5224         }
5225         cifs_buf_release(pSMB);
5226
5227         if (rc == -EAGAIN)
5228                 goto QFSUnixRetry;
5229
5230
5231         return rc;
5232 }
5233
5234 int
5235 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5236 {
5237 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5238         TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5239         TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5240         int rc = 0;
5241         int bytes_returned = 0;
5242         __u16 params, param_offset, offset, byte_count;
5243
5244         cifs_dbg(FYI, "In SETFSUnixInfo\n");
5245 SETFSUnixRetry:
5246         /* BB switch to small buf init to save memory */
5247         rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5248                                         (void **) &pSMB, (void **) &pSMBr);
5249         if (rc)
5250                 return rc;
5251
5252         params = 4;     /* 2 bytes zero followed by info level. */
5253         pSMB->MaxSetupCount = 0;
5254         pSMB->Reserved = 0;
5255         pSMB->Flags = 0;
5256         pSMB->Timeout = 0;
5257         pSMB->Reserved2 = 0;
5258         param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5259                                 - 4;
5260         offset = param_offset + params;
5261
5262         pSMB->MaxParameterCount = cpu_to_le16(4);
5263         /* BB find exact max SMB PDU from sess structure BB */
5264         pSMB->MaxDataCount = cpu_to_le16(100);
5265         pSMB->SetupCount = 1;
5266         pSMB->Reserved3 = 0;
5267         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5268         byte_count = 1 /* pad */ + params + 12;
5269
5270         pSMB->DataCount = cpu_to_le16(12);
5271         pSMB->ParameterCount = cpu_to_le16(params);
5272         pSMB->TotalDataCount = pSMB->DataCount;
5273         pSMB->TotalParameterCount = pSMB->ParameterCount;
5274         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5275         pSMB->DataOffset = cpu_to_le16(offset);
5276
5277         /* Params. */
5278         pSMB->FileNum = 0;
5279         pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5280
5281         /* Data. */
5282         pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5283         pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5284         pSMB->ClientUnixCap = cpu_to_le64(cap);
5285
5286         inc_rfc1001_len(pSMB, byte_count);
5287         pSMB->ByteCount = cpu_to_le16(byte_count);
5288
5289         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5290                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5291         if (rc) {
5292                 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5293         } else {                /* decode response */
5294                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5295                 if (rc)
5296                         rc = -EIO;      /* bad smb */
5297         }
5298         cifs_buf_release(pSMB);
5299
5300         if (rc == -EAGAIN)
5301                 goto SETFSUnixRetry;
5302
5303         return rc;
5304 }
5305
5306
5307
5308 int
5309 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5310                    struct kstatfs *FSData)
5311 {
5312 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5313         TRANSACTION2_QFSI_REQ *pSMB = NULL;
5314         TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5315         FILE_SYSTEM_POSIX_INFO *response_data;
5316         int rc = 0;
5317         int bytes_returned = 0;
5318         __u16 params, byte_count;
5319
5320         cifs_dbg(FYI, "In QFSPosixInfo\n");
5321 QFSPosixRetry:
5322         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5323                       (void **) &pSMBr);
5324         if (rc)
5325                 return rc;
5326
5327         params = 2;     /* level */
5328         pSMB->TotalDataCount = 0;
5329         pSMB->DataCount = 0;
5330         pSMB->DataOffset = 0;
5331         pSMB->MaxParameterCount = cpu_to_le16(2);
5332         /* BB find exact max SMB PDU from sess structure BB */
5333         pSMB->MaxDataCount = cpu_to_le16(100);
5334         pSMB->MaxSetupCount = 0;
5335         pSMB->Reserved = 0;
5336         pSMB->Flags = 0;
5337         pSMB->Timeout = 0;
5338         pSMB->Reserved2 = 0;
5339         byte_count = params + 1 /* pad */ ;
5340         pSMB->ParameterCount = cpu_to_le16(params);
5341         pSMB->TotalParameterCount = pSMB->ParameterCount;
5342         pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5343                         smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5344         pSMB->SetupCount = 1;
5345         pSMB->Reserved3 = 0;
5346         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5347         pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5348         inc_rfc1001_len(pSMB, byte_count);
5349         pSMB->ByteCount = cpu_to_le16(byte_count);
5350
5351         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5352                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5353         if (rc) {
5354                 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5355         } else {                /* decode response */
5356                 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5357
5358                 if (rc || get_bcc(&pSMBr->hdr) < 13) {
5359                         rc = -EIO;      /* bad smb */
5360                 } else {
5361                         __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5362                         response_data =
5363                             (FILE_SYSTEM_POSIX_INFO
5364                              *) (((char *) &pSMBr->hdr.Protocol) +
5365                                  data_offset);
5366                         FSData->f_bsize =
5367                                         le32_to_cpu(response_data->BlockSize);
5368                         FSData->f_blocks =
5369                                         le64_to_cpu(response_data->TotalBlocks);
5370                         FSData->f_bfree =
5371                             le64_to_cpu(response_data->BlocksAvail);
5372                         if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5373                                 FSData->f_bavail = FSData->f_bfree;
5374                         } else {
5375                                 FSData->f_bavail =
5376                                     le64_to_cpu(response_data->UserBlocksAvail);
5377                         }
5378                         if (response_data->TotalFileNodes != cpu_to_le64(-1))
5379                                 FSData->f_files =
5380                                      le64_to_cpu(response_data->TotalFileNodes);
5381                         if (response_data->FreeFileNodes != cpu_to_le64(-1))
5382                                 FSData->f_ffree =
5383                                       le64_to_cpu(response_data->FreeFileNodes);
5384                 }
5385         }
5386         cifs_buf_release(pSMB);
5387
5388         if (rc == -EAGAIN)
5389                 goto QFSPosixRetry;
5390
5391         return rc;
5392 }
5393
5394
5395 /*
5396  * We can not use write of zero bytes trick to set file size due to need for
5397  * large file support. Also note that this SetPathInfo is preferred to
5398  * SetFileInfo based method in next routine which is only needed to work around
5399  * a sharing violation bugin Samba which this routine can run into.
5400  */
5401 int
5402 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5403               const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5404               bool set_allocation)
5405 {
5406         struct smb_com_transaction2_spi_req *pSMB = NULL;
5407         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5408         struct file_end_of_file_info *parm_data;
5409         int name_len;
5410         int rc = 0;
5411         int bytes_returned = 0;
5412         int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
5413
5414         __u16 params, byte_count, data_count, param_offset, offset;
5415
5416         cifs_dbg(FYI, "In SetEOF\n");
5417 SetEOFRetry:
5418         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5419                       (void **) &pSMBr);
5420         if (rc)
5421                 return rc;
5422
5423         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5424                 name_len =
5425                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5426                                        PATH_MAX, cifs_sb->local_nls, remap);
5427                 name_len++;     /* trailing null */
5428                 name_len *= 2;
5429         } else {        /* BB improve the check for buffer overruns BB */
5430                 name_len = strnlen(file_name, PATH_MAX);
5431                 name_len++;     /* trailing null */
5432                 strncpy(pSMB->FileName, file_name, name_len);
5433         }
5434         params = 6 + name_len;
5435         data_count = sizeof(struct file_end_of_file_info);
5436         pSMB->MaxParameterCount = cpu_to_le16(2);
5437         pSMB->MaxDataCount = cpu_to_le16(4100);
5438         pSMB->MaxSetupCount = 0;
5439         pSMB->Reserved = 0;
5440         pSMB->Flags = 0;
5441         pSMB->Timeout = 0;
5442         pSMB->Reserved2 = 0;
5443         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5444                                 InformationLevel) - 4;
5445         offset = param_offset + params;
5446         if (set_allocation) {
5447                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5448                         pSMB->InformationLevel =
5449                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5450                 else
5451                         pSMB->InformationLevel =
5452                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5453         } else /* Set File Size */  {
5454             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5455                     pSMB->InformationLevel =
5456                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5457             else
5458                     pSMB->InformationLevel =
5459                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5460         }
5461
5462         parm_data =
5463             (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5464                                        offset);
5465         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5466         pSMB->DataOffset = cpu_to_le16(offset);
5467         pSMB->SetupCount = 1;
5468         pSMB->Reserved3 = 0;
5469         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5470         byte_count = 3 /* pad */  + params + data_count;
5471         pSMB->DataCount = cpu_to_le16(data_count);
5472         pSMB->TotalDataCount = pSMB->DataCount;
5473         pSMB->ParameterCount = cpu_to_le16(params);
5474         pSMB->TotalParameterCount = pSMB->ParameterCount;
5475         pSMB->Reserved4 = 0;
5476         inc_rfc1001_len(pSMB, byte_count);
5477         parm_data->FileSize = cpu_to_le64(size);
5478         pSMB->ByteCount = cpu_to_le16(byte_count);
5479         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5480                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5481         if (rc)
5482                 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5483
5484         cifs_buf_release(pSMB);
5485
5486         if (rc == -EAGAIN)
5487                 goto SetEOFRetry;
5488
5489         return rc;
5490 }
5491
5492 int
5493 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5494                    struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5495 {
5496         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5497         struct file_end_of_file_info *parm_data;
5498         int rc = 0;
5499         __u16 params, param_offset, offset, byte_count, count;
5500
5501         cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5502                  (long long)size);
5503         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5504
5505         if (rc)
5506                 return rc;
5507
5508         pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5509         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5510
5511         params = 6;
5512         pSMB->MaxSetupCount = 0;
5513         pSMB->Reserved = 0;
5514         pSMB->Flags = 0;
5515         pSMB->Timeout = 0;
5516         pSMB->Reserved2 = 0;
5517         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5518         offset = param_offset + params;
5519
5520         count = sizeof(struct file_end_of_file_info);
5521         pSMB->MaxParameterCount = cpu_to_le16(2);
5522         /* BB find exact max SMB PDU from sess structure BB */
5523         pSMB->MaxDataCount = cpu_to_le16(1000);
5524         pSMB->SetupCount = 1;
5525         pSMB->Reserved3 = 0;
5526         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5527         byte_count = 3 /* pad */  + params + count;
5528         pSMB->DataCount = cpu_to_le16(count);
5529         pSMB->ParameterCount = cpu_to_le16(params);
5530         pSMB->TotalDataCount = pSMB->DataCount;
5531         pSMB->TotalParameterCount = pSMB->ParameterCount;
5532         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5533         parm_data =
5534                 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
5535                                 + offset);
5536         pSMB->DataOffset = cpu_to_le16(offset);
5537         parm_data->FileSize = cpu_to_le64(size);
5538         pSMB->Fid = cfile->fid.netfid;
5539         if (set_allocation) {
5540                 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5541                         pSMB->InformationLevel =
5542                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5543                 else
5544                         pSMB->InformationLevel =
5545                                 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5546         } else /* Set File Size */  {
5547             if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5548                     pSMB->InformationLevel =
5549                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5550             else
5551                     pSMB->InformationLevel =
5552                                 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5553         }
5554         pSMB->Reserved4 = 0;
5555         inc_rfc1001_len(pSMB, byte_count);
5556         pSMB->ByteCount = cpu_to_le16(byte_count);
5557         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5558         if (rc) {
5559                 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5560                          rc);
5561         }
5562
5563         /* Note: On -EAGAIN error only caller can retry on handle based calls
5564                 since file handle passed in no longer valid */
5565
5566         return rc;
5567 }
5568
5569 /* Some legacy servers such as NT4 require that the file times be set on
5570    an open handle, rather than by pathname - this is awkward due to
5571    potential access conflicts on the open, but it is unavoidable for these
5572    old servers since the only other choice is to go from 100 nanosecond DCE
5573    time and resort to the original setpathinfo level which takes the ancient
5574    DOS time format with 2 second granularity */
5575 int
5576 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5577                     const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5578 {
5579         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5580         char *data_offset;
5581         int rc = 0;
5582         __u16 params, param_offset, offset, byte_count, count;
5583
5584         cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5585         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5586
5587         if (rc)
5588                 return rc;
5589
5590         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5591         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5592
5593         params = 6;
5594         pSMB->MaxSetupCount = 0;
5595         pSMB->Reserved = 0;
5596         pSMB->Flags = 0;
5597         pSMB->Timeout = 0;
5598         pSMB->Reserved2 = 0;
5599         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5600         offset = param_offset + params;
5601
5602         data_offset = (char *)pSMB +
5603                         offsetof(struct smb_hdr, Protocol) + offset;
5604
5605         count = sizeof(FILE_BASIC_INFO);
5606         pSMB->MaxParameterCount = cpu_to_le16(2);
5607         /* BB find max SMB PDU from sess */
5608         pSMB->MaxDataCount = cpu_to_le16(1000);
5609         pSMB->SetupCount = 1;
5610         pSMB->Reserved3 = 0;
5611         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5612         byte_count = 3 /* pad */  + params + count;
5613         pSMB->DataCount = cpu_to_le16(count);
5614         pSMB->ParameterCount = cpu_to_le16(params);
5615         pSMB->TotalDataCount = pSMB->DataCount;
5616         pSMB->TotalParameterCount = pSMB->ParameterCount;
5617         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5618         pSMB->DataOffset = cpu_to_le16(offset);
5619         pSMB->Fid = fid;
5620         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5621                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5622         else
5623                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5624         pSMB->Reserved4 = 0;
5625         inc_rfc1001_len(pSMB, byte_count);
5626         pSMB->ByteCount = cpu_to_le16(byte_count);
5627         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5628         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5629         if (rc)
5630                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5631                          rc);
5632
5633         /* Note: On -EAGAIN error only caller can retry on handle based calls
5634                 since file handle passed in no longer valid */
5635
5636         return rc;
5637 }
5638
5639 int
5640 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5641                           bool delete_file, __u16 fid, __u32 pid_of_opener)
5642 {
5643         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5644         char *data_offset;
5645         int rc = 0;
5646         __u16 params, param_offset, offset, byte_count, count;
5647
5648         cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5649         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5650
5651         if (rc)
5652                 return rc;
5653
5654         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5655         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5656
5657         params = 6;
5658         pSMB->MaxSetupCount = 0;
5659         pSMB->Reserved = 0;
5660         pSMB->Flags = 0;
5661         pSMB->Timeout = 0;
5662         pSMB->Reserved2 = 0;
5663         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5664         offset = param_offset + params;
5665
5666         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5667
5668         count = 1;
5669         pSMB->MaxParameterCount = cpu_to_le16(2);
5670         /* BB find max SMB PDU from sess */
5671         pSMB->MaxDataCount = cpu_to_le16(1000);
5672         pSMB->SetupCount = 1;
5673         pSMB->Reserved3 = 0;
5674         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5675         byte_count = 3 /* pad */  + params + count;
5676         pSMB->DataCount = cpu_to_le16(count);
5677         pSMB->ParameterCount = cpu_to_le16(params);
5678         pSMB->TotalDataCount = pSMB->DataCount;
5679         pSMB->TotalParameterCount = pSMB->ParameterCount;
5680         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5681         pSMB->DataOffset = cpu_to_le16(offset);
5682         pSMB->Fid = fid;
5683         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5684         pSMB->Reserved4 = 0;
5685         inc_rfc1001_len(pSMB, byte_count);
5686         pSMB->ByteCount = cpu_to_le16(byte_count);
5687         *data_offset = delete_file ? 1 : 0;
5688         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5689         if (rc)
5690                 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5691
5692         return rc;
5693 }
5694
5695 int
5696 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5697                    const char *fileName, const FILE_BASIC_INFO *data,
5698                    const struct nls_table *nls_codepage, int remap)
5699 {
5700         TRANSACTION2_SPI_REQ *pSMB = NULL;
5701         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5702         int name_len;
5703         int rc = 0;
5704         int bytes_returned = 0;
5705         char *data_offset;
5706         __u16 params, param_offset, offset, byte_count, count;
5707
5708         cifs_dbg(FYI, "In SetTimes\n");
5709
5710 SetTimesRetry:
5711         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5712                       (void **) &pSMBr);
5713         if (rc)
5714                 return rc;
5715
5716         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5717                 name_len =
5718                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5719                                        PATH_MAX, nls_codepage, remap);
5720                 name_len++;     /* trailing null */
5721                 name_len *= 2;
5722         } else {        /* BB improve the check for buffer overruns BB */
5723                 name_len = strnlen(fileName, PATH_MAX);
5724                 name_len++;     /* trailing null */
5725                 strncpy(pSMB->FileName, fileName, name_len);
5726         }
5727
5728         params = 6 + name_len;
5729         count = sizeof(FILE_BASIC_INFO);
5730         pSMB->MaxParameterCount = cpu_to_le16(2);
5731         /* BB find max SMB PDU from sess structure BB */
5732         pSMB->MaxDataCount = cpu_to_le16(1000);
5733         pSMB->MaxSetupCount = 0;
5734         pSMB->Reserved = 0;
5735         pSMB->Flags = 0;
5736         pSMB->Timeout = 0;
5737         pSMB->Reserved2 = 0;
5738         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5739                                 InformationLevel) - 4;
5740         offset = param_offset + params;
5741         data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5742         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5743         pSMB->DataOffset = cpu_to_le16(offset);
5744         pSMB->SetupCount = 1;
5745         pSMB->Reserved3 = 0;
5746         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5747         byte_count = 3 /* pad */  + params + count;
5748
5749         pSMB->DataCount = cpu_to_le16(count);
5750         pSMB->ParameterCount = cpu_to_le16(params);
5751         pSMB->TotalDataCount = pSMB->DataCount;
5752         pSMB->TotalParameterCount = pSMB->ParameterCount;
5753         if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5754                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5755         else
5756                 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5757         pSMB->Reserved4 = 0;
5758         inc_rfc1001_len(pSMB, byte_count);
5759         memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5760         pSMB->ByteCount = cpu_to_le16(byte_count);
5761         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5762                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5763         if (rc)
5764                 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5765
5766         cifs_buf_release(pSMB);
5767
5768         if (rc == -EAGAIN)
5769                 goto SetTimesRetry;
5770
5771         return rc;
5772 }
5773
5774 /* Can not be used to set time stamps yet (due to old DOS time format) */
5775 /* Can be used to set attributes */
5776 #if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
5777           handling it anyway and NT4 was what we thought it would be needed for
5778           Do not delete it until we prove whether needed for Win9x though */
5779 int
5780 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
5781                 __u16 dos_attrs, const struct nls_table *nls_codepage)
5782 {
5783         SETATTR_REQ *pSMB = NULL;
5784         SETATTR_RSP *pSMBr = NULL;
5785         int rc = 0;
5786         int bytes_returned;
5787         int name_len;
5788
5789         cifs_dbg(FYI, "In SetAttrLegacy\n");
5790
5791 SetAttrLgcyRetry:
5792         rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5793                       (void **) &pSMBr);
5794         if (rc)
5795                 return rc;
5796
5797         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5798                 name_len =
5799                         ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
5800                                        PATH_MAX, nls_codepage);
5801                 name_len++;     /* trailing null */
5802                 name_len *= 2;
5803         } else {        /* BB improve the check for buffer overruns BB */
5804                 name_len = strnlen(fileName, PATH_MAX);
5805                 name_len++;     /* trailing null */
5806                 strncpy(pSMB->fileName, fileName, name_len);
5807         }
5808         pSMB->attr = cpu_to_le16(dos_attrs);
5809         pSMB->BufferFormat = 0x04;
5810         inc_rfc1001_len(pSMB, name_len + 1);
5811         pSMB->ByteCount = cpu_to_le16(name_len + 1);
5812         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5813                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5814         if (rc)
5815                 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
5816
5817         cifs_buf_release(pSMB);
5818
5819         if (rc == -EAGAIN)
5820                 goto SetAttrLgcyRetry;
5821
5822         return rc;
5823 }
5824 #endif /* temporarily unneeded SetAttr legacy function */
5825
5826 static void
5827 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5828                         const struct cifs_unix_set_info_args *args)
5829 {
5830         u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5831         u64 mode = args->mode;
5832
5833         if (uid_valid(args->uid))
5834                 uid = from_kuid(&init_user_ns, args->uid);
5835         if (gid_valid(args->gid))
5836                 gid = from_kgid(&init_user_ns, args->gid);
5837
5838         /*
5839          * Samba server ignores set of file size to zero due to bugs in some
5840          * older clients, but we should be precise - we use SetFileSize to
5841          * set file size and do not want to truncate file size to zero
5842          * accidentally as happened on one Samba server beta by putting
5843          * zero instead of -1 here
5844          */
5845         data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5846         data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5847         data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5848         data_offset->LastAccessTime = cpu_to_le64(args->atime);
5849         data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5850         data_offset->Uid = cpu_to_le64(uid);
5851         data_offset->Gid = cpu_to_le64(gid);
5852         /* better to leave device as zero when it is  */
5853         data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5854         data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5855         data_offset->Permissions = cpu_to_le64(mode);
5856
5857         if (S_ISREG(mode))
5858                 data_offset->Type = cpu_to_le32(UNIX_FILE);
5859         else if (S_ISDIR(mode))
5860                 data_offset->Type = cpu_to_le32(UNIX_DIR);
5861         else if (S_ISLNK(mode))
5862                 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5863         else if (S_ISCHR(mode))
5864                 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5865         else if (S_ISBLK(mode))
5866                 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5867         else if (S_ISFIFO(mode))
5868                 data_offset->Type = cpu_to_le32(UNIX_FIFO);
5869         else if (S_ISSOCK(mode))
5870                 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5871 }
5872
5873 int
5874 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5875                        const struct cifs_unix_set_info_args *args,
5876                        u16 fid, u32 pid_of_opener)
5877 {
5878         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5879         char *data_offset;
5880         int rc = 0;
5881         u16 params, param_offset, offset, byte_count, count;
5882
5883         cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5884         rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5885
5886         if (rc)
5887                 return rc;
5888
5889         pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5890         pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5891
5892         params = 6;
5893         pSMB->MaxSetupCount = 0;
5894         pSMB->Reserved = 0;
5895         pSMB->Flags = 0;
5896         pSMB->Timeout = 0;
5897         pSMB->Reserved2 = 0;
5898         param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5899         offset = param_offset + params;
5900
5901         data_offset = (char *)pSMB +
5902                         offsetof(struct smb_hdr, Protocol) + offset;
5903
5904         count = sizeof(FILE_UNIX_BASIC_INFO);
5905
5906         pSMB->MaxParameterCount = cpu_to_le16(2);
5907         /* BB find max SMB PDU from sess */
5908         pSMB->MaxDataCount = cpu_to_le16(1000);
5909         pSMB->SetupCount = 1;
5910         pSMB->Reserved3 = 0;
5911         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5912         byte_count = 3 /* pad */  + params + count;
5913         pSMB->DataCount = cpu_to_le16(count);
5914         pSMB->ParameterCount = cpu_to_le16(params);
5915         pSMB->TotalDataCount = pSMB->DataCount;
5916         pSMB->TotalParameterCount = pSMB->ParameterCount;
5917         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5918         pSMB->DataOffset = cpu_to_le16(offset);
5919         pSMB->Fid = fid;
5920         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5921         pSMB->Reserved4 = 0;
5922         inc_rfc1001_len(pSMB, byte_count);
5923         pSMB->ByteCount = cpu_to_le16(byte_count);
5924
5925         cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5926
5927         rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5928         if (rc)
5929                 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5930                          rc);
5931
5932         /* Note: On -EAGAIN error only caller can retry on handle based calls
5933                 since file handle passed in no longer valid */
5934
5935         return rc;
5936 }
5937
5938 int
5939 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5940                        const char *file_name,
5941                        const struct cifs_unix_set_info_args *args,
5942                        const struct nls_table *nls_codepage, int remap)
5943 {
5944         TRANSACTION2_SPI_REQ *pSMB = NULL;
5945         TRANSACTION2_SPI_RSP *pSMBr = NULL;
5946         int name_len;
5947         int rc = 0;
5948         int bytes_returned = 0;
5949         FILE_UNIX_BASIC_INFO *data_offset;
5950         __u16 params, param_offset, offset, count, byte_count;
5951
5952         cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5953 setPermsRetry:
5954         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5955                       (void **) &pSMBr);
5956         if (rc)
5957                 return rc;
5958
5959         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5960                 name_len =
5961                     cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5962                                        PATH_MAX, nls_codepage, remap);
5963                 name_len++;     /* trailing null */
5964                 name_len *= 2;
5965         } else {        /* BB improve the check for buffer overruns BB */
5966                 name_len = strnlen(file_name, PATH_MAX);
5967                 name_len++;     /* trailing null */
5968                 strncpy(pSMB->FileName, file_name, name_len);
5969         }
5970
5971         params = 6 + name_len;
5972         count = sizeof(FILE_UNIX_BASIC_INFO);
5973         pSMB->MaxParameterCount = cpu_to_le16(2);
5974         /* BB find max SMB PDU from sess structure BB */
5975         pSMB->MaxDataCount = cpu_to_le16(1000);
5976         pSMB->MaxSetupCount = 0;
5977         pSMB->Reserved = 0;
5978         pSMB->Flags = 0;
5979         pSMB->Timeout = 0;
5980         pSMB->Reserved2 = 0;
5981         param_offset = offsetof(struct smb_com_transaction2_spi_req,
5982                                 InformationLevel) - 4;
5983         offset = param_offset + params;
5984         data_offset =
5985             (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
5986                                       offset);
5987         memset(data_offset, 0, count);
5988         pSMB->DataOffset = cpu_to_le16(offset);
5989         pSMB->ParameterOffset = cpu_to_le16(param_offset);
5990         pSMB->SetupCount = 1;
5991         pSMB->Reserved3 = 0;
5992         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5993         byte_count = 3 /* pad */  + params + count;
5994         pSMB->ParameterCount = cpu_to_le16(params);
5995         pSMB->DataCount = cpu_to_le16(count);
5996         pSMB->TotalParameterCount = pSMB->ParameterCount;
5997         pSMB->TotalDataCount = pSMB->DataCount;
5998         pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5999         pSMB->Reserved4 = 0;
6000         inc_rfc1001_len(pSMB, byte_count);
6001
6002         cifs_fill_unix_set_info(data_offset, args);
6003
6004         pSMB->ByteCount = cpu_to_le16(byte_count);
6005         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6006                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6007         if (rc)
6008                 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6009
6010         cifs_buf_release(pSMB);
6011         if (rc == -EAGAIN)
6012                 goto setPermsRetry;
6013         return rc;
6014 }
6015
6016 #ifdef CONFIG_CIFS_XATTR
6017 /*
6018  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6019  * function used by listxattr and getxattr type calls. When ea_name is set,
6020  * it looks for that attribute name and stuffs that value into the EAData
6021  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6022  * buffer. In both cases, the return value is either the length of the
6023  * resulting data or a negative error code. If EAData is a NULL pointer then
6024  * the data isn't copied to it, but the length is returned.
6025  */
6026 ssize_t
6027 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6028                 const unsigned char *searchName, const unsigned char *ea_name,
6029                 char *EAData, size_t buf_size,
6030                 const struct nls_table *nls_codepage, int remap)
6031 {
6032                 /* BB assumes one setup word */
6033         TRANSACTION2_QPI_REQ *pSMB = NULL;
6034         TRANSACTION2_QPI_RSP *pSMBr = NULL;
6035         int rc = 0;
6036         int bytes_returned;
6037         int list_len;
6038         struct fealist *ea_response_data;
6039         struct fea *temp_fea;
6040         char *temp_ptr;
6041         char *end_of_smb;
6042         __u16 params, byte_count, data_offset;
6043         unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6044
6045         cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6046 QAllEAsRetry:
6047         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6048                       (void **) &pSMBr);
6049         if (rc)
6050                 return rc;
6051
6052         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6053                 list_len =
6054                     cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6055                                        PATH_MAX, nls_codepage, remap);
6056                 list_len++;     /* trailing null */
6057                 list_len *= 2;
6058         } else {        /* BB improve the check for buffer overruns BB */
6059                 list_len = strnlen(searchName, PATH_MAX);
6060                 list_len++;     /* trailing null */
6061                 strncpy(pSMB->FileName, searchName, list_len);
6062         }
6063
6064         params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6065         pSMB->TotalDataCount = 0;
6066         pSMB->MaxParameterCount = cpu_to_le16(2);
6067         /* BB find exact max SMB PDU from sess structure BB */
6068         pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6069         pSMB->MaxSetupCount = 0;
6070         pSMB->Reserved = 0;
6071         pSMB->Flags = 0;
6072         pSMB->Timeout = 0;
6073         pSMB->Reserved2 = 0;
6074         pSMB->ParameterOffset = cpu_to_le16(offsetof(
6075         struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6076         pSMB->DataCount = 0;
6077         pSMB->DataOffset = 0;
6078         pSMB->SetupCount = 1;
6079         pSMB->Reserved3 = 0;
6080         pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6081         byte_count = params + 1 /* pad */ ;
6082         pSMB->TotalParameterCount = cpu_to_le16(params);
6083         pSMB->ParameterCount = pSMB->TotalParameterCount;
6084         pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6085         pSMB->Reserved4 = 0;
6086         inc_rfc1001_len(pSMB, byte_count);
6087         pSMB->ByteCount = cpu_to_le16(byte_count);
6088
6089         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6090                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6091         if (rc) {
6092                 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6093                 goto QAllEAsOut;
6094         }
6095
6096
6097         /* BB also check enough total bytes returned */
6098         /* BB we need to improve the validity checking
6099         of these trans2 responses */
6100
6101         rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6102         if (rc || get_bcc(&pSMBr->hdr) < 4) {
6103                 rc = -EIO;      /* bad smb */
6104                 goto QAllEAsOut;
6105         }
6106
6107         /* check that length of list is not more than bcc */
6108         /* check that each entry does not go beyond length
6109            of list */
6110         /* check that each element of each entry does not
6111            go beyond end of list */
6112         /* validate_trans2_offsets() */
6113         /* BB check if start of smb + data_offset > &bcc+ bcc */
6114
6115         data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6116         ea_response_data = (struct fealist *)
6117                                 (((char *) &pSMBr->hdr.Protocol) + data_offset);
6118
6119         list_len = le32_to_cpu(ea_response_data->list_len);
6120         cifs_dbg(FYI, "ea length %d\n", list_len);
6121         if (list_len <= 8) {
6122                 cifs_dbg(FYI, "empty EA list returned from server\n");
6123                 goto QAllEAsOut;
6124         }
6125
6126         /* make sure list_len doesn't go past end of SMB */
6127         end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6128         if ((char *)ea_response_data + list_len > end_of_smb) {
6129                 cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6130                 rc = -EIO;
6131                 goto QAllEAsOut;
6132         }
6133
6134         /* account for ea list len */
6135         list_len -= 4;
6136         temp_fea = ea_response_data->list;
6137         temp_ptr = (char *)temp_fea;
6138         while (list_len > 0) {
6139                 unsigned int name_len;
6140                 __u16 value_len;
6141
6142                 list_len -= 4;
6143                 temp_ptr += 4;
6144                 /* make sure we can read name_len and value_len */
6145                 if (list_len < 0) {
6146                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6147                         rc = -EIO;
6148                         goto QAllEAsOut;
6149                 }
6150
6151                 name_len = temp_fea->name_len;
6152                 value_len = le16_to_cpu(temp_fea->value_len);
6153                 list_len -= name_len + 1 + value_len;
6154                 if (list_len < 0) {
6155                         cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6156                         rc = -EIO;
6157                         goto QAllEAsOut;
6158                 }
6159
6160                 if (ea_name) {
6161                         if (ea_name_len == name_len &&
6162                             memcmp(ea_name, temp_ptr, name_len) == 0) {
6163                                 temp_ptr += name_len + 1;
6164                                 rc = value_len;
6165                                 if (buf_size == 0)
6166                                         goto QAllEAsOut;
6167                                 if ((size_t)value_len > buf_size) {
6168                                         rc = -ERANGE;
6169                                         goto QAllEAsOut;
6170                                 }
6171                                 memcpy(EAData, temp_ptr, value_len);
6172                                 goto QAllEAsOut;
6173                         }
6174                 } else {
6175                         /* account for prefix user. and trailing null */
6176                         rc += (5 + 1 + name_len);
6177                         if (rc < (int) buf_size) {
6178                                 memcpy(EAData, "user.", 5);
6179                                 EAData += 5;
6180                                 memcpy(EAData, temp_ptr, name_len);
6181                                 EAData += name_len;
6182                                 /* null terminate name */
6183                                 *EAData = 0;
6184                                 ++EAData;
6185                         } else if (buf_size == 0) {
6186                                 /* skip copy - calc size only */
6187                         } else {
6188                                 /* stop before overrun buffer */
6189                                 rc = -ERANGE;
6190                                 break;
6191                         }
6192                 }
6193                 temp_ptr += name_len + 1 + value_len;
6194                 temp_fea = (struct fea *)temp_ptr;
6195         }
6196
6197         /* didn't find the named attribute */
6198         if (ea_name)
6199                 rc = -ENODATA;
6200
6201 QAllEAsOut:
6202         cifs_buf_release(pSMB);
6203         if (rc == -EAGAIN)
6204                 goto QAllEAsRetry;
6205
6206         return (ssize_t)rc;
6207 }
6208
6209 int
6210 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6211              const char *fileName, const char *ea_name, const void *ea_value,
6212              const __u16 ea_value_len, const struct nls_table *nls_codepage,
6213              int remap)
6214 {
6215         struct smb_com_transaction2_spi_req *pSMB = NULL;
6216         struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6217         struct fealist *parm_data;
6218         int name_len;
6219         int rc = 0;
6220         int bytes_returned = 0;
6221         __u16 params, param_offset, byte_count, offset, count;
6222
6223         cifs_dbg(FYI, "In SetEA\n");
6224 SetEARetry:
6225         rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6226                       (void **) &pSMBr);
6227         if (rc)
6228                 return rc;
6229
6230         if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6231                 name_len =
6232                     cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6233                                        PATH_MAX, nls_codepage, remap);
6234                 name_len++;     /* trailing null */
6235                 name_len *= 2;
6236         } else {        /* BB improve the check for buffer overruns BB */
6237                 name_len = strnlen(fileName, PATH_MAX);
6238                 name_len++;     /* trailing null */
6239                 strncpy(pSMB->FileName, fileName, name_len);
6240         }
6241
6242         params = 6 + name_len;
6243
6244         /* done calculating parms using name_len of file name,
6245         now use name_len to calculate length of ea name
6246         we are going to create in the inode xattrs */
6247         if (ea_name == NULL)
6248                 name_len = 0;
6249         else
6250                 name_len = strnlen(ea_name, 255);
6251
6252         count = sizeof(*parm_data) + ea_value_len + name_len;
6253         pSMB->MaxParameterCount = cpu_to_le16(2);
6254         /* BB find max SMB PDU from sess */
6255         pSMB->MaxDataCount = cpu_to_le16(1000);
6256         pSMB->MaxSetupCount = 0;
6257         pSMB->Reserved = 0;
6258         pSMB->Flags = 0;
6259         pSMB->Timeout = 0;
6260         pSMB->Reserved2 = 0;
6261         param_offset = offsetof(struct smb_com_transaction2_spi_req,
6262                                 InformationLevel) - 4;
6263         offset = param_offset + params;
6264         pSMB->InformationLevel =
6265                 cpu_to_le16(SMB_SET_FILE_EA);
6266
6267         parm_data =
6268                 (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
6269                                        offset);
6270         pSMB->ParameterOffset = cpu_to_le16(param_offset);
6271         pSMB->DataOffset = cpu_to_le16(offset);
6272         pSMB->SetupCount = 1;
6273         pSMB->Reserved3 = 0;
6274         pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6275         byte_count = 3 /* pad */  + params + count;
6276         pSMB->DataCount = cpu_to_le16(count);
6277         parm_data->list_len = cpu_to_le32(count);
6278         parm_data->list[0].EA_flags = 0;
6279         /* we checked above that name len is less than 255 */
6280         parm_data->list[0].name_len = (__u8)name_len;
6281         /* EA names are always ASCII */
6282         if (ea_name)
6283                 strncpy(parm_data->list[0].name, ea_name, name_len);
6284         parm_data->list[0].name[name_len] = 0;
6285         parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6286         /* caller ensures that ea_value_len is less than 64K but
6287         we need to ensure that it fits within the smb */
6288
6289         /*BB add length check to see if it would fit in
6290              negotiated SMB buffer size BB */
6291         /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6292         if (ea_value_len)
6293                 memcpy(parm_data->list[0].name+name_len+1,
6294                        ea_value, ea_value_len);
6295
6296         pSMB->TotalDataCount = pSMB->DataCount;
6297         pSMB->ParameterCount = cpu_to_le16(params);
6298         pSMB->TotalParameterCount = pSMB->ParameterCount;
6299         pSMB->Reserved4 = 0;
6300         inc_rfc1001_len(pSMB, byte_count);
6301         pSMB->ByteCount = cpu_to_le16(byte_count);
6302         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6303                          (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6304         if (rc)
6305                 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6306
6307         cifs_buf_release(pSMB);
6308
6309         if (rc == -EAGAIN)
6310                 goto SetEARetry;
6311
6312         return rc;
6313 }
6314 #endif
6315
6316 #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
6317 /*
6318  *      Years ago the kernel added a "dnotify" function for Samba server,
6319  *      to allow network clients (such as Windows) to display updated
6320  *      lists of files in directory listings automatically when
6321  *      files are added by one user when another user has the
6322  *      same directory open on their desktop.  The Linux cifs kernel
6323  *      client hooked into the kernel side of this interface for
6324  *      the same reason, but ironically when the VFS moved from
6325  *      "dnotify" to "inotify" it became harder to plug in Linux
6326  *      network file system clients (the most obvious use case
6327  *      for notify interfaces is when multiple users can update
6328  *      the contents of the same directory - exactly what network
6329  *      file systems can do) although the server (Samba) could
6330  *      still use it.  For the short term we leave the worker
6331  *      function ifdeffed out (below) until inotify is fixed
6332  *      in the VFS to make it easier to plug in network file
6333  *      system clients.  If inotify turns out to be permanently
6334  *      incompatible for network fs clients, we could instead simply
6335  *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
6336  */
6337 int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
6338                   const int notify_subdirs, const __u16 netfid,
6339                   __u32 filter, struct file *pfile, int multishot,
6340                   const struct nls_table *nls_codepage)
6341 {
6342         int rc = 0;
6343         struct smb_com_transaction_change_notify_req *pSMB = NULL;
6344         struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
6345         struct dir_notify_req *dnotify_req;
6346         int bytes_returned;
6347
6348         cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
6349         rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
6350                       (void **) &pSMBr);
6351         if (rc)
6352                 return rc;
6353
6354         pSMB->TotalParameterCount = 0 ;
6355         pSMB->TotalDataCount = 0;
6356         pSMB->MaxParameterCount = cpu_to_le32(2);
6357         pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
6358         pSMB->MaxSetupCount = 4;
6359         pSMB->Reserved = 0;
6360         pSMB->ParameterOffset = 0;
6361         pSMB->DataCount = 0;
6362         pSMB->DataOffset = 0;
6363         pSMB->SetupCount = 4; /* single byte does not need le conversion */
6364         pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
6365         pSMB->ParameterCount = pSMB->TotalParameterCount;
6366         if (notify_subdirs)
6367                 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
6368         pSMB->Reserved2 = 0;
6369         pSMB->CompletionFilter = cpu_to_le32(filter);
6370         pSMB->Fid = netfid; /* file handle always le */
6371         pSMB->ByteCount = 0;
6372
6373         rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6374                          (struct smb_hdr *)pSMBr, &bytes_returned,
6375                          CIFS_ASYNC_OP);
6376         if (rc) {
6377                 cifs_dbg(FYI, "Error in Notify = %d\n", rc);
6378         } else {
6379                 /* Add file to outstanding requests */
6380                 /* BB change to kmem cache alloc */
6381                 dnotify_req = kmalloc(
6382                                                 sizeof(struct dir_notify_req),
6383                                                  GFP_KERNEL);
6384                 if (dnotify_req) {
6385                         dnotify_req->Pid = pSMB->hdr.Pid;
6386                         dnotify_req->PidHigh = pSMB->hdr.PidHigh;
6387                         dnotify_req->Mid = pSMB->hdr.Mid;
6388                         dnotify_req->Tid = pSMB->hdr.Tid;
6389                         dnotify_req->Uid = pSMB->hdr.Uid;
6390                         dnotify_req->netfid = netfid;
6391                         dnotify_req->pfile = pfile;
6392                         dnotify_req->filter = filter;
6393                         dnotify_req->multishot = multishot;
6394                         spin_lock(&GlobalMid_Lock);
6395                         list_add_tail(&dnotify_req->lhead,
6396                                         &GlobalDnotifyReqList);
6397                         spin_unlock(&GlobalMid_Lock);
6398                 } else
6399                         rc = -ENOMEM;
6400         }
6401         cifs_buf_release(pSMB);
6402         return rc;
6403 }
6404 #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */