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