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