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