whiterose

linux unikernel
Log | Files | Refs | README | LICENSE | git clone https://git.ne02ptzero.me/git/whiterose

cifssmb.c (199303B)


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