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