xref: /linux/fs/smb/client/cifssmb.c (revision b012ffcd45b0c5bb9eeb57ec1e7e2a71d3f36e06)
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 		__u16 data_offset;
2373 		__u16 data_count;
2374 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2375 
2376 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2377 			rc = smb_EIO2(smb_eio_trace_lock_bcc_too_small,
2378 				      get_bcc(&pSMBr->hdr), sizeof(*parm_data));
2379 			goto plk_err_exit;
2380 		}
2381 		data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2382 		data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2383 		if (data_count < sizeof(struct cifs_posix_lock)) {
2384 			rc = smb_EIO2(smb_eio_trace_lock_data_too_small,
2385 				      data_count, sizeof(struct cifs_posix_lock));
2386 			goto plk_err_exit;
2387 		}
2388 		parm_data = (struct cifs_posix_lock *)
2389 			((char *)&pSMBr->hdr.Protocol + data_offset);
2390 		if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2391 			pLockData->c.flc_type = F_UNLCK;
2392 		else {
2393 			if (parm_data->lock_type ==
2394 					cpu_to_le16(CIFS_RDLCK))
2395 				pLockData->c.flc_type = F_RDLCK;
2396 			else if (parm_data->lock_type ==
2397 					cpu_to_le16(CIFS_WRLCK))
2398 				pLockData->c.flc_type = F_WRLCK;
2399 
2400 			pLockData->fl_start = le64_to_cpu(parm_data->start);
2401 			pLockData->fl_end = pLockData->fl_start +
2402 				(le64_to_cpu(parm_data->length) ?
2403 				 le64_to_cpu(parm_data->length) - 1 : 0);
2404 			pLockData->c.flc_pid = -le32_to_cpu(parm_data->pid);
2405 		}
2406 	}
2407 
2408 plk_err_exit:
2409 	free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2410 
2411 	/* Note: On -EAGAIN error only caller can retry on handle based calls
2412 	   since file handle passed in no longer valid */
2413 
2414 	return rc;
2415 }
2416 
2417 
2418 int
2419 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2420 {
2421 	int rc = 0;
2422 	CLOSE_REQ *pSMB = NULL;
2423 	unsigned int in_len;
2424 
2425 	cifs_dbg(FYI, "In CIFSSMBClose\n");
2426 
2427 /* do not retry on dead session on close */
2428 	rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2429 	if (rc == -EAGAIN)
2430 		return 0;
2431 	if (rc < 0)
2432 		return rc;
2433 	in_len = rc;
2434 
2435 	pSMB->FileID = (__u16) smb_file_id;
2436 	pSMB->LastWriteTime = 0xFFFFFFFF;
2437 	pSMB->ByteCount = 0;
2438 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
2439 	cifs_small_buf_release(pSMB);
2440 	cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2441 	if (rc) {
2442 		if (rc != -EINTR) {
2443 			/* EINTR is expected when user ctl-c to kill app */
2444 			cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2445 		}
2446 	}
2447 
2448 	/* Since session is dead, file will be closed on server already */
2449 	if (rc == -EAGAIN)
2450 		rc = 0;
2451 
2452 	return rc;
2453 }
2454 
2455 int
2456 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2457 {
2458 	int rc = 0;
2459 	FLUSH_REQ *pSMB = NULL;
2460 	unsigned int in_len;
2461 
2462 	cifs_dbg(FYI, "In CIFSSMBFlush\n");
2463 
2464 	rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2465 	if (rc < 0)
2466 		return rc;
2467 	in_len = rc;
2468 
2469 	pSMB->FileID = (__u16) smb_file_id;
2470 	pSMB->ByteCount = 0;
2471 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
2472 	cifs_small_buf_release(pSMB);
2473 	cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2474 	if (rc)
2475 		cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2476 
2477 	return rc;
2478 }
2479 
2480 int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2481 		  struct dentry *source_dentry,
2482 		  const char *from_name, const char *to_name,
2483 		  struct cifs_sb_info *cifs_sb)
2484 {
2485 	int rc = 0;
2486 	RENAME_REQ *pSMB = NULL;
2487 	RENAME_RSP *pSMBr = NULL;
2488 	unsigned int in_len;
2489 	int bytes_returned;
2490 	int name_len, name_len2;
2491 	__u16 count;
2492 	int remap = cifs_remap(cifs_sb);
2493 
2494 	cifs_dbg(FYI, "In CIFSSMBRename\n");
2495 renameRetry:
2496 	rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2497 		      (void **) &pSMBr);
2498 	if (rc < 0)
2499 		return rc;
2500 	in_len = rc;
2501 
2502 	pSMB->BufferFormat = 0x04;
2503 	pSMB->SearchAttributes =
2504 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2505 			ATTR_DIRECTORY);
2506 
2507 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2508 		name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2509 					      from_name, PATH_MAX,
2510 					      cifs_sb->local_nls, remap);
2511 		name_len++;	/* trailing null */
2512 		name_len *= 2;
2513 		pSMB->OldFileName[name_len] = 0x04;	/* pad */
2514 	/* protocol requires ASCII signature byte on Unicode string */
2515 		pSMB->OldFileName[name_len + 1] = 0x00;
2516 		name_len2 =
2517 		    cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2518 				       to_name, PATH_MAX, cifs_sb->local_nls,
2519 				       remap);
2520 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2521 		name_len2 *= 2;	/* convert to bytes */
2522 	} else {
2523 		name_len = copy_path_name(pSMB->OldFileName, from_name);
2524 		name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2525 		pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2526 		name_len2++;	/* signature byte */
2527 	}
2528 
2529 	count = 1 /* 1st signature byte */  + name_len + name_len2;
2530 	in_len += count;
2531 	pSMB->ByteCount = cpu_to_le16(count);
2532 
2533 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2534 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2535 	cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2536 	if (rc)
2537 		cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2538 
2539 	cifs_buf_release(pSMB);
2540 
2541 	if (rc == -EAGAIN)
2542 		goto renameRetry;
2543 
2544 	return rc;
2545 }
2546 
2547 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2548 			  int netfid, const char *target_name, int remap)
2549 {
2550 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2551 	struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2552 	struct set_file_rename *rename_info;
2553 	unsigned int in_len;
2554 	char *data_offset;
2555 	char dummy_string[30];
2556 	int rc = 0;
2557 	int bytes_returned = 0;
2558 	int len_of_str;
2559 	__u16 params, param_offset, offset, count, byte_count;
2560 
2561 	cifs_dbg(FYI, "Rename to File by handle\n");
2562 	rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2563 			(void **) &pSMBr);
2564 	if (rc < 0)
2565 		return rc;
2566 	in_len = rc;
2567 
2568 	params = 6;
2569 	pSMB->MaxSetupCount = 0;
2570 	pSMB->Reserved = 0;
2571 	pSMB->Flags = 0;
2572 	pSMB->Timeout = 0;
2573 	pSMB->Reserved2 = 0;
2574 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
2575 	offset = param_offset + params;
2576 
2577 	data_offset = (char *)(pSMB) + offset;
2578 	rename_info = (struct set_file_rename *) data_offset;
2579 	pSMB->MaxParameterCount = cpu_to_le16(2);
2580 	pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2581 	pSMB->SetupCount = 1;
2582 	pSMB->Reserved3 = 0;
2583 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2584 	byte_count = 3 /* pad */  + params;
2585 	pSMB->ParameterCount = cpu_to_le16(params);
2586 	pSMB->TotalParameterCount = pSMB->ParameterCount;
2587 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
2588 	pSMB->DataOffset = cpu_to_le16(offset);
2589 	/* construct random name ".cifs_tmp<inodenum><mid>" */
2590 	rename_info->overwrite = cpu_to_le32(1);
2591 	rename_info->root_fid  = 0;
2592 	/* unicode only call */
2593 	if (target_name == NULL) {
2594 		sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2595 		len_of_str =
2596 			cifsConvertToUTF16((__le16 *)rename_info->target_name,
2597 					dummy_string, 24,
2598 					pTcon->ses->local_nls, remap);
2599 	} else {
2600 		len_of_str =
2601 			cifsConvertToUTF16((__le16 *)rename_info->target_name,
2602 					target_name, PATH_MAX,
2603 					pTcon->ses->local_nls, remap);
2604 	}
2605 	rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2606 	count = sizeof(struct set_file_rename) + (2 * len_of_str);
2607 	byte_count += count;
2608 	pSMB->DataCount = cpu_to_le16(count);
2609 	pSMB->TotalDataCount = pSMB->DataCount;
2610 	pSMB->Fid = netfid;
2611 	pSMB->InformationLevel =
2612 		cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2613 	pSMB->Reserved4 = 0;
2614 	in_len += byte_count;
2615 	pSMB->ByteCount = cpu_to_le16(byte_count);
2616 	rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, in_len,
2617 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2618 	cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2619 	if (rc)
2620 		cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2621 			 rc);
2622 
2623 	cifs_buf_release(pSMB);
2624 
2625 	/* Note: On -EAGAIN error only caller can retry on handle based calls
2626 		since file handle passed in no longer valid */
2627 
2628 	return rc;
2629 }
2630 
2631 int
2632 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2633 		      const char *fromName, const char *toName,
2634 		      const struct nls_table *nls_codepage, int remap)
2635 {
2636 	TRANSACTION2_SPI_REQ *pSMB = NULL;
2637 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
2638 	unsigned int in_len;
2639 	char *data_offset;
2640 	int name_len;
2641 	int name_len_target;
2642 	int rc = 0;
2643 	int bytes_returned = 0;
2644 	__u16 params, param_offset, offset, byte_count;
2645 
2646 	cifs_dbg(FYI, "In Symlink Unix style\n");
2647 createSymLinkRetry:
2648 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2649 		      (void **) &pSMBr);
2650 	if (rc < 0)
2651 		return rc;
2652 	in_len = rc;
2653 
2654 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2655 		name_len =
2656 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2657 				/* find define for this maxpathcomponent */
2658 					PATH_MAX, nls_codepage, remap);
2659 		name_len++;	/* trailing null */
2660 		name_len *= 2;
2661 
2662 	} else {
2663 		name_len = copy_path_name(pSMB->FileName, fromName);
2664 	}
2665 	params = 6 + name_len;
2666 	pSMB->MaxSetupCount = 0;
2667 	pSMB->Reserved = 0;
2668 	pSMB->Flags = 0;
2669 	pSMB->Timeout = 0;
2670 	pSMB->Reserved2 = 0;
2671 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
2672 				InformationLevel);
2673 	offset = param_offset + params;
2674 
2675 	data_offset = (char *)pSMB + offset;
2676 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2677 		name_len_target =
2678 		    cifsConvertToUTF16((__le16 *) data_offset, toName,
2679 				/* find define for this maxpathcomponent */
2680 					PATH_MAX, nls_codepage, remap);
2681 		name_len_target++;	/* trailing null */
2682 		name_len_target *= 2;
2683 	} else {
2684 		name_len_target = copy_path_name(data_offset, toName);
2685 	}
2686 
2687 	pSMB->MaxParameterCount = cpu_to_le16(2);
2688 	/* BB find exact max on data count below from sess */
2689 	pSMB->MaxDataCount = cpu_to_le16(1000);
2690 	pSMB->SetupCount = 1;
2691 	pSMB->Reserved3 = 0;
2692 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2693 	byte_count = 3 /* pad */  + params + name_len_target;
2694 	pSMB->DataCount = cpu_to_le16(name_len_target);
2695 	pSMB->ParameterCount = cpu_to_le16(params);
2696 	pSMB->TotalDataCount = pSMB->DataCount;
2697 	pSMB->TotalParameterCount = pSMB->ParameterCount;
2698 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
2699 	pSMB->DataOffset = cpu_to_le16(offset);
2700 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2701 	pSMB->Reserved4 = 0;
2702 	in_len += byte_count;
2703 	pSMB->ByteCount = cpu_to_le16(byte_count);
2704 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2705 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2706 	cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2707 	if (rc)
2708 		cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2709 			 rc);
2710 
2711 	cifs_buf_release(pSMB);
2712 
2713 	if (rc == -EAGAIN)
2714 		goto createSymLinkRetry;
2715 
2716 	return rc;
2717 }
2718 
2719 int
2720 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2721 		       const char *fromName, const char *toName,
2722 		       const struct nls_table *nls_codepage, int remap)
2723 {
2724 	TRANSACTION2_SPI_REQ *pSMB = NULL;
2725 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
2726 	unsigned int in_len;
2727 	char *data_offset;
2728 	int name_len;
2729 	int name_len_target;
2730 	int rc = 0;
2731 	int bytes_returned = 0;
2732 	__u16 params, param_offset, offset, byte_count;
2733 
2734 	cifs_dbg(FYI, "In Create Hard link Unix style\n");
2735 createHardLinkRetry:
2736 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2737 		      (void **) &pSMBr);
2738 	if (rc < 0)
2739 		return rc;
2740 	in_len = rc;
2741 
2742 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2743 		name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2744 					      PATH_MAX, nls_codepage, remap);
2745 		name_len++;	/* trailing null */
2746 		name_len *= 2;
2747 
2748 	} else {
2749 		name_len = copy_path_name(pSMB->FileName, toName);
2750 	}
2751 	params = 6 + name_len;
2752 	pSMB->MaxSetupCount = 0;
2753 	pSMB->Reserved = 0;
2754 	pSMB->Flags = 0;
2755 	pSMB->Timeout = 0;
2756 	pSMB->Reserved2 = 0;
2757 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
2758 				InformationLevel);
2759 	offset = param_offset + params;
2760 
2761 	data_offset = (char *)pSMB + offset;
2762 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2763 		name_len_target =
2764 		    cifsConvertToUTF16((__le16 *) data_offset, fromName,
2765 				       PATH_MAX, nls_codepage, remap);
2766 		name_len_target++;	/* trailing null */
2767 		name_len_target *= 2;
2768 	} else {
2769 		name_len_target = copy_path_name(data_offset, fromName);
2770 	}
2771 
2772 	pSMB->MaxParameterCount = cpu_to_le16(2);
2773 	/* BB find exact max on data count below from sess*/
2774 	pSMB->MaxDataCount = cpu_to_le16(1000);
2775 	pSMB->SetupCount = 1;
2776 	pSMB->Reserved3 = 0;
2777 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2778 	byte_count = 3 /* pad */  + params + name_len_target;
2779 	pSMB->ParameterCount = cpu_to_le16(params);
2780 	pSMB->TotalParameterCount = pSMB->ParameterCount;
2781 	pSMB->DataCount = cpu_to_le16(name_len_target);
2782 	pSMB->TotalDataCount = pSMB->DataCount;
2783 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
2784 	pSMB->DataOffset = cpu_to_le16(offset);
2785 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2786 	pSMB->Reserved4 = 0;
2787 	in_len += byte_count;
2788 	pSMB->ByteCount = cpu_to_le16(byte_count);
2789 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2790 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2791 	cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2792 	if (rc)
2793 		cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
2794 			 rc);
2795 
2796 	cifs_buf_release(pSMB);
2797 	if (rc == -EAGAIN)
2798 		goto createHardLinkRetry;
2799 
2800 	return rc;
2801 }
2802 
2803 int CIFSCreateHardLink(const unsigned int xid,
2804 		       struct cifs_tcon *tcon,
2805 		       struct dentry *source_dentry,
2806 		       const char *from_name, const char *to_name,
2807 		       struct cifs_sb_info *cifs_sb)
2808 {
2809 	int rc = 0;
2810 	NT_RENAME_REQ *pSMB = NULL;
2811 	RENAME_RSP *pSMBr = NULL;
2812 	unsigned int in_len;
2813 	int bytes_returned;
2814 	int name_len, name_len2;
2815 	__u16 count;
2816 	int remap = cifs_remap(cifs_sb);
2817 
2818 	cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2819 winCreateHardLinkRetry:
2820 
2821 	rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2822 		      (void **) &pSMBr);
2823 	if (rc < 0)
2824 		return rc;
2825 	in_len = rc;
2826 
2827 	pSMB->SearchAttributes =
2828 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2829 			ATTR_DIRECTORY);
2830 	pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2831 	pSMB->ClusterCount = 0;
2832 
2833 	pSMB->BufferFormat = 0x04;
2834 
2835 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2836 		name_len =
2837 		    cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2838 				       PATH_MAX, cifs_sb->local_nls, remap);
2839 		name_len++;	/* trailing null */
2840 		name_len *= 2;
2841 
2842 		/* protocol specifies ASCII buffer format (0x04) for unicode */
2843 		pSMB->OldFileName[name_len] = 0x04;
2844 		pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2845 		name_len2 =
2846 		    cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2847 				       to_name, PATH_MAX, cifs_sb->local_nls,
2848 				       remap);
2849 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2850 		name_len2 *= 2;	/* convert to bytes */
2851 	} else {
2852 		name_len = copy_path_name(pSMB->OldFileName, from_name);
2853 		pSMB->OldFileName[name_len] = 0x04;	/* 2nd buffer format */
2854 		name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2855 		name_len2++;	/* signature byte */
2856 	}
2857 
2858 	count = 1 /* string type byte */  + name_len + name_len2;
2859 	in_len += count;
2860 	pSMB->ByteCount = cpu_to_le16(count);
2861 
2862 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2863 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2864 	cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2865 	if (rc)
2866 		cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2867 
2868 	cifs_buf_release(pSMB);
2869 	if (rc == -EAGAIN)
2870 		goto winCreateHardLinkRetry;
2871 
2872 	return rc;
2873 }
2874 
2875 int
2876 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2877 			const unsigned char *searchName, char **symlinkinfo,
2878 			const struct nls_table *nls_codepage, int remap)
2879 {
2880 /* SMB_QUERY_FILE_UNIX_LINK */
2881 	TRANSACTION2_QPI_REQ *pSMB = NULL;
2882 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
2883 	unsigned int in_len;
2884 	int rc = 0;
2885 	int bytes_returned;
2886 	int name_len;
2887 	__u16 params, byte_count;
2888 	char *data_start;
2889 
2890 	cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2891 
2892 querySymLinkRetry:
2893 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2894 		      (void **) &pSMBr);
2895 	if (rc < 0)
2896 		return rc;
2897 	in_len = rc;
2898 
2899 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2900 		name_len =
2901 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
2902 					   searchName, PATH_MAX, nls_codepage,
2903 					   remap);
2904 		name_len++;	/* trailing null */
2905 		name_len *= 2;
2906 	} else {
2907 		name_len = copy_path_name(pSMB->FileName, searchName);
2908 	}
2909 
2910 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
2911 	pSMB->TotalDataCount = 0;
2912 	pSMB->MaxParameterCount = cpu_to_le16(2);
2913 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2914 	pSMB->MaxSetupCount = 0;
2915 	pSMB->Reserved = 0;
2916 	pSMB->Flags = 0;
2917 	pSMB->Timeout = 0;
2918 	pSMB->Reserved2 = 0;
2919 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
2920 		struct smb_com_transaction2_qpi_req, InformationLevel));
2921 	pSMB->DataCount = 0;
2922 	pSMB->DataOffset = 0;
2923 	pSMB->SetupCount = 1;
2924 	pSMB->Reserved3 = 0;
2925 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2926 	byte_count = params + 1 /* pad */ ;
2927 	pSMB->TotalParameterCount = cpu_to_le16(params);
2928 	pSMB->ParameterCount = pSMB->TotalParameterCount;
2929 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2930 	pSMB->Reserved4 = 0;
2931 	in_len += byte_count;
2932 	pSMB->ByteCount = cpu_to_le16(byte_count);
2933 
2934 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
2935 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2936 	if (rc) {
2937 		cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2938 	} else {
2939 		/* decode response */
2940 
2941 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2942 		/* BB also check enough total bytes returned */
2943 		if (rc || get_bcc(&pSMBr->hdr) < 2)
2944 			rc = smb_EIO2(smb_eio_trace_qsym_bcc_too_small,
2945 				      get_bcc(&pSMBr->hdr), 2);
2946 		else {
2947 			bool is_unicode;
2948 			u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2949 
2950 			data_start = ((char *) &pSMBr->hdr.Protocol) +
2951 					   le16_to_cpu(pSMBr->t2.DataOffset);
2952 
2953 			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2954 				is_unicode = true;
2955 			else
2956 				is_unicode = false;
2957 
2958 			/* BB FIXME investigate remapping reserved chars here */
2959 			*symlinkinfo = cifs_strndup_from_utf16(data_start,
2960 					count, is_unicode, nls_codepage);
2961 			if (!*symlinkinfo)
2962 				rc = -ENOMEM;
2963 		}
2964 	}
2965 	cifs_buf_release(pSMB);
2966 	if (rc == -EAGAIN)
2967 		goto querySymLinkRetry;
2968 	return rc;
2969 }
2970 
2971 int cifs_query_reparse_point(const unsigned int xid,
2972 			     struct cifs_tcon *tcon,
2973 			     struct cifs_sb_info *cifs_sb,
2974 			     const char *full_path,
2975 			     u32 *tag, struct kvec *rsp,
2976 			     int *rsp_buftype)
2977 {
2978 	struct reparse_data_buffer *buf;
2979 	struct cifs_open_parms oparms;
2980 	TRANSACT_IOCTL_REQ *io_req = NULL;
2981 	TRANSACT_IOCTL_RSP *io_rsp = NULL;
2982 	struct cifs_fid fid;
2983 	unsigned int in_len;
2984 	__u32 data_offset, data_count, len;
2985 	__u8 *start, *end;
2986 	int io_rsp_len;
2987 	int oplock = 0;
2988 	int rc;
2989 
2990 	cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
2991 
2992 	if (cap_unix(tcon->ses))
2993 		return -EOPNOTSUPP;
2994 
2995 	if (!CIFS_REPARSE_SUPPORT(tcon))
2996 		return -EOPNOTSUPP;
2997 
2998 	oparms = (struct cifs_open_parms) {
2999 		.tcon = tcon,
3000 		.cifs_sb = cifs_sb,
3001 		.desired_access = FILE_READ_ATTRIBUTES,
3002 		.create_options = cifs_create_options(cifs_sb,
3003 						      OPEN_REPARSE_POINT),
3004 		.disposition = FILE_OPEN,
3005 		.path = full_path,
3006 		.fid = &fid,
3007 	};
3008 
3009 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
3010 	if (rc)
3011 		return rc;
3012 
3013 	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
3014 		      (void **)&io_req, (void **)&io_rsp);
3015 	if (rc < 0)
3016 		goto error;
3017 	in_len = rc;
3018 
3019 	io_req->TotalParameterCount = 0;
3020 	io_req->TotalDataCount = 0;
3021 	io_req->MaxParameterCount = cpu_to_le32(0);
3022 	/* BB find exact data count max from sess structure BB */
3023 	io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3024 	io_req->MaxSetupCount = 1;
3025 	io_req->Reserved = 0;
3026 	io_req->ParameterOffset = 0;
3027 	io_req->DataCount = 0;
3028 	io_req->DataOffset = 0;
3029 	io_req->SetupCount = 4;
3030 	io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3031 	io_req->ParameterCount = io_req->TotalParameterCount;
3032 	io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3033 	io_req->IsFsctl = 1;
3034 	io_req->IsRootFlag = 0;
3035 	io_req->Fid = fid.netfid;
3036 	io_req->ByteCount = 0;
3037 
3038 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, in_len,
3039 			 (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
3040 	if (rc)
3041 		goto error;
3042 
3043 	data_offset = le32_to_cpu(io_rsp->DataOffset);
3044 	data_count = le32_to_cpu(io_rsp->DataCount);
3045 	if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
3046 	    !data_count || data_count > 2048) {
3047 		rc = smb_EIO2(smb_eio_trace_qreparse_sizes_wrong,
3048 			      get_bcc(&io_rsp->hdr), data_count);
3049 		goto error;
3050 	}
3051 
3052 	/* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */
3053 	if (io_rsp->SetupCount != 1) {
3054 		rc = smb_EIO2(smb_eio_trace_qreparse_setup_count,
3055 			      io_rsp->SetupCount, 1);
3056 		goto error;
3057 	}
3058 
3059 	/*
3060 	 * ReturnedDataLen is output length of executed IOCTL.
3061 	 * DataCount is output length transferred over network.
3062 	 * Check that we have full FSCTL_GET_REPARSE_POINT buffer.
3063 	 */
3064 	if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) {
3065 		rc = smb_EIO2(smb_eio_trace_qreparse_ret_datalen,
3066 			      data_count, le16_to_cpu(io_rsp->ReturnedDataLen));
3067 		goto error;
3068 	}
3069 
3070 	end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
3071 	start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
3072 	if (start >= end || (size_t)(end - start) < sizeof(*buf)) {
3073 		rc = smb_EIO2(smb_eio_trace_qreparse_data_area,
3074 			      (unsigned long)start - (unsigned long)io_rsp,
3075 			      (unsigned long)end - (unsigned long)io_rsp);
3076 		goto error;
3077 	}
3078 
3079 	data_count = le16_to_cpu(io_rsp->ByteCount);
3080 	buf = (struct reparse_data_buffer *)start;
3081 	len = sizeof(*buf);
3082 	if (data_count < len ||
3083 	    data_count < le16_to_cpu(buf->ReparseDataLength) + len) {
3084 		rc = smb_EIO2(smb_eio_trace_qreparse_rep_datalen,
3085 			      data_count, le16_to_cpu(buf->ReparseDataLength) + len);
3086 		goto error;
3087 	}
3088 
3089 	*tag = le32_to_cpu(buf->ReparseTag);
3090 	rsp->iov_base = io_rsp;
3091 	rsp->iov_len = io_rsp_len;
3092 	*rsp_buftype = CIFS_LARGE_BUFFER;
3093 	CIFSSMBClose(xid, tcon, fid.netfid);
3094 	return 0;
3095 
3096 error:
3097 	cifs_buf_release(io_req);
3098 	CIFSSMBClose(xid, tcon, fid.netfid);
3099 	return rc;
3100 }
3101 
3102 struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
3103 					struct super_block *sb,
3104 					const unsigned int xid,
3105 					struct cifs_tcon *tcon,
3106 					const char *full_path,
3107 					bool directory,
3108 					struct kvec *reparse_iov,
3109 					struct kvec *xattr_iov)
3110 {
3111 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
3112 	struct cifs_open_parms oparms;
3113 	TRANSACT_IOCTL_REQ *io_req;
3114 	struct inode *new = NULL;
3115 	struct kvec in_iov[2];
3116 	struct kvec out_iov;
3117 	struct cifs_fid fid;
3118 	unsigned int in_len;
3119 	int oplock = 0;
3120 	int buf_type = 0;
3121 	int rc;
3122 
3123 	cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
3124 
3125 	/*
3126 	 * If server filesystem does not support reparse points then do not
3127 	 * attempt to create reparse point. This will prevent creating unusable
3128 	 * empty object on the server.
3129 	 */
3130 	if (!CIFS_REPARSE_SUPPORT(tcon))
3131 		return ERR_PTR(-EOPNOTSUPP);
3132 
3133 #ifndef CONFIG_CIFS_XATTR
3134 	if (xattr_iov)
3135 		return ERR_PTR(-EOPNOTSUPP);
3136 #endif
3137 
3138 	oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
3139 			     FILE_READ_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA,
3140 			     FILE_CREATE,
3141 			     (directory ? CREATE_NOT_FILE : CREATE_NOT_DIR) | OPEN_REPARSE_POINT,
3142 			     ACL_NO_MODE);
3143 	oparms.fid = &fid;
3144 
3145 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
3146 	if (rc)
3147 		return ERR_PTR(rc);
3148 
3149 #ifdef CONFIG_CIFS_XATTR
3150 	if (xattr_iov) {
3151 		struct smb2_file_full_ea_info *ea;
3152 
3153 		ea = &((struct smb2_create_ea_ctx *)xattr_iov->iov_base)->ea;
3154 		while (1) {
3155 			rc = CIFSSMBSetEA(xid,
3156 					  tcon,
3157 					  full_path,
3158 					  &ea->ea_data[0],
3159 					  &ea->ea_data[ea->ea_name_length+1],
3160 					  le16_to_cpu(ea->ea_value_length),
3161 					  cifs_sb);
3162 			if (rc)
3163 				goto out_close;
3164 			if (le32_to_cpu(ea->next_entry_offset) == 0)
3165 				break;
3166 			ea = (struct smb2_file_full_ea_info *)((u8 *)ea +
3167 				le32_to_cpu(ea->next_entry_offset));
3168 		}
3169 	}
3170 #endif
3171 
3172 	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **)&io_req, NULL);
3173 	if (rc < 0)
3174 		goto out_close;
3175 	in_len = rc;
3176 	in_len += sizeof(io_req->Pad);
3177 
3178 	/* NT IOCTL response contains one-word long output setup buffer with size of output data. */
3179 	io_req->MaxSetupCount = 1;
3180 	/* NT IOCTL response does not contain output parameters. */
3181 	io_req->MaxParameterCount = cpu_to_le32(0);
3182 	/* FSCTL_SET_REPARSE_POINT response contains empty output data. */
3183 	io_req->MaxDataCount = cpu_to_le32(0);
3184 
3185 	io_req->TotalParameterCount = cpu_to_le32(0);
3186 	io_req->TotalDataCount = cpu_to_le32(reparse_iov->iov_len);
3187 	io_req->ParameterCount = io_req->TotalParameterCount;
3188 	io_req->ParameterOffset = cpu_to_le32(0);
3189 	io_req->DataCount = io_req->TotalDataCount;
3190 	io_req->DataOffset = cpu_to_le32(offsetof(typeof(*io_req), Data));
3191 	io_req->SetupCount = 4;
3192 	io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3193 	io_req->FunctionCode = cpu_to_le32(FSCTL_SET_REPARSE_POINT);
3194 	io_req->Fid = fid.netfid;
3195 	io_req->IsFsctl = 1;
3196 	io_req->IsRootFlag = 0;
3197 	io_req->ByteCount = cpu_to_le16(le32_to_cpu(io_req->DataCount) + sizeof(io_req->Pad));
3198 
3199 	in_iov[0].iov_base = (char *)io_req;
3200 	in_iov[0].iov_len = in_len;
3201 	in_iov[1] = *reparse_iov;
3202 	rc = SendReceive2(xid, tcon->ses, in_iov, ARRAY_SIZE(in_iov), &buf_type,
3203 			  CIFS_NO_RSP_BUF, &out_iov);
3204 
3205 	cifs_buf_release(io_req);
3206 
3207 	if (!rc)
3208 		rc = cifs_get_inode_info(&new, full_path, data, sb, xid, NULL);
3209 
3210 out_close:
3211 	CIFSSMBClose(xid, tcon, fid.netfid);
3212 
3213 	/*
3214 	 * If CREATE was successful but FSCTL_SET_REPARSE_POINT failed then
3215 	 * remove the intermediate object created by CREATE. Otherwise
3216 	 * empty object stay on the server when reparse call failed.
3217 	 */
3218 	if (rc)
3219 		CIFSSMBDelFile(xid, tcon, full_path, cifs_sb, NULL);
3220 
3221 	return rc ? ERR_PTR(rc) : new;
3222 }
3223 
3224 int
3225 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3226 		    __u16 fid, __u16 compression_state)
3227 {
3228 	int rc = 0;
3229 	int bytes_returned;
3230 	struct smb_com_transaction_compr_ioctl_req *pSMB;
3231 	struct smb_com_transaction_ioctl_rsp *pSMBr;
3232 	unsigned int in_len;
3233 
3234 	cifs_dbg(FYI, "Set compression for %u\n", fid);
3235 	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3236 		      (void **) &pSMBr);
3237 	if (rc < 0)
3238 		return rc;
3239 	in_len = rc;
3240 
3241 	pSMB->compression_state = cpu_to_le16(compression_state);
3242 
3243 	pSMB->TotalParameterCount = 0;
3244 	pSMB->TotalDataCount = cpu_to_le32(2);
3245 	pSMB->MaxParameterCount = 0;
3246 	pSMB->MaxDataCount = 0;
3247 	pSMB->MaxSetupCount = 4;
3248 	pSMB->Reserved = 0;
3249 	pSMB->ParameterOffset = 0;
3250 	pSMB->DataCount = cpu_to_le32(2);
3251 	pSMB->DataOffset =
3252 		cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3253 				     compression_state));  /* 84 */
3254 	pSMB->SetupCount = 4;
3255 	pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3256 	pSMB->ParameterCount = 0;
3257 	pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3258 	pSMB->IsFsctl = 1; /* FSCTL */
3259 	pSMB->IsRootFlag = 0;
3260 	pSMB->Fid = fid; /* file handle always le */
3261 	/* 3 byte pad, followed by 2 byte compress state */
3262 	pSMB->ByteCount = cpu_to_le16(5);
3263 	in_len += 5;
3264 
3265 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3266 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3267 	if (rc)
3268 		cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3269 
3270 	cifs_buf_release(pSMB);
3271 
3272 	/*
3273 	 * Note: On -EAGAIN error only caller can retry on handle based calls
3274 	 * since file handle passed in no longer valid.
3275 	 */
3276 	return rc;
3277 }
3278 
3279 
3280 #ifdef CONFIG_CIFS_POSIX
3281 
3282 #ifdef CONFIG_FS_POSIX_ACL
3283 /**
3284  * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
3285  * @ace: POSIX ACL entry to store converted ACL into
3286  * @cifs_ace: ACL in cifs format
3287  *
3288  * Convert an Access Control Entry from wire format to local POSIX xattr
3289  * format.
3290  *
3291  * Note that the @cifs_uid member is used to store both {g,u}id_t.
3292  */
3293 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
3294 				struct cifs_posix_ace *cifs_ace)
3295 {
3296 	/* u8 cifs fields do not need le conversion */
3297 	ace->e_perm = cifs_ace->cifs_e_perm;
3298 	ace->e_tag = cifs_ace->cifs_e_tag;
3299 
3300 	switch (ace->e_tag) {
3301 	case ACL_USER:
3302 		ace->e_uid = make_kuid(&init_user_ns,
3303 				       le64_to_cpu(cifs_ace->cifs_uid));
3304 		break;
3305 	case ACL_GROUP:
3306 		ace->e_gid = make_kgid(&init_user_ns,
3307 				       le64_to_cpu(cifs_ace->cifs_uid));
3308 		break;
3309 	}
3310 	return;
3311 }
3312 
3313 /**
3314  * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
3315  * @acl: ACLs returned in POSIX ACL format
3316  * @src: ACLs in cifs format
3317  * @acl_type: type of POSIX ACL requested
3318  * @size_of_data_area: size of SMB we got
3319  *
3320  * This function converts ACLs from cifs format to POSIX ACL format.
3321  * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
3322  * their uapi format is returned.
3323  */
3324 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
3325 			     const int acl_type, const int size_of_data_area)
3326 {
3327 	int size =  0;
3328 	__u16 count;
3329 	struct cifs_posix_ace *pACE;
3330 	struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3331 	struct posix_acl *kacl = NULL;
3332 	struct posix_acl_entry *pa, *pe;
3333 
3334 	if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3335 		return -EOPNOTSUPP;
3336 
3337 	if (acl_type == ACL_TYPE_ACCESS) {
3338 		count = le16_to_cpu(cifs_acl->access_entry_count);
3339 		pACE = &cifs_acl->ace_array[0];
3340 		size = sizeof(struct cifs_posix_acl);
3341 		size += sizeof(struct cifs_posix_ace) * count;
3342 		/* check if we would go beyond end of SMB */
3343 		if (size_of_data_area < size) {
3344 			cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3345 				 size_of_data_area, size);
3346 			return -EINVAL;
3347 		}
3348 	} else if (acl_type == ACL_TYPE_DEFAULT) {
3349 		count = le16_to_cpu(cifs_acl->access_entry_count);
3350 		size = sizeof(struct cifs_posix_acl);
3351 		size += sizeof(struct cifs_posix_ace) * count;
3352 		/* skip past access ACEs to get to default ACEs */
3353 		pACE = &cifs_acl->ace_array[count];
3354 		count = le16_to_cpu(cifs_acl->default_entry_count);
3355 		size += sizeof(struct cifs_posix_ace) * count;
3356 		/* check if we would go beyond end of SMB */
3357 		if (size_of_data_area < size)
3358 			return -EINVAL;
3359 	} else {
3360 		/* illegal type */
3361 		return -EINVAL;
3362 	}
3363 
3364 	/* Allocate number of POSIX ACLs to store in VFS format. */
3365 	kacl = posix_acl_alloc(count, GFP_NOFS);
3366 	if (!kacl)
3367 		return -ENOMEM;
3368 
3369 	FOREACH_ACL_ENTRY(pa, kacl, pe) {
3370 		cifs_init_posix_acl(pa, pACE);
3371 		pACE++;
3372 	}
3373 
3374 	*acl = kacl;
3375 	return 0;
3376 }
3377 
3378 /**
3379  * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
3380  * @cifs_ace: the cifs ACL entry to store into
3381  * @local_ace: the POSIX ACL entry to convert
3382  */
3383 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
3384 			  const struct posix_acl_entry *local_ace)
3385 {
3386 	cifs_ace->cifs_e_perm = local_ace->e_perm;
3387 	cifs_ace->cifs_e_tag =  local_ace->e_tag;
3388 
3389 	switch (local_ace->e_tag) {
3390 	case ACL_USER:
3391 		cifs_ace->cifs_uid =
3392 			cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
3393 		break;
3394 	case ACL_GROUP:
3395 		cifs_ace->cifs_uid =
3396 			cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
3397 		break;
3398 	default:
3399 		cifs_ace->cifs_uid = cpu_to_le64(-1);
3400 	}
3401 }
3402 
3403 /**
3404  * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
3405  * @parm_data: ACLs in cifs format to convert to
3406  * @acl: ACLs in POSIX ACL format to convert from
3407  * @acl_type: the type of POSIX ACLs stored in @acl
3408  *
3409  * Return: the number cifs ACL entries after conversion
3410  */
3411 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
3412 			       const int acl_type)
3413 {
3414 	__u16 rc = 0;
3415 	struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3416 	const struct posix_acl_entry *pa, *pe;
3417 	int count;
3418 	int i = 0;
3419 
3420 	if ((acl == NULL) || (cifs_acl == NULL))
3421 		return 0;
3422 
3423 	count = acl->a_count;
3424 	cifs_dbg(FYI, "setting acl with %d entries\n", count);
3425 
3426 	/*
3427 	 * Note that the uapi POSIX ACL version is verified by the VFS and is
3428 	 * independent of the cifs ACL version. Changing the POSIX ACL version
3429 	 * is a uapi change and if it's changed we will pass down the POSIX ACL
3430 	 * version in struct posix_acl from the VFS. For now there's really
3431 	 * only one that all filesystems know how to deal with.
3432 	 */
3433 	cifs_acl->version = cpu_to_le16(1);
3434 	if (acl_type == ACL_TYPE_ACCESS) {
3435 		cifs_acl->access_entry_count = cpu_to_le16(count);
3436 		cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3437 	} else if (acl_type == ACL_TYPE_DEFAULT) {
3438 		cifs_acl->default_entry_count = cpu_to_le16(count);
3439 		cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3440 	} else {
3441 		cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3442 		return 0;
3443 	}
3444 	FOREACH_ACL_ENTRY(pa, acl, pe) {
3445 		cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3446 	}
3447 	if (rc == 0) {
3448 		rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3449 		rc += sizeof(struct cifs_posix_acl);
3450 		/* BB add check to make sure ACL does not overflow SMB */
3451 	}
3452 	return rc;
3453 }
3454 
3455 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3456 		    const unsigned char *searchName, struct posix_acl **acl,
3457 		    const int acl_type, const struct nls_table *nls_codepage,
3458 		    int remap)
3459 {
3460 /* SMB_QUERY_POSIX_ACL */
3461 	TRANSACTION2_QPI_REQ *pSMB = NULL;
3462 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
3463 	unsigned int in_len;
3464 	int rc = 0;
3465 	int bytes_returned;
3466 	int name_len;
3467 	__u16 params, byte_count;
3468 
3469 	cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3470 
3471 queryAclRetry:
3472 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3473 		(void **) &pSMBr);
3474 	if (rc < 0)
3475 		return rc;
3476 	in_len = rc;
3477 
3478 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3479 		name_len =
3480 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
3481 					   searchName, PATH_MAX, nls_codepage,
3482 					   remap);
3483 		name_len++;     /* trailing null */
3484 		name_len *= 2;
3485 		pSMB->FileName[name_len] = 0;
3486 		pSMB->FileName[name_len+1] = 0;
3487 	} else {
3488 		name_len = copy_path_name(pSMB->FileName, searchName);
3489 	}
3490 
3491 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3492 	pSMB->TotalDataCount = 0;
3493 	pSMB->MaxParameterCount = cpu_to_le16(2);
3494 	/* BB find exact max data count below from sess structure BB */
3495 	pSMB->MaxDataCount = cpu_to_le16(4000);
3496 	pSMB->MaxSetupCount = 0;
3497 	pSMB->Reserved = 0;
3498 	pSMB->Flags = 0;
3499 	pSMB->Timeout = 0;
3500 	pSMB->Reserved2 = 0;
3501 	pSMB->ParameterOffset = cpu_to_le16(
3502 		offsetof(struct smb_com_transaction2_qpi_req,
3503 			 InformationLevel));
3504 	pSMB->DataCount = 0;
3505 	pSMB->DataOffset = 0;
3506 	pSMB->SetupCount = 1;
3507 	pSMB->Reserved3 = 0;
3508 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3509 	byte_count = params + 1 /* pad */ ;
3510 	pSMB->TotalParameterCount = cpu_to_le16(params);
3511 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3512 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3513 	pSMB->Reserved4 = 0;
3514 	in_len += byte_count;
3515 	pSMB->ByteCount = cpu_to_le16(byte_count);
3516 
3517 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3518 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
3519 	cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3520 	if (rc) {
3521 		cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3522 	} else {
3523 		/* decode response */
3524 
3525 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3526 		/* BB also check enough total bytes returned */
3527 		if (rc || get_bcc(&pSMBr->hdr) < 2)
3528 			rc = smb_EIO2(smb_eio_trace_getacl_bcc_too_small,
3529 				      get_bcc(&pSMBr->hdr), 2);
3530 		else {
3531 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3532 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3533 			rc = cifs_to_posix_acl(acl,
3534 				(char *)&pSMBr->hdr.Protocol+data_offset,
3535 				acl_type, count);
3536 		}
3537 	}
3538 	cifs_buf_release(pSMB);
3539 	/*
3540 	 * The else branch after SendReceive() doesn't return EAGAIN so if we
3541 	 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3542 	 * here and don't leak POSIX ACLs.
3543 	 */
3544 	if (rc == -EAGAIN)
3545 		goto queryAclRetry;
3546 	return rc;
3547 }
3548 
3549 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3550 		    const unsigned char *fileName, const struct posix_acl *acl,
3551 		    const int acl_type, const struct nls_table *nls_codepage,
3552 		    int remap)
3553 {
3554 	struct smb_com_transaction2_spi_req *pSMB = NULL;
3555 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3556 	unsigned int in_len;
3557 	char *parm_data;
3558 	int name_len;
3559 	int rc = 0;
3560 	int bytes_returned = 0;
3561 	__u16 params, byte_count, data_count, param_offset, offset;
3562 	size_t cifs_acl_size, bytes_available;
3563 
3564 	cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3565 setAclRetry:
3566 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3567 		      (void **) &pSMBr);
3568 	if (rc < 0)
3569 		return rc;
3570 	in_len = rc;
3571 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3572 		name_len =
3573 			cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3574 					   PATH_MAX, nls_codepage, remap);
3575 		name_len++;     /* trailing null */
3576 		name_len *= 2;
3577 	} else {
3578 		name_len = copy_path_name(pSMB->FileName, fileName);
3579 	}
3580 	params = 6 + name_len;
3581 	pSMB->MaxParameterCount = cpu_to_le16(2);
3582 	pSMB->MaxDataCount = cpu_to_le16(min_t(unsigned int, CIFSMaxBufSize, USHRT_MAX));
3583 	pSMB->MaxSetupCount = 0;
3584 	pSMB->Reserved = 0;
3585 	pSMB->Flags = 0;
3586 	pSMB->Timeout = 0;
3587 	pSMB->Reserved2 = 0;
3588 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
3589 				InformationLevel);
3590 	offset = param_offset + params;
3591 	parm_data = ((char *)pSMB) + offset;
3592 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
3593 
3594 	/* make sure we can fit the larger cifs_posix_aces in the buffer */
3595 	cifs_acl_size = sizeof(struct cifs_posix_acl) +
3596 		       (acl->a_count * sizeof(struct cifs_posix_ace));
3597 	bytes_available = (CIFSMaxBufSize + MAX_HEADER_SIZE(tcon->ses->server)) - offset;
3598 	if (cifs_acl_size > bytes_available || cifs_acl_size > USHRT_MAX) {
3599 		rc = -E2BIG;
3600 		goto setACLerrorExit;
3601 	}
3602 
3603 	/* convert to on the wire format for POSIX ACL */
3604 	data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3605 
3606 	if (data_count == 0) {
3607 		rc = -EOPNOTSUPP;
3608 		goto setACLerrorExit;
3609 	}
3610 	pSMB->DataOffset = cpu_to_le16(offset);
3611 	pSMB->SetupCount = 1;
3612 	pSMB->Reserved3 = 0;
3613 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3614 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3615 	byte_count = 3 /* pad */  + params + data_count;
3616 	pSMB->DataCount = cpu_to_le16(data_count);
3617 	pSMB->TotalDataCount = pSMB->DataCount;
3618 	pSMB->ParameterCount = cpu_to_le16(params);
3619 	pSMB->TotalParameterCount = pSMB->ParameterCount;
3620 	pSMB->Reserved4 = 0;
3621 	in_len += byte_count;
3622 	pSMB->ByteCount = cpu_to_le16(byte_count);
3623 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3624 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3625 	if (rc)
3626 		cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3627 
3628 setACLerrorExit:
3629 	cifs_buf_release(pSMB);
3630 	if (rc == -EAGAIN)
3631 		goto setAclRetry;
3632 	return rc;
3633 }
3634 #else
3635 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3636 		    const unsigned char *searchName, struct posix_acl **acl,
3637 		    const int acl_type, const struct nls_table *nls_codepage,
3638 		    int remap)
3639 {
3640 	return -EOPNOTSUPP;
3641 }
3642 
3643 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3644 		    const unsigned char *fileName, const struct posix_acl *acl,
3645 		    const int acl_type, const struct nls_table *nls_codepage,
3646 		    int remap)
3647 {
3648 	return -EOPNOTSUPP;
3649 }
3650 #endif /* CONFIG_FS_POSIX_ACL */
3651 
3652 int
3653 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3654 	       const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3655 {
3656 	int rc = 0;
3657 	struct smb_t2_qfi_req *pSMB = NULL;
3658 	struct smb_t2_qfi_rsp *pSMBr = NULL;
3659 	unsigned int in_len;
3660 	int bytes_returned;
3661 	__u16 params, byte_count;
3662 
3663 	cifs_dbg(FYI, "In GetExtAttr\n");
3664 	if (tcon == NULL)
3665 		return -ENODEV;
3666 
3667 GetExtAttrRetry:
3668 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3669 		      (void **) &pSMBr);
3670 	if (rc < 0)
3671 		return rc;
3672 	in_len = rc;
3673 
3674 	params = 2 /* level */ + 2 /* fid */;
3675 	pSMB->t2.TotalDataCount = 0;
3676 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3677 	/* BB find exact max data count below from sess structure BB */
3678 	pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3679 	pSMB->t2.MaxSetupCount = 0;
3680 	pSMB->t2.Reserved = 0;
3681 	pSMB->t2.Flags = 0;
3682 	pSMB->t2.Timeout = 0;
3683 	pSMB->t2.Reserved2 = 0;
3684 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3685 					       Fid));
3686 	pSMB->t2.DataCount = 0;
3687 	pSMB->t2.DataOffset = 0;
3688 	pSMB->t2.SetupCount = 1;
3689 	pSMB->t2.Reserved3 = 0;
3690 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3691 	byte_count = params + 1 /* pad */ ;
3692 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3693 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3694 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3695 	pSMB->Pad = 0;
3696 	pSMB->Fid = netfid;
3697 	in_len += byte_count;
3698 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3699 
3700 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3701 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3702 	if (rc) {
3703 		cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3704 	} else {
3705 		/* decode response */
3706 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3707 		/* BB also check enough total bytes returned */
3708 		if (rc || get_bcc(&pSMBr->hdr) < 2)
3709 			/* If rc should we check for EOPNOSUPP and
3710 			   disable the srvino flag? or in caller? */
3711 			rc = smb_EIO2(smb_eio_trace_getextattr_bcc_too_small,
3712 				      get_bcc(&pSMBr->hdr), 2);
3713 		else {
3714 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3715 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3716 			struct file_chattr_info *pfinfo;
3717 
3718 			if (count != 16) {
3719 				cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3720 				rc = smb_EIO2(smb_eio_trace_getextattr_inv_size,
3721 					      count, 16);
3722 				goto GetExtAttrOut;
3723 			}
3724 			pfinfo = (struct file_chattr_info *)
3725 				 (data_offset + (char *) &pSMBr->hdr.Protocol);
3726 			*pExtAttrBits = le64_to_cpu(pfinfo->mode);
3727 			*pMask = le64_to_cpu(pfinfo->mask);
3728 		}
3729 	}
3730 GetExtAttrOut:
3731 	cifs_buf_release(pSMB);
3732 	if (rc == -EAGAIN)
3733 		goto GetExtAttrRetry;
3734 	return rc;
3735 }
3736 
3737 #endif /* CONFIG_POSIX */
3738 
3739 /*
3740  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3741  * all NT TRANSACTS that we init here have total parm and data under about 400
3742  * bytes (to fit in small cifs buffer size), which is the case so far, it
3743  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3744  * returned setup area) and MaxParameterCount (returned parms size) must be set
3745  * by caller
3746  */
3747 static int
3748 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3749 		   const int parm_len, struct cifs_tcon *tcon,
3750 		   void **ret_buf)
3751 {
3752 	int rc;
3753 	__u32 temp_offset;
3754 	struct smb_com_ntransact_req *pSMB;
3755 	unsigned int in_len;
3756 
3757 	rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3758 				(void **)&pSMB);
3759 	if (rc < 0)
3760 		return rc;
3761 	in_len = rc;
3762 	*ret_buf = (void *)pSMB;
3763 	pSMB->Reserved = 0;
3764 	pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3765 	pSMB->TotalDataCount  = 0;
3766 	pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3767 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3768 	pSMB->DataCount  = pSMB->TotalDataCount;
3769 	temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3770 		(setup_count * 2);
3771 	pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3772 	pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3773 	pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3774 	pSMB->SubCommand = cpu_to_le16(sub_command);
3775 	return in_len;
3776 }
3777 
3778 static int
3779 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3780 		   __u32 *pparmlen, __u32 *pdatalen)
3781 {
3782 	char *end_of_smb;
3783 	__u32 data_count, data_offset, parm_count, parm_offset;
3784 	struct smb_com_ntransact_rsp *pSMBr;
3785 	u16 bcc;
3786 
3787 	*pdatalen = 0;
3788 	*pparmlen = 0;
3789 
3790 	if (buf == NULL)
3791 		return -EINVAL;
3792 
3793 	pSMBr = (struct smb_com_ntransact_rsp *)buf;
3794 
3795 	bcc = get_bcc(&pSMBr->hdr);
3796 	end_of_smb = 2 /* sizeof byte count */ + bcc +
3797 			(char *)&pSMBr->ByteCount;
3798 
3799 	data_offset = le32_to_cpu(pSMBr->DataOffset);
3800 	data_count = le32_to_cpu(pSMBr->DataCount);
3801 	parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3802 	parm_count = le32_to_cpu(pSMBr->ParameterCount);
3803 
3804 	*ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3805 	*ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3806 
3807 	/* should we also check that parm and data areas do not overlap? */
3808 	if (*ppparm > end_of_smb) {
3809 		cifs_dbg(FYI, "parms start after end of smb\n");
3810 		return -EINVAL;
3811 	} else if (parm_count + *ppparm > end_of_smb) {
3812 		cifs_dbg(FYI, "parm end after end of smb\n");
3813 		return -EINVAL;
3814 	} else if (*ppdata > end_of_smb) {
3815 		cifs_dbg(FYI, "data starts after end of smb\n");
3816 		return -EINVAL;
3817 	} else if (data_count + *ppdata > end_of_smb) {
3818 		cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3819 			 *ppdata, data_count, (data_count + *ppdata),
3820 			 end_of_smb, pSMBr);
3821 		return -EINVAL;
3822 	} else if (parm_count + data_count > bcc) {
3823 		cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3824 		return -EINVAL;
3825 	}
3826 	*pdatalen = data_count;
3827 	*pparmlen = parm_count;
3828 	return 0;
3829 }
3830 
3831 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3832 int
3833 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3834 		  struct smb_ntsd **acl_inf, __u32 *pbuflen, __u32 info)
3835 {
3836 	int rc = 0;
3837 	int buf_type = 0;
3838 	QUERY_SEC_DESC_REQ *pSMB;
3839 	struct kvec iov[1];
3840 	struct kvec rsp_iov;
3841 	unsigned int in_len;
3842 
3843 	cifs_dbg(FYI, "GetCifsACL\n");
3844 
3845 	*pbuflen = 0;
3846 	*acl_inf = NULL;
3847 
3848 	rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3849 			8 /* parm len */, tcon, (void **) &pSMB);
3850 	if (rc < 0)
3851 		return rc;
3852 	in_len = rc;
3853 
3854 	pSMB->MaxParameterCount = cpu_to_le32(4);
3855 	/* BB TEST with big acls that might need to be e.g. larger than 16K */
3856 	pSMB->MaxSetupCount = 0;
3857 	pSMB->Fid = fid; /* file handle always le */
3858 	pSMB->AclFlags = cpu_to_le32(info);
3859 	pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3860 	in_len += 11;
3861 	iov[0].iov_base = (char *)pSMB;
3862 	iov[0].iov_len = in_len;
3863 
3864 	rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3865 			  0, &rsp_iov);
3866 	cifs_small_buf_release(pSMB);
3867 	cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3868 	if (rc) {
3869 		cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3870 	} else {                /* decode response */
3871 		__le32 *parm;
3872 		__u32 parm_len;
3873 		__u32 acl_len;
3874 		struct smb_com_ntransact_rsp *pSMBr;
3875 		char *pdata;
3876 
3877 /* validate_nttransact */
3878 		rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3879 					&pdata, &parm_len, pbuflen);
3880 		if (rc)
3881 			goto qsec_out;
3882 		pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3883 
3884 		cifs_dbg(FYI, "smb %p parm %p data %p\n",
3885 			 pSMBr, parm, *acl_inf);
3886 
3887 		if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3888 			rc = smb_EIO2(smb_eio_trace_getcifsacl_param_count,
3889 				      le32_to_cpu(pSMBr->ParameterCount), 4);
3890 			*pbuflen = 0;
3891 			goto qsec_out;
3892 		}
3893 
3894 /* BB check that data area is minimum length and as big as acl_len */
3895 
3896 		acl_len = le32_to_cpu(*parm);
3897 		if (acl_len != *pbuflen) {
3898 			cifs_dbg(VFS, "acl length %d does not match %d\n",
3899 				 acl_len, *pbuflen);
3900 			if (*pbuflen > acl_len)
3901 				*pbuflen = acl_len;
3902 		}
3903 
3904 		/* check if buffer is big enough for the acl
3905 		   header followed by the smallest SID */
3906 		if ((*pbuflen < sizeof(struct smb_ntsd) + 8) ||
3907 		    (*pbuflen >= 64 * 1024)) {
3908 			cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3909 			rc = -EINVAL;
3910 			*pbuflen = 0;
3911 		} else {
3912 			*acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3913 			if (*acl_inf == NULL) {
3914 				*pbuflen = 0;
3915 				rc = -ENOMEM;
3916 			}
3917 		}
3918 	}
3919 qsec_out:
3920 	free_rsp_buf(buf_type, rsp_iov.iov_base);
3921 	return rc;
3922 }
3923 
3924 int
3925 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3926 			struct smb_ntsd *pntsd, __u32 acllen, int aclflag)
3927 {
3928 	__u16 byte_count, param_count, data_count, param_offset, data_offset;
3929 	int rc = 0;
3930 	int bytes_returned = 0;
3931 	SET_SEC_DESC_REQ *pSMB = NULL;
3932 	unsigned int in_len;
3933 	void *pSMBr;
3934 
3935 setCifsAclRetry:
3936 	rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3937 	if (rc < 0)
3938 		return rc;
3939 	in_len = rc;
3940 
3941 	pSMB->MaxSetupCount = 0;
3942 	pSMB->Reserved = 0;
3943 
3944 	param_count = 8;
3945 	param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid);
3946 	data_count = acllen;
3947 	data_offset = param_offset + param_count;
3948 	byte_count = 3 /* pad */  + param_count;
3949 
3950 	pSMB->DataCount = cpu_to_le32(data_count);
3951 	pSMB->TotalDataCount = pSMB->DataCount;
3952 	pSMB->MaxParameterCount = cpu_to_le32(4);
3953 	pSMB->MaxDataCount = cpu_to_le32(16384);
3954 	pSMB->ParameterCount = cpu_to_le32(param_count);
3955 	pSMB->ParameterOffset = cpu_to_le32(param_offset);
3956 	pSMB->TotalParameterCount = pSMB->ParameterCount;
3957 	pSMB->DataOffset = cpu_to_le32(data_offset);
3958 	pSMB->SetupCount = 0;
3959 	pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3960 	pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3961 
3962 	pSMB->Fid = fid; /* file handle always le */
3963 	pSMB->Reserved2 = 0;
3964 	pSMB->AclFlags = cpu_to_le32(aclflag);
3965 
3966 	if (pntsd && acllen) {
3967 		memcpy((char *)pSMBr + data_offset, pntsd, acllen);
3968 		in_len += byte_count + data_count;
3969 	} else
3970 		in_len += byte_count;
3971 
3972 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
3973 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
3974 
3975 	cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3976 		 bytes_returned, rc);
3977 	if (rc)
3978 		cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3979 	cifs_buf_release(pSMB);
3980 
3981 	if (rc == -EAGAIN)
3982 		goto setCifsAclRetry;
3983 
3984 	return (rc);
3985 }
3986 
3987 
3988 /* Legacy Query Path Information call for lookup to old servers such
3989    as Win9x/WinME */
3990 int
3991 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3992 		    const char *search_name, FILE_ALL_INFO *data,
3993 		    const struct nls_table *nls_codepage, int remap)
3994 {
3995 	QUERY_INFORMATION_REQ *pSMB;
3996 	QUERY_INFORMATION_RSP *pSMBr;
3997 	unsigned int in_len;
3998 	int rc = 0;
3999 	int bytes_returned;
4000 	int name_len;
4001 
4002 	cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4003 QInfRetry:
4004 	rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4005 		      (void **) &pSMBr);
4006 	if (rc < 0)
4007 		return rc;
4008 	in_len = rc;
4009 
4010 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4011 		name_len =
4012 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
4013 					   search_name, PATH_MAX, nls_codepage,
4014 					   remap);
4015 		name_len++;     /* trailing null */
4016 		name_len *= 2;
4017 	} else {
4018 		name_len = copy_path_name(pSMB->FileName, search_name);
4019 	}
4020 	pSMB->BufferFormat = 0x04;
4021 	name_len++; /* account for buffer type byte */
4022 	in_len += name_len;
4023 	pSMB->ByteCount = cpu_to_le16(name_len);
4024 
4025 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4026 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4027 	if (rc) {
4028 		cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4029 	} else if (data) {
4030 		struct timespec64 ts;
4031 		__u32 time = le32_to_cpu(pSMBr->last_write_time);
4032 
4033 		/* decode response */
4034 		/* BB FIXME - add time zone adjustment BB */
4035 		memset(data, 0, sizeof(FILE_ALL_INFO));
4036 		ts.tv_nsec = 0;
4037 		ts.tv_sec = time;
4038 		/* decode time fields */
4039 		data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4040 		data->LastWriteTime = data->ChangeTime;
4041 		data->LastAccessTime = 0;
4042 		data->AllocationSize =
4043 			cpu_to_le64(le32_to_cpu(pSMBr->size));
4044 		data->EndOfFile = data->AllocationSize;
4045 		data->Attributes =
4046 			cpu_to_le32(le16_to_cpu(pSMBr->attr));
4047 	} else {
4048 		/* bad buffer passed in */
4049 		rc = smb_EIO(smb_eio_trace_null_pointers);
4050 	}
4051 
4052 	cifs_buf_release(pSMB);
4053 
4054 	if (rc == -EAGAIN)
4055 		goto QInfRetry;
4056 
4057 	return rc;
4058 }
4059 
4060 int
4061 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4062 		 u16 netfid, FILE_ALL_INFO *pFindData)
4063 {
4064 	struct smb_t2_qfi_req *pSMB = NULL;
4065 	struct smb_t2_qfi_rsp *pSMBr = NULL;
4066 	unsigned int in_len;
4067 	int rc = 0;
4068 	int bytes_returned;
4069 	__u16 params, byte_count;
4070 
4071 QFileInfoRetry:
4072 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4073 		      (void **) &pSMBr);
4074 	if (rc < 0)
4075 		return rc;
4076 	in_len = rc;
4077 
4078 	params = 2 /* level */ + 2 /* fid */;
4079 	pSMB->t2.TotalDataCount = 0;
4080 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4081 	/* BB find exact max data count below from sess structure BB */
4082 	pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4083 	pSMB->t2.MaxSetupCount = 0;
4084 	pSMB->t2.Reserved = 0;
4085 	pSMB->t2.Flags = 0;
4086 	pSMB->t2.Timeout = 0;
4087 	pSMB->t2.Reserved2 = 0;
4088 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4089 					       Fid));
4090 	pSMB->t2.DataCount = 0;
4091 	pSMB->t2.DataOffset = 0;
4092 	pSMB->t2.SetupCount = 1;
4093 	pSMB->t2.Reserved3 = 0;
4094 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4095 	byte_count = params + 1 /* pad */ ;
4096 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4097 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4098 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4099 	pSMB->Pad = 0;
4100 	pSMB->Fid = netfid;
4101 	in_len += byte_count;
4102 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4103 
4104 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4105 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4106 	if (rc) {
4107 		cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4108 	} else {		/* decode response */
4109 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4110 
4111 		if (rc) /* BB add auto retry on EOPNOTSUPP? */
4112 			rc = smb_EIO2(smb_eio_trace_qfileinfo_invalid,
4113 				      get_bcc(&pSMBr->hdr), 40);
4114 		else if (get_bcc(&pSMBr->hdr) < 40)
4115 			rc = smb_EIO2(smb_eio_trace_qfileinfo_bcc_too_small,
4116 				      get_bcc(&pSMBr->hdr), 40);
4117 		else if (pFindData) {
4118 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4119 			memcpy((char *) pFindData,
4120 			       (char *) &pSMBr->hdr.Protocol +
4121 			       data_offset, sizeof(FILE_ALL_INFO));
4122 		} else
4123 		    rc = -ENOMEM;
4124 	}
4125 	cifs_buf_release(pSMB);
4126 	if (rc == -EAGAIN)
4127 		goto QFileInfoRetry;
4128 
4129 	return rc;
4130 }
4131 
4132 int
4133 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4134 		 const char *search_name, FILE_ALL_INFO *data,
4135 		 int legacy /* old style infolevel */,
4136 		 const struct nls_table *nls_codepage, int remap)
4137 {
4138 	/* level 263 SMB_QUERY_FILE_ALL_INFO */
4139 	TRANSACTION2_QPI_REQ *pSMB = NULL;
4140 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
4141 	unsigned int in_len;
4142 	int rc = 0;
4143 	int bytes_returned;
4144 	int name_len;
4145 	__u16 params, byte_count;
4146 
4147 QPathInfoRetry:
4148 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4149 		      (void **) &pSMBr);
4150 	if (rc < 0)
4151 		return rc;
4152 	in_len = rc;
4153 
4154 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4155 		name_len =
4156 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4157 				       PATH_MAX, nls_codepage, remap);
4158 		name_len++;	/* trailing null */
4159 		name_len *= 2;
4160 	} else {
4161 		name_len = copy_path_name(pSMB->FileName, search_name);
4162 	}
4163 
4164 	params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4165 	pSMB->TotalDataCount = 0;
4166 	pSMB->MaxParameterCount = cpu_to_le16(2);
4167 	/* BB find exact max SMB PDU from sess structure BB */
4168 	pSMB->MaxDataCount = cpu_to_le16(4000);
4169 	pSMB->MaxSetupCount = 0;
4170 	pSMB->Reserved = 0;
4171 	pSMB->Flags = 0;
4172 	pSMB->Timeout = 0;
4173 	pSMB->Reserved2 = 0;
4174 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4175 		struct smb_com_transaction2_qpi_req, InformationLevel));
4176 	pSMB->DataCount = 0;
4177 	pSMB->DataOffset = 0;
4178 	pSMB->SetupCount = 1;
4179 	pSMB->Reserved3 = 0;
4180 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4181 	byte_count = params + 1 /* pad */ ;
4182 	pSMB->TotalParameterCount = cpu_to_le16(params);
4183 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4184 	if (legacy)
4185 		pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4186 	else
4187 		pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4188 	pSMB->Reserved4 = 0;
4189 	in_len += byte_count;
4190 	pSMB->ByteCount = cpu_to_le16(byte_count);
4191 
4192 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4193 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4194 	if (rc) {
4195 		cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4196 	} else {		/* decode response */
4197 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4198 
4199 		if (rc) /* BB add auto retry on EOPNOTSUPP? */
4200 			rc = smb_EIO2(smb_eio_trace_qpathinfo_invalid,
4201 				      get_bcc(&pSMBr->hdr), 40);
4202 		else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4203 			rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
4204 				      get_bcc(&pSMBr->hdr), 40);
4205 		else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4206 			/* 24 or 26 expected but we do not read last field */
4207 			rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
4208 				      get_bcc(&pSMBr->hdr), 24);
4209 		else if (data) {
4210 			int size;
4211 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4212 
4213 			/*
4214 			 * On legacy responses we do not read the last field,
4215 			 * EAsize, fortunately since it varies by subdialect and
4216 			 * also note it differs on Set vs Get, ie two bytes or 4
4217 			 * bytes depending but we don't care here.
4218 			 */
4219 			if (legacy)
4220 				size = sizeof(FILE_INFO_STANDARD);
4221 			else
4222 				size = sizeof(FILE_ALL_INFO);
4223 			memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4224 			       data_offset, size);
4225 		} else
4226 		    rc = -ENOMEM;
4227 	}
4228 	cifs_buf_release(pSMB);
4229 	if (rc == -EAGAIN)
4230 		goto QPathInfoRetry;
4231 
4232 	return rc;
4233 }
4234 
4235 int
4236 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4237 		 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4238 {
4239 	struct smb_t2_qfi_req *pSMB = NULL;
4240 	struct smb_t2_qfi_rsp *pSMBr = NULL;
4241 	unsigned int in_len;
4242 	int rc = 0;
4243 	int bytes_returned;
4244 	__u16 params, byte_count;
4245 
4246 UnixQFileInfoRetry:
4247 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4248 		      (void **) &pSMBr);
4249 	if (rc < 0)
4250 		return rc;
4251 	in_len = rc;
4252 
4253 	params = 2 /* level */ + 2 /* fid */;
4254 	pSMB->t2.TotalDataCount = 0;
4255 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4256 	/* BB find exact max data count below from sess structure BB */
4257 	pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4258 	pSMB->t2.MaxSetupCount = 0;
4259 	pSMB->t2.Reserved = 0;
4260 	pSMB->t2.Flags = 0;
4261 	pSMB->t2.Timeout = 0;
4262 	pSMB->t2.Reserved2 = 0;
4263 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4264 					       Fid));
4265 	pSMB->t2.DataCount = 0;
4266 	pSMB->t2.DataOffset = 0;
4267 	pSMB->t2.SetupCount = 1;
4268 	pSMB->t2.Reserved3 = 0;
4269 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4270 	byte_count = params + 1 /* pad */ ;
4271 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4272 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4273 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4274 	pSMB->Pad = 0;
4275 	pSMB->Fid = netfid;
4276 	in_len += byte_count;
4277 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4278 
4279 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4280 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4281 	if (rc) {
4282 		cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4283 	} else {		/* decode response */
4284 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4285 
4286 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4287 			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4288 			rc = smb_EIO2(smb_eio_trace_unixqfileinfo_bcc_too_small,
4289 				      get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
4290 		} else {
4291 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4292 			memcpy((char *) pFindData,
4293 			       (char *) &pSMBr->hdr.Protocol +
4294 			       data_offset,
4295 			       sizeof(FILE_UNIX_BASIC_INFO));
4296 		}
4297 	}
4298 
4299 	cifs_buf_release(pSMB);
4300 	if (rc == -EAGAIN)
4301 		goto UnixQFileInfoRetry;
4302 
4303 	return rc;
4304 }
4305 
4306 int
4307 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4308 		     const unsigned char *searchName,
4309 		     FILE_UNIX_BASIC_INFO *pFindData,
4310 		     const struct nls_table *nls_codepage, int remap)
4311 {
4312 /* SMB_QUERY_FILE_UNIX_BASIC */
4313 	TRANSACTION2_QPI_REQ *pSMB = NULL;
4314 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
4315 	unsigned int in_len;
4316 	int rc = 0;
4317 	int bytes_returned = 0;
4318 	int name_len;
4319 	__u16 params, byte_count;
4320 
4321 	cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4322 UnixQPathInfoRetry:
4323 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4324 		      (void **) &pSMBr);
4325 	if (rc < 0)
4326 		return rc;
4327 	in_len = rc;
4328 
4329 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4330 		name_len =
4331 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4332 				       PATH_MAX, nls_codepage, remap);
4333 		name_len++;	/* trailing null */
4334 		name_len *= 2;
4335 	} else {
4336 		name_len = copy_path_name(pSMB->FileName, searchName);
4337 	}
4338 
4339 	params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4340 	pSMB->TotalDataCount = 0;
4341 	pSMB->MaxParameterCount = cpu_to_le16(2);
4342 	/* BB find exact max SMB PDU from sess structure BB */
4343 	pSMB->MaxDataCount = cpu_to_le16(4000);
4344 	pSMB->MaxSetupCount = 0;
4345 	pSMB->Reserved = 0;
4346 	pSMB->Flags = 0;
4347 	pSMB->Timeout = 0;
4348 	pSMB->Reserved2 = 0;
4349 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4350 		struct smb_com_transaction2_qpi_req, InformationLevel));
4351 	pSMB->DataCount = 0;
4352 	pSMB->DataOffset = 0;
4353 	pSMB->SetupCount = 1;
4354 	pSMB->Reserved3 = 0;
4355 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4356 	byte_count = params + 1 /* pad */ ;
4357 	pSMB->TotalParameterCount = cpu_to_le16(params);
4358 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4359 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4360 	pSMB->Reserved4 = 0;
4361 	in_len += byte_count;
4362 	pSMB->ByteCount = cpu_to_le16(byte_count);
4363 
4364 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4365 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4366 	if (rc) {
4367 		cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4368 	} else {		/* decode response */
4369 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4370 
4371 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4372 			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4373 			rc = smb_EIO2(smb_eio_trace_unixqpathinfo_bcc_too_small,
4374 				      get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
4375 		} else {
4376 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4377 			memcpy((char *) pFindData,
4378 			       (char *) &pSMBr->hdr.Protocol +
4379 			       data_offset,
4380 			       sizeof(FILE_UNIX_BASIC_INFO));
4381 		}
4382 	}
4383 	cifs_buf_release(pSMB);
4384 	if (rc == -EAGAIN)
4385 		goto UnixQPathInfoRetry;
4386 
4387 	return rc;
4388 }
4389 
4390 /* xid, tcon, searchName and codepage are input parms, rest are returned */
4391 int
4392 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4393 	      const char *searchName, struct cifs_sb_info *cifs_sb,
4394 	      __u16 *pnetfid, __u16 search_flags,
4395 	      struct cifs_search_info *psrch_inf, bool msearch)
4396 {
4397 /* level 257 SMB_ */
4398 	unsigned int parm_off, parm_count, data_off, data_count;
4399 	TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4400 	TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4401 	struct nls_table *nls_codepage;
4402 	T2_FFIRST_RSP_PARMS *parms;
4403 	unsigned int in_len, lnoff;
4404 	__u16 params, byte_count;
4405 	int bytes_returned = 0;
4406 	int name_len, remap;
4407 	int rc = 0;
4408 
4409 	cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4410 
4411 findFirstRetry:
4412 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4413 		      (void **) &pSMBr);
4414 	if (rc < 0)
4415 		return rc;
4416 	in_len = rc;
4417 
4418 	nls_codepage = cifs_sb->local_nls;
4419 	remap = cifs_remap(cifs_sb);
4420 
4421 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4422 		name_len =
4423 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4424 				       PATH_MAX, nls_codepage, remap);
4425 		/* We can not add the asterisk earlier in case
4426 		it got remapped to 0xF03A as if it were part of the
4427 		directory name instead of a wildcard */
4428 		name_len *= 2;
4429 		if (msearch) {
4430 			pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4431 			pSMB->FileName[name_len+1] = 0;
4432 			pSMB->FileName[name_len+2] = '*';
4433 			pSMB->FileName[name_len+3] = 0;
4434 			name_len += 4; /* now the trailing null */
4435 			/* null terminate just in case */
4436 			pSMB->FileName[name_len] = 0;
4437 			pSMB->FileName[name_len+1] = 0;
4438 			name_len += 2;
4439 		} else if (!searchName[0]) {
4440 			pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb);
4441 			pSMB->FileName[1] = 0;
4442 			pSMB->FileName[2] = 0;
4443 			pSMB->FileName[3] = 0;
4444 			name_len = 4;
4445 		}
4446 	} else {
4447 		name_len = copy_path_name(pSMB->FileName, searchName);
4448 		if (msearch) {
4449 			if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4450 				name_len = PATH_MAX-2;
4451 			/* overwrite nul byte */
4452 			pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4453 			pSMB->FileName[name_len] = '*';
4454 			pSMB->FileName[name_len+1] = 0;
4455 			name_len += 2;
4456 		} else if (!searchName[0]) {
4457 			pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb);
4458 			pSMB->FileName[1] = 0;
4459 			name_len = 2;
4460 		}
4461 	}
4462 
4463 	params = 12 + name_len /* includes null */ ;
4464 	pSMB->TotalDataCount = 0;	/* no EAs */
4465 	pSMB->MaxParameterCount = cpu_to_le16(10);
4466 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4467 	pSMB->MaxSetupCount = 0;
4468 	pSMB->Reserved = 0;
4469 	pSMB->Flags = 0;
4470 	pSMB->Timeout = 0;
4471 	pSMB->Reserved2 = 0;
4472 	byte_count = params + 1 /* pad */ ;
4473 	pSMB->TotalParameterCount = cpu_to_le16(params);
4474 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4475 	pSMB->ParameterOffset = cpu_to_le16(
4476 	      offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes));
4477 	pSMB->DataCount = 0;
4478 	pSMB->DataOffset = 0;
4479 	pSMB->SetupCount = 1;	/* one byte, no need to make endian neutral */
4480 	pSMB->Reserved3 = 0;
4481 	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4482 	pSMB->SearchAttributes =
4483 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4484 			ATTR_DIRECTORY);
4485 	pSMB->SearchCount = cpu_to_le16(msearch ? CIFSMaxBufSize/sizeof(FILE_UNIX_INFO) : 1);
4486 	pSMB->SearchFlags = cpu_to_le16(search_flags);
4487 	pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4488 
4489 	/* BB what should we set StorageType to? Does it matter? BB */
4490 	pSMB->SearchStorageType = 0;
4491 	in_len += byte_count;
4492 	pSMB->ByteCount = cpu_to_le16(byte_count);
4493 
4494 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4495 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4496 	cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4497 
4498 	if (rc) {
4499 		/*
4500 		 * BB: add logic to retry regular search if Unix search rejected
4501 		 * unexpectedly by server.
4502 		 */
4503 		/* BB: add code to handle unsupported level rc */
4504 		cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4505 		cifs_buf_release(pSMB);
4506 		/*
4507 		 * BB: eventually could optimize out free and realloc of buf for
4508 		 * this case.
4509 		 */
4510 		if (rc == -EAGAIN)
4511 			goto findFirstRetry;
4512 		return rc;
4513 	}
4514 	/* decode response */
4515 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4516 	if (rc) {
4517 		cifs_buf_release(pSMB);
4518 		return rc;
4519 	}
4520 
4521 	parm_off = le16_to_cpu(pSMBr->t2.ParameterOffset);
4522 	parm_count = le16_to_cpu(pSMBr->t2.ParameterCount);
4523 	if (parm_count < sizeof(*parms) ||
4524 	    parm_off + parm_count > (unsigned int)bytes_returned) {
4525 		cifs_dbg(FYI, "%s: bad parameter area offset %u count %u for response of %d\n",
4526 			 __func__, parm_off, parm_count, bytes_returned);
4527 		rc = smb_EIO2(smb_eio_trace_ffirst_param_area,
4528 			      parm_off, parm_count);
4529 		cifs_buf_release(pSMB);
4530 		return rc;
4531 	}
4532 
4533 	data_off = le16_to_cpu(pSMBr->t2.DataOffset);
4534 	data_count = le16_to_cpu(pSMBr->t2.DataCount);
4535 	if (data_off + data_count > (unsigned int)bytes_returned) {
4536 		cifs_dbg(VFS, "%s: data area offset %u count %u past response length %d\n",
4537 			 __func__, data_off, data_count, bytes_returned);
4538 		cifs_buf_release(pSMB);
4539 		return -EINVAL;
4540 	}
4541 
4542 	psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4543 	psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4544 	psrch_inf->smallBuf = false;
4545 	psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol + data_off;
4546 
4547 	parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol + parm_off);
4548 	psrch_inf->endOfSearch = !!parms->EndofSearch;
4549 
4550 	psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4551 	psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4552 		psrch_inf->entries_in_buffer;
4553 	psrch_inf->presume_name = NULL;
4554 	psrch_inf->resume_name_len = 0;
4555 	psrch_inf->resume_key = 0;
4556 	if (pnetfid)
4557 		*pnetfid = parms->SearchHandle;
4558 	lnoff = le16_to_cpu(parms->LastNameOffset);
4559 	if (!psrch_inf->entries_in_buffer) {
4560 		psrch_inf->last_entry = NULL;
4561 	} else if (psrch_inf->srch_entries_start + lnoff >=
4562 		   psrch_inf->ntwrk_buf_start + bytes_returned) {
4563 		cifs_dbg(VFS, "ignoring corrupt resume name\n");
4564 		psrch_inf->last_entry = NULL;
4565 	} else {
4566 		psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff;
4567 	}
4568 	return 0;
4569 }
4570 
4571 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4572 		 __u16 searchHandle, __u16 search_flags,
4573 		 struct cifs_search_info *psrch_inf)
4574 {
4575 	unsigned int parm_off, parm_count, data_off, data_count;
4576 	TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4577 	TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4578 	unsigned int name_len, in_len;
4579 	T2_FNEXT_RSP_PARMS *parms;
4580 	unsigned int lnoff;
4581 	__u16 params, byte_count;
4582 	char *response_data;
4583 	int bytes_returned;
4584 	int rc = 0;
4585 
4586 	cifs_dbg(FYI, "In FindNext\n");
4587 
4588 	if (psrch_inf->endOfSearch)
4589 		return -ENOENT;
4590 
4591 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4592 		(void **) &pSMBr);
4593 	if (rc < 0)
4594 		return rc;
4595 	in_len = rc;
4596 
4597 	params = 14; /* includes 2 bytes of null string, converted to LE below*/
4598 	byte_count = 0;
4599 	pSMB->TotalDataCount = 0;       /* no EAs */
4600 	pSMB->MaxParameterCount = cpu_to_le16(8);
4601 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4602 	pSMB->MaxSetupCount = 0;
4603 	pSMB->Reserved = 0;
4604 	pSMB->Flags = 0;
4605 	pSMB->Timeout = 0;
4606 	pSMB->Reserved2 = 0;
4607 	pSMB->ParameterOffset =  cpu_to_le16(
4608 	      offsetof(struct smb_com_transaction2_fnext_req, SearchHandle));
4609 	pSMB->DataCount = 0;
4610 	pSMB->DataOffset = 0;
4611 	pSMB->SetupCount = 1;
4612 	pSMB->Reserved3 = 0;
4613 	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4614 	pSMB->SearchHandle = searchHandle;      /* always kept as le */
4615 	pSMB->SearchCount =
4616 		cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4617 	pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4618 	pSMB->ResumeKey = psrch_inf->resume_key;
4619 	pSMB->SearchFlags = cpu_to_le16(search_flags);
4620 
4621 	name_len = psrch_inf->resume_name_len;
4622 	params += name_len;
4623 	if (name_len < PATH_MAX) {
4624 		if (name_len) {
4625 			memcpy(pSMB->ResumeFileName,
4626 			       psrch_inf->presume_name, name_len);
4627 		}
4628 		byte_count += name_len;
4629 		/* 14 byte parm len above enough for 2 byte null terminator */
4630 		pSMB->ResumeFileName[name_len] = 0;
4631 		pSMB->ResumeFileName[name_len+1] = 0;
4632 	} else {
4633 		cifs_buf_release(pSMB);
4634 		return -EINVAL;
4635 	}
4636 	byte_count = params + 1 /* pad */ ;
4637 	pSMB->TotalParameterCount = cpu_to_le16(params);
4638 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4639 	in_len += byte_count;
4640 	pSMB->ByteCount = cpu_to_le16(byte_count);
4641 
4642 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4643 			(struct smb_hdr *) pSMBr, &bytes_returned, 0);
4644 	cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4645 
4646 	if (rc) {
4647 		cifs_buf_release(pSMB);
4648 		if (rc == -EBADF) {
4649 			psrch_inf->endOfSearch = true;
4650 			rc = 0; /* search probably was closed at end of search*/
4651 		} else {
4652 			cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4653 		}
4654 		return rc;
4655 	}
4656 
4657 	/* decode response */
4658 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4659 	if (rc) {
4660 		cifs_buf_release(pSMB);
4661 		return rc;
4662 	}
4663 
4664 	parm_off = le16_to_cpu(pSMBr->t2.ParameterOffset);
4665 	parm_count = le16_to_cpu(pSMBr->t2.ParameterCount);
4666 	if (parm_count < sizeof(*parms) ||
4667 	    parm_off + parm_count > (unsigned int)bytes_returned) {
4668 		cifs_dbg(FYI, "%s: bad parameter area offset %u count %u for response of %d\n",
4669 			 __func__, parm_off, parm_count, bytes_returned);
4670 		rc = smb_EIO2(smb_eio_trace_fnext_param_area,
4671 			      parm_off, parm_count);
4672 		cifs_buf_release(pSMB);
4673 		return rc;
4674 	}
4675 
4676 	data_off = le16_to_cpu(pSMBr->t2.DataOffset);
4677 	data_count = le16_to_cpu(pSMBr->t2.DataCount);
4678 	if (data_off + data_count > (unsigned int)bytes_returned) {
4679 		cifs_dbg(VFS, "%s: data area offset %u count %u past response length %d\n",
4680 			 __func__, data_off, data_count, bytes_returned);
4681 		cifs_buf_release(pSMB);
4682 		return -EINVAL;
4683 	}
4684 
4685 	/* BB fixme add lock for file (srch_info) struct here */
4686 	psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4687 	response_data = (char *)&pSMBr->hdr.Protocol + parm_off;
4688 	parms = (T2_FNEXT_RSP_PARMS *)response_data;
4689 	response_data = (char *)&pSMBr->hdr.Protocol + data_off;
4690 
4691 	if (psrch_inf->smallBuf)
4692 		cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
4693 	else
4694 		cifs_buf_release(psrch_inf->ntwrk_buf_start);
4695 
4696 	psrch_inf->srch_entries_start = response_data;
4697 	psrch_inf->ntwrk_buf_start = (char *)pSMB;
4698 	psrch_inf->smallBuf = false;
4699 	psrch_inf->endOfSearch = !!parms->EndofSearch;
4700 	psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4701 	psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer;
4702 	psrch_inf->presume_name = NULL;
4703 	psrch_inf->resume_name_len = 0;
4704 	psrch_inf->resume_key = 0;
4705 	lnoff = le16_to_cpu(parms->LastNameOffset);
4706 	if (!psrch_inf->entries_in_buffer) {
4707 		psrch_inf->last_entry = NULL;
4708 	} else if (psrch_inf->srch_entries_start + lnoff >=
4709 		   psrch_inf->ntwrk_buf_start + bytes_returned) {
4710 		cifs_dbg(VFS, "ignoring corrupt resume name\n");
4711 		psrch_inf->last_entry = NULL;
4712 	} else {
4713 		psrch_inf->last_entry =
4714 			psrch_inf->srch_entries_start + lnoff;
4715 	}
4716 	/* BB fixme add unlock here */
4717 
4718 	/*
4719 	 * BB: On error, should we leave previous search buf
4720 	 * (and count and last entry fields) intact or free the previous one?
4721 	 *
4722 	 * Note: On -EAGAIN error only caller can retry on handle based calls
4723 	 * since file handle passed in no longer valid.
4724 	 */
4725 	return 0;
4726 }
4727 
4728 int
4729 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4730 	      const __u16 searchHandle)
4731 {
4732 	int rc = 0;
4733 	FINDCLOSE_REQ *pSMB = NULL;
4734 	unsigned int in_len;
4735 
4736 	cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4737 	rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4738 
4739 	/* no sense returning error if session restarted
4740 		as file handle has been closed */
4741 	if (rc == -EAGAIN)
4742 		return 0;
4743 	if (rc < 0)
4744 		return rc;
4745 	in_len = rc;
4746 
4747 	pSMB->FileID = searchHandle;
4748 	pSMB->ByteCount = 0;
4749 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
4750 	cifs_small_buf_release(pSMB);
4751 	if (rc)
4752 		cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4753 
4754 	cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4755 
4756 	/* Since session is dead, search handle closed on server already */
4757 	if (rc == -EAGAIN)
4758 		rc = 0;
4759 
4760 	return rc;
4761 }
4762 
4763 int
4764 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4765 		      const char *search_name, __u64 *inode_number,
4766 		      const struct nls_table *nls_codepage, int remap)
4767 {
4768 	int rc = 0;
4769 	TRANSACTION2_QPI_REQ *pSMB = NULL;
4770 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
4771 	unsigned int in_len;
4772 	int name_len, bytes_returned;
4773 	__u16 params, byte_count;
4774 
4775 	cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4776 	if (tcon == NULL)
4777 		return -ENODEV;
4778 
4779 GetInodeNumberRetry:
4780 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4781 		      (void **) &pSMBr);
4782 	if (rc < 0)
4783 		return rc;
4784 	in_len = rc;
4785 
4786 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4787 		name_len =
4788 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
4789 					   search_name, PATH_MAX, nls_codepage,
4790 					   remap);
4791 		name_len++;     /* trailing null */
4792 		name_len *= 2;
4793 	} else {
4794 		name_len = copy_path_name(pSMB->FileName, search_name);
4795 	}
4796 
4797 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4798 	pSMB->TotalDataCount = 0;
4799 	pSMB->MaxParameterCount = cpu_to_le16(2);
4800 	/* BB find exact max data count below from sess structure BB */
4801 	pSMB->MaxDataCount = cpu_to_le16(4000);
4802 	pSMB->MaxSetupCount = 0;
4803 	pSMB->Reserved = 0;
4804 	pSMB->Flags = 0;
4805 	pSMB->Timeout = 0;
4806 	pSMB->Reserved2 = 0;
4807 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4808 		struct smb_com_transaction2_qpi_req, InformationLevel));
4809 	pSMB->DataCount = 0;
4810 	pSMB->DataOffset = 0;
4811 	pSMB->SetupCount = 1;
4812 	pSMB->Reserved3 = 0;
4813 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4814 	byte_count = params + 1 /* pad */ ;
4815 	pSMB->TotalParameterCount = cpu_to_le16(params);
4816 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4817 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4818 	pSMB->Reserved4 = 0;
4819 	in_len += byte_count;
4820 	pSMB->ByteCount = cpu_to_le16(byte_count);
4821 
4822 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
4823 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
4824 	if (rc) {
4825 		cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4826 	} else {
4827 		/* decode response */
4828 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4829 		/* BB also check enough total bytes returned */
4830 		if (rc || get_bcc(&pSMBr->hdr) < 2)
4831 			/* If rc should we check for EOPNOSUPP and
4832 			disable the srvino flag? or in caller? */
4833 			rc = smb_EIO2(smb_eio_trace_getsrvinonum_bcc_too_small,
4834 				      get_bcc(&pSMBr->hdr), 2);
4835 		else {
4836 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4837 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4838 			struct file_internal_info *pfinfo;
4839 			/* BB Do we need a cast or hash here ? */
4840 			if (count < 8) {
4841 				cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4842 				rc = smb_EIO2(smb_eio_trace_getsrvinonum_size,
4843 					      count, 8);
4844 				goto GetInodeNumOut;
4845 			}
4846 			pfinfo = (struct file_internal_info *)
4847 				(data_offset + (char *) &pSMBr->hdr.Protocol);
4848 			*inode_number = le64_to_cpu(pfinfo->UniqueId);
4849 		}
4850 	}
4851 GetInodeNumOut:
4852 	cifs_buf_release(pSMB);
4853 	if (rc == -EAGAIN)
4854 		goto GetInodeNumberRetry;
4855 	return rc;
4856 }
4857 
4858 int
4859 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4860 		const char *search_name, struct dfs_info3_param **target_nodes,
4861 		unsigned int *num_of_nodes,
4862 		const struct nls_table *nls_codepage, int remap)
4863 {
4864 /* TRANS2_GET_DFS_REFERRAL */
4865 	TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4866 	TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4867 	unsigned int in_len;
4868 	int rc = 0;
4869 	int bytes_returned;
4870 	int name_len;
4871 	__u16 params, byte_count;
4872 	*num_of_nodes = 0;
4873 	*target_nodes = NULL;
4874 
4875 	cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4876 	if (ses == NULL || ses->tcon_ipc == NULL)
4877 		return -ENODEV;
4878 
4879 getDFSRetry:
4880 	/*
4881 	 * Use smb_init_no_reconnect() instead of smb_init() as
4882 	 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4883 	 * causing an infinite recursion.
4884 	 */
4885 	rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4886 		      (void **)&pSMB, (void **)&pSMBr);
4887 	if (rc < 0)
4888 		return rc;
4889 	in_len = rc;
4890 
4891 	/* server pointer checked in called function,
4892 	but should never be null here anyway */
4893 	pSMB->hdr.Mid = get_next_mid(ses->server);
4894 	pSMB->hdr.Tid = ses->tcon_ipc->tid;
4895 	pSMB->hdr.Uid = ses->Suid;
4896 	if (ses->capabilities & CAP_STATUS32)
4897 		pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4898 	if (ses->capabilities & CAP_DFS)
4899 		pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4900 
4901 	if (ses->capabilities & CAP_UNICODE) {
4902 		pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4903 		name_len =
4904 		    cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4905 				       search_name, PATH_MAX, nls_codepage,
4906 				       remap);
4907 		name_len++;	/* trailing null */
4908 		name_len *= 2;
4909 	} else {	/* BB improve the check for buffer overruns BB */
4910 		name_len = copy_path_name(pSMB->RequestFileName, search_name);
4911 	}
4912 
4913 	if (ses->server->sign)
4914 		pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4915 
4916 	pSMB->hdr.Uid = ses->Suid;
4917 
4918 	params = 2 /* level */  + name_len /*includes null */ ;
4919 	pSMB->TotalDataCount = 0;
4920 	pSMB->DataCount = 0;
4921 	pSMB->DataOffset = 0;
4922 	pSMB->MaxParameterCount = 0;
4923 	/* BB find exact max SMB PDU from sess structure BB */
4924 	pSMB->MaxDataCount = cpu_to_le16(4000);
4925 	pSMB->MaxSetupCount = 0;
4926 	pSMB->Reserved = 0;
4927 	pSMB->Flags = 0;
4928 	pSMB->Timeout = 0;
4929 	pSMB->Reserved2 = 0;
4930 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4931 	  struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel));
4932 	pSMB->SetupCount = 1;
4933 	pSMB->Reserved3 = 0;
4934 	pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4935 	byte_count = params + 3 /* pad */ ;
4936 	pSMB->ParameterCount = cpu_to_le16(params);
4937 	pSMB->TotalParameterCount = pSMB->ParameterCount;
4938 	pSMB->MaxReferralLevel = cpu_to_le16(3);
4939 	in_len += byte_count;
4940 	pSMB->ByteCount = cpu_to_le16(byte_count);
4941 
4942 	rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len,
4943 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4944 	if (rc) {
4945 		cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4946 		goto GetDFSRefExit;
4947 	}
4948 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4949 
4950 	/* BB Also check if enough total bytes returned? */
4951 	if (rc || get_bcc(&pSMBr->hdr) < 17) {
4952 		rc = smb_EIO2(smb_eio_trace_getdfsrefer_bcc_too_small,
4953 			      get_bcc(&pSMBr->hdr), 17);
4954 		goto GetDFSRefExit;
4955 	}
4956 
4957 	cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4958 		 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4959 
4960 	/* parse returned result into more usable form */
4961 	rc = parse_dfs_referrals(&pSMBr->dfs_data,
4962 				 le16_to_cpu(pSMBr->t2.DataCount),
4963 				 num_of_nodes, target_nodes, nls_codepage,
4964 				 remap, search_name,
4965 				 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4966 
4967 GetDFSRefExit:
4968 	cifs_buf_release(pSMB);
4969 
4970 	if (rc == -EAGAIN)
4971 		goto getDFSRetry;
4972 
4973 	return rc;
4974 }
4975 
4976 /* Query File System Info such as free space to old servers such as Win 9x */
4977 int
4978 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4979 	      struct kstatfs *FSData)
4980 {
4981 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4982 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4983 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4984 	FILE_SYSTEM_ALLOC_INFO *response_data;
4985 	unsigned int in_len;
4986 	int rc = 0;
4987 	int bytes_returned = 0;
4988 	__u16 params, byte_count;
4989 
4990 	cifs_dbg(FYI, "OldQFSInfo\n");
4991 oldQFSInfoRetry:
4992 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4993 		(void **) &pSMBr);
4994 	if (rc < 0)
4995 		return rc;
4996 	in_len = rc;
4997 
4998 	params = 2;     /* level */
4999 	pSMB->TotalDataCount = 0;
5000 	pSMB->MaxParameterCount = cpu_to_le16(2);
5001 	pSMB->MaxDataCount = cpu_to_le16(1000);
5002 	pSMB->MaxSetupCount = 0;
5003 	pSMB->Reserved = 0;
5004 	pSMB->Flags = 0;
5005 	pSMB->Timeout = 0;
5006 	pSMB->Reserved2 = 0;
5007 	byte_count = params + 1 /* pad */ ;
5008 	pSMB->TotalParameterCount = cpu_to_le16(params);
5009 	pSMB->ParameterCount = pSMB->TotalParameterCount;
5010 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
5011 		struct smb_com_transaction2_qfsi_req, InformationLevel));
5012 	pSMB->DataCount = 0;
5013 	pSMB->DataOffset = 0;
5014 	pSMB->SetupCount = 1;
5015 	pSMB->Reserved3 = 0;
5016 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5017 	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
5018 	in_len += byte_count;
5019 	pSMB->ByteCount = cpu_to_le16(byte_count);
5020 
5021 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5022 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
5023 	if (rc) {
5024 		cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5025 	} else {                /* decode response */
5026 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5027 
5028 		if (rc || get_bcc(&pSMBr->hdr) < 18)
5029 			rc = smb_EIO2(smb_eio_trace_oldqfsinfo_bcc_too_small,
5030 				      get_bcc(&pSMBr->hdr), 18);
5031 		else {
5032 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5033 			cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
5034 				 get_bcc(&pSMBr->hdr), data_offset);
5035 
5036 			response_data = (FILE_SYSTEM_ALLOC_INFO *)
5037 				(((char *) &pSMBr->hdr.Protocol) + data_offset);
5038 			FSData->f_bsize =
5039 				le16_to_cpu(response_data->BytesPerSector) *
5040 				le32_to_cpu(response_data->
5041 					SectorsPerAllocationUnit);
5042 			/*
5043 			 * much prefer larger but if server doesn't report
5044 			 * a valid size than 4K is a reasonable minimum
5045 			 */
5046 			if (FSData->f_bsize < 512)
5047 				FSData->f_bsize = 4096;
5048 
5049 			FSData->f_blocks =
5050 			       le32_to_cpu(response_data->TotalAllocationUnits);
5051 			FSData->f_bfree = FSData->f_bavail =
5052 				le32_to_cpu(response_data->FreeAllocationUnits);
5053 			cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
5054 				 (unsigned long long)FSData->f_blocks,
5055 				 (unsigned long long)FSData->f_bfree,
5056 				 FSData->f_bsize);
5057 		}
5058 	}
5059 	cifs_buf_release(pSMB);
5060 
5061 	if (rc == -EAGAIN)
5062 		goto oldQFSInfoRetry;
5063 
5064 	return rc;
5065 }
5066 
5067 int
5068 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
5069 	       struct kstatfs *FSData)
5070 {
5071 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
5072 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5073 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5074 	FILE_SYSTEM_SIZE_INFO *response_data;
5075 	unsigned int in_len;
5076 	int rc = 0;
5077 	int bytes_returned = 0;
5078 	__u16 params, byte_count;
5079 
5080 	cifs_dbg(FYI, "In QFSInfo\n");
5081 QFSInfoRetry:
5082 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5083 		      (void **) &pSMBr);
5084 	if (rc < 0)
5085 		return rc;
5086 	in_len = rc;
5087 
5088 	params = 2;	/* level */
5089 	pSMB->TotalDataCount = 0;
5090 	pSMB->MaxParameterCount = cpu_to_le16(2);
5091 	pSMB->MaxDataCount = cpu_to_le16(1000);
5092 	pSMB->MaxSetupCount = 0;
5093 	pSMB->Reserved = 0;
5094 	pSMB->Flags = 0;
5095 	pSMB->Timeout = 0;
5096 	pSMB->Reserved2 = 0;
5097 	byte_count = params + 1 /* pad */ ;
5098 	pSMB->TotalParameterCount = cpu_to_le16(params);
5099 	pSMB->ParameterCount = pSMB->TotalParameterCount;
5100 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
5101 		struct smb_com_transaction2_qfsi_req, InformationLevel));
5102 	pSMB->DataCount = 0;
5103 	pSMB->DataOffset = 0;
5104 	pSMB->SetupCount = 1;
5105 	pSMB->Reserved3 = 0;
5106 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5107 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5108 	in_len += byte_count;
5109 	pSMB->ByteCount = cpu_to_le16(byte_count);
5110 
5111 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5112 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5113 	if (rc) {
5114 		cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5115 	} else {		/* decode response */
5116 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5117 
5118 		if (rc || get_bcc(&pSMBr->hdr) < 24)
5119 			rc = smb_EIO2(smb_eio_trace_qfsinfo_bcc_too_small,
5120 				      get_bcc(&pSMBr->hdr), 24);
5121 		else {
5122 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5123 
5124 			response_data =
5125 			    (FILE_SYSTEM_SIZE_INFO
5126 			     *) (((char *) &pSMBr->hdr.Protocol) +
5127 				 data_offset);
5128 			FSData->f_bsize =
5129 			    le32_to_cpu(response_data->BytesPerSector) *
5130 			    le32_to_cpu(response_data->
5131 					SectorsPerAllocationUnit);
5132 			/*
5133 			 * much prefer larger but if server doesn't report
5134 			 * a valid size than 4K is a reasonable minimum
5135 			 */
5136 			if (FSData->f_bsize < 512)
5137 				FSData->f_bsize = 4096;
5138 
5139 			FSData->f_blocks =
5140 			    le64_to_cpu(response_data->TotalAllocationUnits);
5141 			FSData->f_bfree = FSData->f_bavail =
5142 			    le64_to_cpu(response_data->AvailableAllocationUnits);
5143 			cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
5144 				 (unsigned long long)FSData->f_blocks,
5145 				 (unsigned long long)FSData->f_bfree,
5146 				 FSData->f_bsize);
5147 		}
5148 	}
5149 	cifs_buf_release(pSMB);
5150 
5151 	if (rc == -EAGAIN)
5152 		goto QFSInfoRetry;
5153 
5154 	return rc;
5155 }
5156 
5157 int
5158 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5159 {
5160 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5161 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5162 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5163 	FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5164 	unsigned int in_len;
5165 	int rc = 0;
5166 	int bytes_returned = 0;
5167 	__u16 params, byte_count;
5168 
5169 	cifs_dbg(FYI, "In QFSAttributeInfo\n");
5170 QFSAttributeRetry:
5171 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5172 		      (void **) &pSMBr);
5173 	if (rc < 0)
5174 		return rc;
5175 	in_len = rc;
5176 
5177 	params = 2;	/* level */
5178 	pSMB->TotalDataCount = 0;
5179 	pSMB->MaxParameterCount = cpu_to_le16(2);
5180 	/* BB find exact max SMB PDU from sess structure BB */
5181 	pSMB->MaxDataCount = cpu_to_le16(1000);
5182 	pSMB->MaxSetupCount = 0;
5183 	pSMB->Reserved = 0;
5184 	pSMB->Flags = 0;
5185 	pSMB->Timeout = 0;
5186 	pSMB->Reserved2 = 0;
5187 	byte_count = params + 1 /* pad */ ;
5188 	pSMB->TotalParameterCount = cpu_to_le16(params);
5189 	pSMB->ParameterCount = pSMB->TotalParameterCount;
5190 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
5191 		struct smb_com_transaction2_qfsi_req, InformationLevel));
5192 	pSMB->DataCount = 0;
5193 	pSMB->DataOffset = 0;
5194 	pSMB->SetupCount = 1;
5195 	pSMB->Reserved3 = 0;
5196 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5197 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5198 	in_len += byte_count;
5199 	pSMB->ByteCount = cpu_to_le16(byte_count);
5200 
5201 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5202 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5203 	if (rc) {
5204 		cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5205 	} else {		/* decode response */
5206 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5207 
5208 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
5209 			/* BB also check if enough bytes returned */
5210 			rc = smb_EIO2(smb_eio_trace_qfsattrinfo_bcc_too_small,
5211 				      get_bcc(&pSMBr->hdr), 13);
5212 		} else {
5213 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5214 			response_data =
5215 			    (FILE_SYSTEM_ATTRIBUTE_INFO
5216 			     *) (((char *) &pSMBr->hdr.Protocol) +
5217 				 data_offset);
5218 			memcpy(&tcon->fsAttrInfo, response_data,
5219 			       sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5220 		}
5221 	}
5222 	cifs_buf_release(pSMB);
5223 
5224 	if (rc == -EAGAIN)
5225 		goto QFSAttributeRetry;
5226 
5227 	return rc;
5228 }
5229 
5230 int
5231 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5232 {
5233 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5234 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5235 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5236 	FILE_SYSTEM_DEVICE_INFO *response_data;
5237 	unsigned int in_len;
5238 	int rc = 0;
5239 	int bytes_returned = 0;
5240 	__u16 params, byte_count;
5241 
5242 	cifs_dbg(FYI, "In QFSDeviceInfo\n");
5243 QFSDeviceRetry:
5244 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5245 		      (void **) &pSMBr);
5246 	if (rc < 0)
5247 		return rc;
5248 	in_len = rc;
5249 
5250 	params = 2;	/* level */
5251 	pSMB->TotalDataCount = 0;
5252 	pSMB->MaxParameterCount = cpu_to_le16(2);
5253 	/* BB find exact max SMB PDU from sess structure BB */
5254 	pSMB->MaxDataCount = cpu_to_le16(1000);
5255 	pSMB->MaxSetupCount = 0;
5256 	pSMB->Reserved = 0;
5257 	pSMB->Flags = 0;
5258 	pSMB->Timeout = 0;
5259 	pSMB->Reserved2 = 0;
5260 	byte_count = params + 1 /* pad */ ;
5261 	pSMB->TotalParameterCount = cpu_to_le16(params);
5262 	pSMB->ParameterCount = pSMB->TotalParameterCount;
5263 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
5264 		struct smb_com_transaction2_qfsi_req, InformationLevel));
5265 
5266 	pSMB->DataCount = 0;
5267 	pSMB->DataOffset = 0;
5268 	pSMB->SetupCount = 1;
5269 	pSMB->Reserved3 = 0;
5270 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5271 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5272 	in_len += byte_count;
5273 	pSMB->ByteCount = cpu_to_le16(byte_count);
5274 
5275 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5276 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5277 	if (rc) {
5278 		cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5279 	} else {		/* decode response */
5280 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5281 
5282 		if (rc || get_bcc(&pSMBr->hdr) <
5283 			  sizeof(FILE_SYSTEM_DEVICE_INFO))
5284 			rc = smb_EIO2(smb_eio_trace_qfsdevinfo_bcc_too_small,
5285 				      get_bcc(&pSMBr->hdr),
5286 				      sizeof(FILE_SYSTEM_DEVICE_INFO));
5287 		else {
5288 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5289 			response_data =
5290 			    (FILE_SYSTEM_DEVICE_INFO *)
5291 				(((char *) &pSMBr->hdr.Protocol) +
5292 				 data_offset);
5293 			memcpy(&tcon->fsDevInfo, response_data,
5294 			       sizeof(FILE_SYSTEM_DEVICE_INFO));
5295 		}
5296 	}
5297 	cifs_buf_release(pSMB);
5298 
5299 	if (rc == -EAGAIN)
5300 		goto QFSDeviceRetry;
5301 
5302 	return rc;
5303 }
5304 
5305 int
5306 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5307 {
5308 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5309 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5310 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5311 	FILE_SYSTEM_UNIX_INFO *response_data;
5312 	unsigned int in_len;
5313 	int rc = 0;
5314 	int bytes_returned = 0;
5315 	__u16 params, byte_count;
5316 
5317 	cifs_dbg(FYI, "In QFSUnixInfo\n");
5318 QFSUnixRetry:
5319 	rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5320 				   (void **) &pSMB, (void **) &pSMBr);
5321 	if (rc < 0)
5322 		return rc;
5323 	in_len = rc;
5324 
5325 	params = 2;	/* level */
5326 	pSMB->TotalDataCount = 0;
5327 	pSMB->DataCount = 0;
5328 	pSMB->DataOffset = 0;
5329 	pSMB->MaxParameterCount = cpu_to_le16(2);
5330 	/* BB find exact max SMB PDU from sess structure BB */
5331 	pSMB->MaxDataCount = cpu_to_le16(100);
5332 	pSMB->MaxSetupCount = 0;
5333 	pSMB->Reserved = 0;
5334 	pSMB->Flags = 0;
5335 	pSMB->Timeout = 0;
5336 	pSMB->Reserved2 = 0;
5337 	byte_count = params + 1 /* pad */ ;
5338 	pSMB->ParameterCount = cpu_to_le16(params);
5339 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5340 	pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5341 			smb_com_transaction2_qfsi_req, InformationLevel));
5342 	pSMB->SetupCount = 1;
5343 	pSMB->Reserved3 = 0;
5344 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5345 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5346 	in_len += byte_count;
5347 	pSMB->ByteCount = cpu_to_le16(byte_count);
5348 
5349 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5350 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5351 	if (rc) {
5352 		cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5353 	} else {		/* decode response */
5354 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5355 
5356 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
5357 			rc = smb_EIO2(smb_eio_trace_qfsunixinfo_bcc_too_small,
5358 				      get_bcc(&pSMBr->hdr), 13);
5359 		} else {
5360 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5361 			response_data =
5362 			    (FILE_SYSTEM_UNIX_INFO
5363 			     *) (((char *) &pSMBr->hdr.Protocol) +
5364 				 data_offset);
5365 			memcpy(&tcon->fsUnixInfo, response_data,
5366 			       sizeof(FILE_SYSTEM_UNIX_INFO));
5367 		}
5368 	}
5369 	cifs_buf_release(pSMB);
5370 
5371 	if (rc == -EAGAIN)
5372 		goto QFSUnixRetry;
5373 
5374 
5375 	return rc;
5376 }
5377 
5378 int
5379 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5380 {
5381 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5382 	TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5383 	TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5384 	unsigned int in_len;
5385 	int rc = 0;
5386 	int bytes_returned = 0;
5387 	__u16 params, param_offset, offset, byte_count;
5388 
5389 	cifs_dbg(FYI, "In SETFSUnixInfo\n");
5390 SETFSUnixRetry:
5391 	/* BB switch to small buf init to save memory */
5392 	rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5393 					(void **) &pSMB, (void **) &pSMBr);
5394 	if (rc < 0)
5395 		return rc;
5396 	in_len = rc;
5397 
5398 	params = 4;	/* 2 bytes zero followed by info level. */
5399 	pSMB->MaxSetupCount = 0;
5400 	pSMB->Reserved = 0;
5401 	pSMB->Flags = 0;
5402 	pSMB->Timeout = 0;
5403 	pSMB->Reserved2 = 0;
5404 	param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum);
5405 	offset = param_offset + params;
5406 
5407 	pSMB->MaxParameterCount = cpu_to_le16(4);
5408 	/* BB find exact max SMB PDU from sess structure BB */
5409 	pSMB->MaxDataCount = cpu_to_le16(100);
5410 	pSMB->SetupCount = 1;
5411 	pSMB->Reserved3 = 0;
5412 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5413 	byte_count = 1 /* pad */ + params + 12;
5414 
5415 	pSMB->DataCount = cpu_to_le16(12);
5416 	pSMB->ParameterCount = cpu_to_le16(params);
5417 	pSMB->TotalDataCount = pSMB->DataCount;
5418 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5419 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5420 	pSMB->DataOffset = cpu_to_le16(offset);
5421 
5422 	/* Params. */
5423 	pSMB->FileNum = 0;
5424 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5425 
5426 	/* Data. */
5427 	pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5428 	pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5429 	pSMB->ClientUnixCap = cpu_to_le64(cap);
5430 
5431 	in_len += byte_count;
5432 	pSMB->ByteCount = cpu_to_le16(byte_count);
5433 
5434 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5435 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5436 	if (rc) {
5437 		cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5438 	} else {		/* decode response */
5439 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5440 		if (rc)
5441 			rc = -EIO;	/* bad smb */
5442 	}
5443 	cifs_buf_release(pSMB);
5444 
5445 	if (rc == -EAGAIN)
5446 		goto SETFSUnixRetry;
5447 
5448 	return rc;
5449 }
5450 
5451 
5452 
5453 int
5454 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5455 		   struct kstatfs *FSData)
5456 {
5457 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5458 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
5459 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5460 	FILE_SYSTEM_POSIX_INFO *response_data;
5461 	unsigned int in_len;
5462 	int rc = 0;
5463 	int bytes_returned = 0;
5464 	__u16 params, byte_count;
5465 
5466 	cifs_dbg(FYI, "In QFSPosixInfo\n");
5467 QFSPosixRetry:
5468 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5469 		      (void **) &pSMBr);
5470 	if (rc < 0)
5471 		return rc;
5472 	in_len = rc;
5473 
5474 	params = 2;	/* level */
5475 	pSMB->TotalDataCount = 0;
5476 	pSMB->DataCount = 0;
5477 	pSMB->DataOffset = 0;
5478 	pSMB->MaxParameterCount = cpu_to_le16(2);
5479 	/* BB find exact max SMB PDU from sess structure BB */
5480 	pSMB->MaxDataCount = cpu_to_le16(100);
5481 	pSMB->MaxSetupCount = 0;
5482 	pSMB->Reserved = 0;
5483 	pSMB->Flags = 0;
5484 	pSMB->Timeout = 0;
5485 	pSMB->Reserved2 = 0;
5486 	byte_count = params + 1 /* pad */ ;
5487 	pSMB->ParameterCount = cpu_to_le16(params);
5488 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5489 	pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5490 			smb_com_transaction2_qfsi_req, InformationLevel));
5491 	pSMB->SetupCount = 1;
5492 	pSMB->Reserved3 = 0;
5493 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5494 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5495 	in_len += byte_count;
5496 	pSMB->ByteCount = cpu_to_le16(byte_count);
5497 
5498 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5499 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5500 	if (rc) {
5501 		cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5502 	} else {		/* decode response */
5503 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5504 
5505 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
5506 			rc = smb_EIO2(smb_eio_trace_qfsposixinfo_bcc_too_small,
5507 				      get_bcc(&pSMBr->hdr), 13);
5508 		} else {
5509 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5510 			response_data =
5511 			    (FILE_SYSTEM_POSIX_INFO
5512 			     *) (((char *) &pSMBr->hdr.Protocol) +
5513 				 data_offset);
5514 			FSData->f_bsize =
5515 					le32_to_cpu(response_data->BlockSize);
5516 			/*
5517 			 * much prefer larger but if server doesn't report
5518 			 * a valid size than 4K is a reasonable minimum
5519 			 */
5520 			if (FSData->f_bsize < 512)
5521 				FSData->f_bsize = 4096;
5522 
5523 			FSData->f_blocks =
5524 					le64_to_cpu(response_data->TotalBlocks);
5525 			FSData->f_bfree =
5526 			    le64_to_cpu(response_data->BlocksAvail);
5527 			if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5528 				FSData->f_bavail = FSData->f_bfree;
5529 			} else {
5530 				FSData->f_bavail =
5531 				    le64_to_cpu(response_data->UserBlocksAvail);
5532 			}
5533 			if (response_data->TotalFileNodes != cpu_to_le64(-1))
5534 				FSData->f_files =
5535 				     le64_to_cpu(response_data->TotalFileNodes);
5536 			if (response_data->FreeFileNodes != cpu_to_le64(-1))
5537 				FSData->f_ffree =
5538 				      le64_to_cpu(response_data->FreeFileNodes);
5539 		}
5540 	}
5541 	cifs_buf_release(pSMB);
5542 
5543 	if (rc == -EAGAIN)
5544 		goto QFSPosixRetry;
5545 
5546 	return rc;
5547 }
5548 
5549 
5550 /*
5551  * We can not use write of zero bytes trick to set file size due to need for
5552  * large file support. Also note that this SetPathInfo is preferred to
5553  * SetFileInfo based method in next routine which is only needed to work around
5554  * a sharing violation bugin Samba which this routine can run into.
5555  */
5556 int
5557 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5558 	      const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5559 	      bool set_allocation, struct dentry *dentry)
5560 {
5561 	struct smb_com_transaction2_spi_req *pSMB = NULL;
5562 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5563 	struct file_end_of_file_info *parm_data;
5564 	unsigned int in_len;
5565 	int name_len;
5566 	int rc = 0;
5567 	int bytes_returned = 0;
5568 	int remap = cifs_remap(cifs_sb);
5569 
5570 	__u16 params, byte_count, data_count, param_offset, offset;
5571 
5572 	cifs_dbg(FYI, "In SetEOF\n");
5573 SetEOFRetry:
5574 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5575 		      (void **) &pSMBr);
5576 	if (rc < 0)
5577 		return rc;
5578 	in_len = rc;
5579 
5580 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5581 		name_len =
5582 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5583 				       PATH_MAX, cifs_sb->local_nls, remap);
5584 		name_len++;	/* trailing null */
5585 		name_len *= 2;
5586 	} else {
5587 		name_len = copy_path_name(pSMB->FileName, file_name);
5588 	}
5589 	params = 6 + name_len;
5590 	data_count = sizeof(struct file_end_of_file_info);
5591 	pSMB->MaxParameterCount = cpu_to_le16(2);
5592 	pSMB->MaxDataCount = cpu_to_le16(4100);
5593 	pSMB->MaxSetupCount = 0;
5594 	pSMB->Reserved = 0;
5595 	pSMB->Flags = 0;
5596 	pSMB->Timeout = 0;
5597 	pSMB->Reserved2 = 0;
5598 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
5599 				InformationLevel);
5600 	offset = param_offset + params;
5601 	if (set_allocation) {
5602 		if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5603 			pSMB->InformationLevel =
5604 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5605 		else
5606 			pSMB->InformationLevel =
5607 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5608 	} else /* Set File Size */  {
5609 	    if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5610 		    pSMB->InformationLevel =
5611 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5612 	    else
5613 		    pSMB->InformationLevel =
5614 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5615 	}
5616 
5617 	parm_data =
5618 	    (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5619 				       offset);
5620 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5621 	pSMB->DataOffset = cpu_to_le16(offset);
5622 	pSMB->SetupCount = 1;
5623 	pSMB->Reserved3 = 0;
5624 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5625 	byte_count = 3 /* pad */  + params + data_count;
5626 	pSMB->DataCount = cpu_to_le16(data_count);
5627 	pSMB->TotalDataCount = pSMB->DataCount;
5628 	pSMB->ParameterCount = cpu_to_le16(params);
5629 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5630 	pSMB->Reserved4 = 0;
5631 	in_len += byte_count;
5632 	parm_data->FileSize = cpu_to_le64(size);
5633 	pSMB->ByteCount = cpu_to_le16(byte_count);
5634 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5635 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5636 	if (rc)
5637 		cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5638 
5639 	cifs_buf_release(pSMB);
5640 
5641 	if (rc == -EAGAIN)
5642 		goto SetEOFRetry;
5643 
5644 	return rc;
5645 }
5646 
5647 int
5648 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5649 		   struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5650 {
5651 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5652 	struct file_end_of_file_info *parm_data;
5653 	unsigned int in_len;
5654 	int rc = 0;
5655 	__u16 params, param_offset, offset, byte_count, count;
5656 
5657 	cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5658 		 (long long)size);
5659 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5660 	if (rc < 0)
5661 		return rc;
5662 	in_len = rc;
5663 
5664 	pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5665 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5666 
5667 	params = 6;
5668 	pSMB->MaxSetupCount = 0;
5669 	pSMB->Reserved = 0;
5670 	pSMB->Flags = 0;
5671 	pSMB->Timeout = 0;
5672 	pSMB->Reserved2 = 0;
5673 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
5674 	offset = param_offset + params;
5675 
5676 	count = sizeof(struct file_end_of_file_info);
5677 	pSMB->MaxParameterCount = cpu_to_le16(2);
5678 	/* BB find exact max SMB PDU from sess structure BB */
5679 	pSMB->MaxDataCount = cpu_to_le16(1000);
5680 	pSMB->SetupCount = 1;
5681 	pSMB->Reserved3 = 0;
5682 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5683 	byte_count = 3 /* pad */  + params + count;
5684 	pSMB->DataCount = cpu_to_le16(count);
5685 	pSMB->ParameterCount = cpu_to_le16(params);
5686 	pSMB->TotalDataCount = pSMB->DataCount;
5687 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5688 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5689 	parm_data =
5690 		(struct file_end_of_file_info *)(((char *)pSMB) + offset);
5691 	pSMB->DataOffset = cpu_to_le16(offset);
5692 	parm_data->FileSize = cpu_to_le64(size);
5693 	pSMB->Fid = cfile->fid.netfid;
5694 	if (set_allocation) {
5695 		if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5696 			pSMB->InformationLevel =
5697 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5698 		else
5699 			pSMB->InformationLevel =
5700 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5701 	} else /* Set File Size */  {
5702 	    if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5703 		    pSMB->InformationLevel =
5704 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5705 	    else
5706 		    pSMB->InformationLevel =
5707 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5708 	}
5709 	pSMB->Reserved4 = 0;
5710 	in_len += byte_count;
5711 	pSMB->ByteCount = cpu_to_le16(byte_count);
5712 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
5713 	cifs_small_buf_release(pSMB);
5714 	if (rc) {
5715 		cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5716 			 rc);
5717 	}
5718 
5719 	/* Note: On -EAGAIN error only caller can retry on handle based calls
5720 		since file handle passed in no longer valid */
5721 
5722 	return rc;
5723 }
5724 
5725 int SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon,
5726 		      const char *fileName, __le32 attributes,
5727 		      __le64 write_time, struct cifs_sb_info *cifs_sb)
5728 {
5729 	SETATTR_REQ *pSMB;
5730 	SETATTR_RSP *pSMBr;
5731 	struct timespec64 ts;
5732 	unsigned int in_len;
5733 	int bytes_returned;
5734 	int name_len;
5735 	int rc;
5736 
5737 	cifs_dbg(FYI, "In %s path %s\n", __func__, fileName);
5738 
5739 retry:
5740 	rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
5741 		      (void **) &pSMBr);
5742 	if (rc < 0)
5743 		return rc;
5744 	in_len = rc;
5745 
5746 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5747 		name_len =
5748 			cifsConvertToUTF16((__le16 *) pSMB->fileName,
5749 					   fileName, PATH_MAX,
5750 					   tcon->ses->local_nls,
5751 					   cifs_remap(cifs_sb));
5752 		name_len++;     /* trailing null */
5753 		name_len *= 2;
5754 	} else {
5755 		name_len = copy_path_name(pSMB->fileName, fileName);
5756 	}
5757 	/* Only few attributes can be set by this command, others are not accepted by Win9x. */
5758 	pSMB->attr = cpu_to_le16(le32_to_cpu(attributes) &
5759 			(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE));
5760 	/* Zero write time value (in both NT and SETATTR formats) means to not change it. */
5761 	if (le64_to_cpu(write_time) != 0) {
5762 		ts = cifs_NTtimeToUnix(write_time);
5763 		pSMB->last_write_time = cpu_to_le32(ts.tv_sec);
5764 	}
5765 	pSMB->BufferFormat = 0x04;
5766 	name_len++; /* account for buffer type byte */
5767 	in_len += name_len;
5768 	pSMB->ByteCount = cpu_to_le16(name_len);
5769 
5770 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5771 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5772 	if (rc)
5773 		cifs_dbg(FYI, "Send error in %s = %d\n", __func__, rc);
5774 
5775 	cifs_buf_release(pSMB);
5776 
5777 	if (rc == -EAGAIN)
5778 		goto retry;
5779 
5780 	return rc;
5781 }
5782 
5783 /* Some legacy servers such as NT4 require that the file times be set on
5784    an open handle, rather than by pathname - this is awkward due to
5785    potential access conflicts on the open, but it is unavoidable for these
5786    old servers since the only other choice is to go from 100 nanosecond DCE
5787    time and resort to the original setpathinfo level which takes the ancient
5788    DOS time format with 2 second granularity */
5789 int
5790 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5791 		    const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5792 {
5793 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5794 	unsigned int in_len;
5795 	char *data_offset;
5796 	int rc = 0;
5797 	__u16 params, param_offset, offset, byte_count, count;
5798 
5799 	cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5800 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5801 	if (rc < 0)
5802 		return rc;
5803 	in_len = rc;
5804 
5805 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5806 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5807 
5808 	params = 6;
5809 	pSMB->MaxSetupCount = 0;
5810 	pSMB->Reserved = 0;
5811 	pSMB->Flags = 0;
5812 	pSMB->Timeout = 0;
5813 	pSMB->Reserved2 = 0;
5814 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
5815 	offset = param_offset + params;
5816 
5817 	data_offset = (char *)pSMB + offset;
5818 
5819 	count = sizeof(FILE_BASIC_INFO);
5820 	pSMB->MaxParameterCount = cpu_to_le16(2);
5821 	/* BB find max SMB PDU from sess */
5822 	pSMB->MaxDataCount = cpu_to_le16(1000);
5823 	pSMB->SetupCount = 1;
5824 	pSMB->Reserved3 = 0;
5825 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5826 	byte_count = 3 /* pad */  + params + count;
5827 	pSMB->DataCount = cpu_to_le16(count);
5828 	pSMB->ParameterCount = cpu_to_le16(params);
5829 	pSMB->TotalDataCount = pSMB->DataCount;
5830 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5831 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5832 	pSMB->DataOffset = cpu_to_le16(offset);
5833 	pSMB->Fid = fid;
5834 	if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5835 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5836 	else
5837 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5838 	pSMB->Reserved4 = 0;
5839 	in_len += byte_count;
5840 	pSMB->ByteCount = cpu_to_le16(byte_count);
5841 	memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5842 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
5843 	cifs_small_buf_release(pSMB);
5844 	if (rc)
5845 		cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5846 			 rc);
5847 
5848 	/* Note: On -EAGAIN error only caller can retry on handle based calls
5849 		since file handle passed in no longer valid */
5850 
5851 	return rc;
5852 }
5853 
5854 int
5855 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5856 			  bool delete_file, __u16 fid, __u32 pid_of_opener)
5857 {
5858 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5859 	unsigned int in_len;
5860 	char *data_offset;
5861 	int rc = 0;
5862 	__u16 params, param_offset, offset, byte_count, count;
5863 
5864 	cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5865 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5866 	if (rc < 0)
5867 		return rc;
5868 	in_len = rc;
5869 
5870 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5871 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5872 
5873 	params = 6;
5874 	pSMB->MaxSetupCount = 0;
5875 	pSMB->Reserved = 0;
5876 	pSMB->Flags = 0;
5877 	pSMB->Timeout = 0;
5878 	pSMB->Reserved2 = 0;
5879 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
5880 	offset = param_offset + params;
5881 	data_offset = (char *)(pSMB) + offset;
5882 
5883 	count = 1;
5884 	pSMB->MaxParameterCount = cpu_to_le16(2);
5885 	/* BB find max SMB PDU from sess */
5886 	pSMB->MaxDataCount = cpu_to_le16(1000);
5887 	pSMB->SetupCount = 1;
5888 	pSMB->Reserved3 = 0;
5889 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5890 	byte_count = 3 /* pad */  + params + count;
5891 	pSMB->DataCount = cpu_to_le16(count);
5892 	pSMB->ParameterCount = cpu_to_le16(params);
5893 	pSMB->TotalDataCount = pSMB->DataCount;
5894 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5895 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5896 	pSMB->DataOffset = cpu_to_le16(offset);
5897 	pSMB->Fid = fid;
5898 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5899 	pSMB->Reserved4 = 0;
5900 	in_len += byte_count;
5901 	pSMB->ByteCount = cpu_to_le16(byte_count);
5902 	*data_offset = delete_file ? 1 : 0;
5903 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
5904 	cifs_small_buf_release(pSMB);
5905 	if (rc)
5906 		cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5907 
5908 	return rc;
5909 }
5910 
5911 int CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5912 		       const char *fileName, const FILE_BASIC_INFO *data,
5913 		       struct cifs_sb_info *cifs_sb)
5914 {
5915 	TRANSACTION2_SPI_REQ *pSMB = NULL;
5916 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
5917 	unsigned int in_len;
5918 	int name_len;
5919 	int rc = 0;
5920 	int bytes_returned = 0;
5921 	char *data_offset;
5922 	__u16 params, param_offset, offset, byte_count, count;
5923 	int remap = cifs_remap(cifs_sb);
5924 
5925 	cifs_dbg(FYI, "In SetTimes\n");
5926 
5927 SetTimesRetry:
5928 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5929 		      (void **) &pSMBr);
5930 	if (rc < 0)
5931 		return rc;
5932 	in_len = rc;
5933 
5934 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5935 		name_len =
5936 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5937 				       PATH_MAX, tcon->ses->local_nls, remap);
5938 		name_len++;	/* trailing null */
5939 		name_len *= 2;
5940 	} else {
5941 		name_len = copy_path_name(pSMB->FileName, fileName);
5942 	}
5943 
5944 	params = 6 + name_len;
5945 	count = sizeof(FILE_BASIC_INFO);
5946 	pSMB->MaxParameterCount = cpu_to_le16(2);
5947 	/* BB find max SMB PDU from sess structure BB */
5948 	pSMB->MaxDataCount = cpu_to_le16(1000);
5949 	pSMB->MaxSetupCount = 0;
5950 	pSMB->Reserved = 0;
5951 	pSMB->Flags = 0;
5952 	pSMB->Timeout = 0;
5953 	pSMB->Reserved2 = 0;
5954 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
5955 				InformationLevel);
5956 	offset = param_offset + params;
5957 	data_offset = (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + offset;
5958 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5959 	pSMB->DataOffset = cpu_to_le16(offset);
5960 	pSMB->SetupCount = 1;
5961 	pSMB->Reserved3 = 0;
5962 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5963 	byte_count = 3 /* pad */  + params + count;
5964 
5965 	pSMB->DataCount = cpu_to_le16(count);
5966 	pSMB->ParameterCount = cpu_to_le16(params);
5967 	pSMB->TotalDataCount = pSMB->DataCount;
5968 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5969 	if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5970 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5971 	else
5972 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5973 	pSMB->Reserved4 = 0;
5974 	in_len += byte_count;
5975 	memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5976 	pSMB->ByteCount = cpu_to_le16(byte_count);
5977 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
5978 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5979 	if (rc)
5980 		cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5981 
5982 	cifs_buf_release(pSMB);
5983 
5984 	if (rc == -EAGAIN)
5985 		goto SetTimesRetry;
5986 
5987 	return rc;
5988 }
5989 
5990 static void
5991 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5992 			const struct cifs_unix_set_info_args *args)
5993 {
5994 	u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5995 	u64 mode = args->mode;
5996 
5997 	if (uid_valid(args->uid))
5998 		uid = from_kuid(&init_user_ns, args->uid);
5999 	if (gid_valid(args->gid))
6000 		gid = from_kgid(&init_user_ns, args->gid);
6001 
6002 	/*
6003 	 * Samba server ignores set of file size to zero due to bugs in some
6004 	 * older clients, but we should be precise - we use SetFileSize to
6005 	 * set file size and do not want to truncate file size to zero
6006 	 * accidentally as happened on one Samba server beta by putting
6007 	 * zero instead of -1 here
6008 	 */
6009 	data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
6010 	data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
6011 	data_offset->LastStatusChange = cpu_to_le64(args->ctime);
6012 	data_offset->LastAccessTime = cpu_to_le64(args->atime);
6013 	data_offset->LastModificationTime = cpu_to_le64(args->mtime);
6014 	data_offset->Uid = cpu_to_le64(uid);
6015 	data_offset->Gid = cpu_to_le64(gid);
6016 	/* better to leave device as zero when it is  */
6017 	data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
6018 	data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
6019 	data_offset->Permissions = cpu_to_le64(mode);
6020 
6021 	if (S_ISREG(mode))
6022 		data_offset->Type = cpu_to_le32(UNIX_FILE);
6023 	else if (S_ISDIR(mode))
6024 		data_offset->Type = cpu_to_le32(UNIX_DIR);
6025 	else if (S_ISLNK(mode))
6026 		data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
6027 	else if (S_ISCHR(mode))
6028 		data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
6029 	else if (S_ISBLK(mode))
6030 		data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
6031 	else if (S_ISFIFO(mode))
6032 		data_offset->Type = cpu_to_le32(UNIX_FIFO);
6033 	else if (S_ISSOCK(mode))
6034 		data_offset->Type = cpu_to_le32(UNIX_SOCKET);
6035 }
6036 
6037 int
6038 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
6039 		       const struct cifs_unix_set_info_args *args,
6040 		       u16 fid, u32 pid_of_opener)
6041 {
6042 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
6043 	unsigned int in_len;
6044 	char *data_offset;
6045 	int rc = 0;
6046 	u16 params, param_offset, offset, byte_count, count;
6047 
6048 	cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
6049 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
6050 	if (rc < 0)
6051 		return rc;
6052 	in_len = rc;
6053 
6054 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
6055 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
6056 
6057 	params = 6;
6058 	pSMB->MaxSetupCount = 0;
6059 	pSMB->Reserved = 0;
6060 	pSMB->Flags = 0;
6061 	pSMB->Timeout = 0;
6062 	pSMB->Reserved2 = 0;
6063 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
6064 	offset = param_offset + params;
6065 
6066 	data_offset = (char *)pSMB + offset;
6067 
6068 	count = sizeof(FILE_UNIX_BASIC_INFO);
6069 
6070 	pSMB->MaxParameterCount = cpu_to_le16(2);
6071 	/* BB find max SMB PDU from sess */
6072 	pSMB->MaxDataCount = cpu_to_le16(1000);
6073 	pSMB->SetupCount = 1;
6074 	pSMB->Reserved3 = 0;
6075 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
6076 	byte_count = 3 /* pad */  + params + count;
6077 	pSMB->DataCount = cpu_to_le16(count);
6078 	pSMB->ParameterCount = cpu_to_le16(params);
6079 	pSMB->TotalDataCount = pSMB->DataCount;
6080 	pSMB->TotalParameterCount = pSMB->ParameterCount;
6081 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
6082 	pSMB->DataOffset = cpu_to_le16(offset);
6083 	pSMB->Fid = fid;
6084 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6085 	pSMB->Reserved4 = 0;
6086 	in_len += byte_count;
6087 	pSMB->ByteCount = cpu_to_le16(byte_count);
6088 
6089 	cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
6090 
6091 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
6092 	cifs_small_buf_release(pSMB);
6093 	if (rc)
6094 		cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
6095 			 rc);
6096 
6097 	/* Note: On -EAGAIN error only caller can retry on handle based calls
6098 		since file handle passed in no longer valid */
6099 
6100 	return rc;
6101 }
6102 
6103 int
6104 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
6105 		       const char *file_name,
6106 		       const struct cifs_unix_set_info_args *args,
6107 		       const struct nls_table *nls_codepage, int remap)
6108 {
6109 	TRANSACTION2_SPI_REQ *pSMB = NULL;
6110 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
6111 	unsigned int in_len;
6112 	int name_len;
6113 	int rc = 0;
6114 	int bytes_returned = 0;
6115 	FILE_UNIX_BASIC_INFO *data_offset;
6116 	__u16 params, param_offset, offset, count, byte_count;
6117 
6118 	cifs_dbg(FYI, "In SetUID/GID/Mode\n");
6119 setPermsRetry:
6120 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6121 		      (void **) &pSMBr);
6122 	if (rc < 0)
6123 		return rc;
6124 	in_len = rc;
6125 
6126 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6127 		name_len =
6128 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6129 				       PATH_MAX, nls_codepage, remap);
6130 		name_len++;	/* trailing null */
6131 		name_len *= 2;
6132 	} else {
6133 		name_len = copy_path_name(pSMB->FileName, file_name);
6134 	}
6135 
6136 	params = 6 + name_len;
6137 	count = sizeof(FILE_UNIX_BASIC_INFO);
6138 	pSMB->MaxParameterCount = cpu_to_le16(2);
6139 	/* BB find max SMB PDU from sess structure BB */
6140 	pSMB->MaxDataCount = cpu_to_le16(1000);
6141 	pSMB->MaxSetupCount = 0;
6142 	pSMB->Reserved = 0;
6143 	pSMB->Flags = 0;
6144 	pSMB->Timeout = 0;
6145 	pSMB->Reserved2 = 0;
6146 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
6147 				InformationLevel);
6148 	offset = param_offset + params;
6149 	data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset);
6150 	memset(data_offset, 0, count);
6151 	pSMB->DataOffset = cpu_to_le16(offset);
6152 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
6153 	pSMB->SetupCount = 1;
6154 	pSMB->Reserved3 = 0;
6155 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6156 	byte_count = 3 /* pad */  + params + count;
6157 	pSMB->ParameterCount = cpu_to_le16(params);
6158 	pSMB->DataCount = cpu_to_le16(count);
6159 	pSMB->TotalParameterCount = pSMB->ParameterCount;
6160 	pSMB->TotalDataCount = pSMB->DataCount;
6161 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6162 	pSMB->Reserved4 = 0;
6163 	in_len += byte_count;
6164 
6165 	cifs_fill_unix_set_info(data_offset, args);
6166 
6167 	pSMB->ByteCount = cpu_to_le16(byte_count);
6168 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
6169 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6170 	if (rc)
6171 		cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6172 
6173 	cifs_buf_release(pSMB);
6174 	if (rc == -EAGAIN)
6175 		goto setPermsRetry;
6176 	return rc;
6177 }
6178 
6179 #ifdef CONFIG_CIFS_XATTR
6180 /*
6181  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6182  * function used by listxattr and getxattr type calls. When ea_name is set,
6183  * it looks for that attribute name and stuffs that value into the EAData
6184  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6185  * buffer. In both cases, the return value is either the length of the
6186  * resulting data or a negative error code. If EAData is a NULL pointer then
6187  * the data isn't copied to it, but the length is returned.
6188  */
6189 ssize_t
6190 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6191 		const unsigned char *searchName, const unsigned char *ea_name,
6192 		char *EAData, size_t buf_size,
6193 		struct cifs_sb_info *cifs_sb)
6194 {
6195 		/* BB assumes one setup word */
6196 	TRANSACTION2_QPI_REQ *pSMB = NULL;
6197 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
6198 	int remap = cifs_remap(cifs_sb);
6199 	struct nls_table *nls_codepage = cifs_sb->local_nls;
6200 	unsigned int in_len;
6201 	int rc = 0;
6202 	int bytes_returned;
6203 	int list_len;
6204 	struct fealist *ea_response_data;
6205 	struct fea *temp_fea;
6206 	char *temp_ptr;
6207 	char *end_of_smb;
6208 	__u16 params, byte_count, data_offset;
6209 	unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6210 
6211 	cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6212 QAllEAsRetry:
6213 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6214 		      (void **) &pSMBr);
6215 	if (rc < 0)
6216 		return rc;
6217 	in_len = rc;
6218 
6219 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6220 		list_len =
6221 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6222 				       PATH_MAX, nls_codepage, remap);
6223 		list_len++;	/* trailing null */
6224 		list_len *= 2;
6225 	} else {
6226 		list_len = copy_path_name(pSMB->FileName, searchName);
6227 	}
6228 
6229 	params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6230 	pSMB->TotalDataCount = 0;
6231 	pSMB->MaxParameterCount = cpu_to_le16(2);
6232 	/* BB find exact max SMB PDU from sess structure BB */
6233 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6234 	pSMB->MaxSetupCount = 0;
6235 	pSMB->Reserved = 0;
6236 	pSMB->Flags = 0;
6237 	pSMB->Timeout = 0;
6238 	pSMB->Reserved2 = 0;
6239 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
6240 		struct smb_com_transaction2_qpi_req, InformationLevel));
6241 	pSMB->DataCount = 0;
6242 	pSMB->DataOffset = 0;
6243 	pSMB->SetupCount = 1;
6244 	pSMB->Reserved3 = 0;
6245 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6246 	byte_count = params + 1 /* pad */ ;
6247 	pSMB->TotalParameterCount = cpu_to_le16(params);
6248 	pSMB->ParameterCount = pSMB->TotalParameterCount;
6249 	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6250 	pSMB->Reserved4 = 0;
6251 	in_len += byte_count;
6252 	pSMB->ByteCount = cpu_to_le16(byte_count);
6253 
6254 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
6255 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6256 	if (rc) {
6257 		cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6258 		goto QAllEAsOut;
6259 	}
6260 
6261 
6262 	/* BB also check enough total bytes returned */
6263 	/* BB we need to improve the validity checking
6264 	of these trans2 responses */
6265 
6266 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6267 	if (rc || get_bcc(&pSMBr->hdr) < 4) {
6268 		rc = smb_EIO2(smb_eio_trace_qalleas_bcc_too_small,
6269 			      get_bcc(&pSMBr->hdr), 4);
6270 		goto QAllEAsOut;
6271 	}
6272 
6273 	/* check that length of list is not more than bcc */
6274 	/* check that each entry does not go beyond length
6275 	   of list */
6276 	/* check that each element of each entry does not
6277 	   go beyond end of list */
6278 	/* validate_trans2_offsets() */
6279 	/* BB check if start of smb + data_offset > &bcc+ bcc */
6280 
6281 	data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6282 	ea_response_data = (struct fealist *)
6283 				(((char *) &pSMBr->hdr.Protocol) + data_offset);
6284 
6285 	list_len = le32_to_cpu(ea_response_data->list_len);
6286 	cifs_dbg(FYI, "ea length %d\n", list_len);
6287 	if (list_len <= 8) {
6288 		cifs_dbg(FYI, "empty EA list returned from server\n");
6289 		/* didn't find the named attribute */
6290 		if (ea_name)
6291 			rc = -ENODATA;
6292 		goto QAllEAsOut;
6293 	}
6294 
6295 	/* make sure list_len doesn't go past end of SMB */
6296 	end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6297 	if ((char *)ea_response_data + list_len > end_of_smb) {
6298 		cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6299 		rc = smb_EIO2(smb_eio_trace_qalleas_overlong,
6300 			      (unsigned long)ea_response_data + list_len - (unsigned long)pSMBr,
6301 			      (unsigned long)end_of_smb - (unsigned long)pSMBr);
6302 		goto QAllEAsOut;
6303 	}
6304 
6305 	/* account for ea list len */
6306 	list_len -= 4;
6307 	temp_fea = &ea_response_data->list;
6308 	temp_ptr = (char *)temp_fea;
6309 	while (list_len > 0) {
6310 		unsigned int name_len;
6311 		__u16 value_len;
6312 
6313 		list_len -= 4;
6314 		temp_ptr += 4;
6315 		/* make sure we can read name_len and value_len */
6316 		if (list_len < 0) {
6317 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6318 			rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
6319 			goto QAllEAsOut;
6320 		}
6321 
6322 		name_len = temp_fea->name_len;
6323 		value_len = le16_to_cpu(temp_fea->value_len);
6324 		list_len -= name_len + 1 + value_len;
6325 		if (list_len < 0) {
6326 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6327 			rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
6328 			goto QAllEAsOut;
6329 		}
6330 
6331 		if (ea_name) {
6332 			if (ea_name_len == name_len &&
6333 			    memcmp(ea_name, temp_ptr, name_len) == 0) {
6334 				temp_ptr += name_len + 1;
6335 				rc = value_len;
6336 				if (buf_size == 0)
6337 					goto QAllEAsOut;
6338 				if ((size_t)value_len > buf_size) {
6339 					rc = -ERANGE;
6340 					goto QAllEAsOut;
6341 				}
6342 				memcpy(EAData, temp_ptr, value_len);
6343 				goto QAllEAsOut;
6344 			}
6345 		} else {
6346 			/* account for prefix user. and trailing null */
6347 			rc += (5 + 1 + name_len);
6348 			if (rc < (int) buf_size) {
6349 				memcpy(EAData, "user.", 5);
6350 				EAData += 5;
6351 				memcpy(EAData, temp_ptr, name_len);
6352 				EAData += name_len;
6353 				/* null terminate name */
6354 				*EAData = 0;
6355 				++EAData;
6356 			} else if (buf_size == 0) {
6357 				/* skip copy - calc size only */
6358 			} else {
6359 				/* stop before overrun buffer */
6360 				rc = -ERANGE;
6361 				break;
6362 			}
6363 		}
6364 		temp_ptr += name_len + 1 + value_len;
6365 		temp_fea = (struct fea *)temp_ptr;
6366 	}
6367 
6368 	/* didn't find the named attribute */
6369 	if (ea_name)
6370 		rc = -ENODATA;
6371 
6372 QAllEAsOut:
6373 	cifs_buf_release(pSMB);
6374 	if (rc == -EAGAIN)
6375 		goto QAllEAsRetry;
6376 
6377 	return (ssize_t)rc;
6378 }
6379 
6380 int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6381 		 const char *fileName, const char *ea_name,
6382 		 const void *ea_value, const __u16 ea_value_len,
6383 		 struct cifs_sb_info *cifs_sb)
6384 {
6385 	struct smb_com_transaction2_spi_req *pSMB = NULL;
6386 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6387 	struct fealist *parm_data;
6388 	unsigned int in_len;
6389 	int name_len;
6390 	int rc = 0;
6391 	int bytes_returned = 0;
6392 	__u16 params, param_offset;
6393 	unsigned int byte_count, offset, count;
6394 	int remap = cifs_remap(cifs_sb);
6395 	unsigned int total_len;
6396 
6397 	cifs_dbg(FYI, "In SetEA\n");
6398 SetEARetry:
6399 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6400 		      (void **) &pSMBr);
6401 	if (rc < 0)
6402 		return rc;
6403 	in_len = rc;
6404 
6405 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6406 		name_len =
6407 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6408 				       PATH_MAX, tcon->ses->local_nls, remap);
6409 		name_len++;	/* trailing null */
6410 		name_len *= 2;
6411 	} else {
6412 		name_len = copy_path_name(pSMB->FileName, fileName);
6413 	}
6414 
6415 	params = 6 + name_len;
6416 
6417 	/* done calculating parms using name_len of file name,
6418 	now use name_len to calculate length of ea name
6419 	we are going to create in the inode xattrs */
6420 	if (ea_name == NULL)
6421 		name_len = 0;
6422 	else
6423 		name_len = strnlen(ea_name, 255);
6424 
6425 	count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
6426 	pSMB->MaxParameterCount = cpu_to_le16(2);
6427 	/* BB find max SMB PDU from sess */
6428 	pSMB->MaxDataCount = cpu_to_le16(1000);
6429 	pSMB->MaxSetupCount = 0;
6430 	pSMB->Reserved = 0;
6431 	pSMB->Flags = 0;
6432 	pSMB->Timeout = 0;
6433 	pSMB->Reserved2 = 0;
6434 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
6435 				InformationLevel);
6436 	offset = param_offset + params;
6437 	pSMB->InformationLevel =
6438 		cpu_to_le16(SMB_SET_FILE_EA);
6439 
6440 	parm_data = (void *)pSMB + offset;
6441 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
6442 	pSMB->DataOffset = cpu_to_le16(offset);
6443 	pSMB->SetupCount = 1;
6444 	pSMB->Reserved3 = 0;
6445 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6446 	byte_count = 3 /* pad */  + params + count;
6447 	if (check_add_overflow(in_len, byte_count, &total_len) ||
6448 	    byte_count > U16_MAX ||
6449 	    total_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
6450 		cifs_dbg(VFS, "EA request too large: %u bytes\n", total_len);
6451 		cifs_buf_release(pSMB);
6452 		return -E2BIG;
6453 	}
6454 	pSMB->DataCount = cpu_to_le16(count);
6455 	parm_data->list_len = cpu_to_le32(count);
6456 	parm_data->list.EA_flags = 0;
6457 	/* we checked above that name len is less than 255 */
6458 	parm_data->list.name_len = (__u8)name_len;
6459 	/* EA names are always ASCII and NUL-terminated */
6460 	strscpy(parm_data->list.name, ea_name ?: "", name_len + 1);
6461 	parm_data->list.value_len = cpu_to_le16(ea_value_len);
6462 	/* caller ensures that ea_value_len is less than 64K but
6463 	we need to ensure that it fits within the smb */
6464 
6465 	/*BB add length check to see if it would fit in
6466 	     negotiated SMB buffer size BB */
6467 	/* if (ea_value_len > buffer_size - 512 (enough for header)) */
6468 	if (ea_value_len)
6469 		memcpy(parm_data->list.name + name_len + 1,
6470 		       ea_value, ea_value_len);
6471 
6472 	pSMB->TotalDataCount = pSMB->DataCount;
6473 	pSMB->ParameterCount = cpu_to_le16(params);
6474 	pSMB->TotalParameterCount = pSMB->ParameterCount;
6475 	pSMB->Reserved4 = 0;
6476 	in_len += byte_count;
6477 	pSMB->ByteCount = cpu_to_le16(byte_count);
6478 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
6479 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6480 	if (rc)
6481 		cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6482 
6483 	cifs_buf_release(pSMB);
6484 
6485 	if (rc == -EAGAIN)
6486 		goto SetEARetry;
6487 
6488 	return rc;
6489 }
6490 #endif
6491