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