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