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