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