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