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