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