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