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