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