xref: /openbmc/linux/fs/smb/client/cifssmb.c (revision 236a9bf2)
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
2153 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
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
2534 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2535 		   const char *from_name, const char *to_name,
2536 		   struct cifs_sb_info *cifs_sb)
2537 {
2538 	int rc = 0;
2539 	NT_RENAME_REQ *pSMB = NULL;
2540 	RENAME_RSP *pSMBr = NULL;
2541 	int bytes_returned;
2542 	int name_len, name_len2;
2543 	__u16 count;
2544 	int remap = cifs_remap(cifs_sb);
2545 
2546 	cifs_dbg(FYI, "In CIFSCreateHardLink\n");
2547 winCreateHardLinkRetry:
2548 
2549 	rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
2550 		      (void **) &pSMBr);
2551 	if (rc)
2552 		return rc;
2553 
2554 	pSMB->SearchAttributes =
2555 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2556 			ATTR_DIRECTORY);
2557 	pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
2558 	pSMB->ClusterCount = 0;
2559 
2560 	pSMB->BufferFormat = 0x04;
2561 
2562 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2563 		name_len =
2564 		    cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
2565 				       PATH_MAX, cifs_sb->local_nls, remap);
2566 		name_len++;	/* trailing null */
2567 		name_len *= 2;
2568 
2569 		/* protocol specifies ASCII buffer format (0x04) for unicode */
2570 		pSMB->OldFileName[name_len] = 0x04;
2571 		pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
2572 		name_len2 =
2573 		    cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2574 				       to_name, PATH_MAX, cifs_sb->local_nls,
2575 				       remap);
2576 		name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2577 		name_len2 *= 2;	/* convert to bytes */
2578 	} else {
2579 		name_len = copy_path_name(pSMB->OldFileName, from_name);
2580 		pSMB->OldFileName[name_len] = 0x04;	/* 2nd buffer format */
2581 		name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2582 		name_len2++;	/* signature byte */
2583 	}
2584 
2585 	count = 1 /* string type byte */  + name_len + name_len2;
2586 	inc_rfc1001_len(pSMB, count);
2587 	pSMB->ByteCount = cpu_to_le16(count);
2588 
2589 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2590 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2591 	cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
2592 	if (rc)
2593 		cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
2594 
2595 	cifs_buf_release(pSMB);
2596 	if (rc == -EAGAIN)
2597 		goto winCreateHardLinkRetry;
2598 
2599 	return rc;
2600 }
2601 
2602 int
2603 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
2604 			const unsigned char *searchName, char **symlinkinfo,
2605 			const struct nls_table *nls_codepage, int remap)
2606 {
2607 /* SMB_QUERY_FILE_UNIX_LINK */
2608 	TRANSACTION2_QPI_REQ *pSMB = NULL;
2609 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
2610 	int rc = 0;
2611 	int bytes_returned;
2612 	int name_len;
2613 	__u16 params, byte_count;
2614 	char *data_start;
2615 
2616 	cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
2617 
2618 querySymLinkRetry:
2619 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2620 		      (void **) &pSMBr);
2621 	if (rc)
2622 		return rc;
2623 
2624 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2625 		name_len =
2626 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
2627 					   searchName, PATH_MAX, nls_codepage,
2628 					   remap);
2629 		name_len++;	/* trailing null */
2630 		name_len *= 2;
2631 	} else {
2632 		name_len = copy_path_name(pSMB->FileName, searchName);
2633 	}
2634 
2635 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
2636 	pSMB->TotalDataCount = 0;
2637 	pSMB->MaxParameterCount = cpu_to_le16(2);
2638 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
2639 	pSMB->MaxSetupCount = 0;
2640 	pSMB->Reserved = 0;
2641 	pSMB->Flags = 0;
2642 	pSMB->Timeout = 0;
2643 	pSMB->Reserved2 = 0;
2644 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
2645 	struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2646 	pSMB->DataCount = 0;
2647 	pSMB->DataOffset = 0;
2648 	pSMB->SetupCount = 1;
2649 	pSMB->Reserved3 = 0;
2650 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2651 	byte_count = params + 1 /* pad */ ;
2652 	pSMB->TotalParameterCount = cpu_to_le16(params);
2653 	pSMB->ParameterCount = pSMB->TotalParameterCount;
2654 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2655 	pSMB->Reserved4 = 0;
2656 	inc_rfc1001_len(pSMB, byte_count);
2657 	pSMB->ByteCount = cpu_to_le16(byte_count);
2658 
2659 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2660 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2661 	if (rc) {
2662 		cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
2663 	} else {
2664 		/* decode response */
2665 
2666 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2667 		/* BB also check enough total bytes returned */
2668 		if (rc || get_bcc(&pSMBr->hdr) < 2)
2669 			rc = -EIO;
2670 		else {
2671 			bool is_unicode;
2672 			u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2673 
2674 			data_start = ((char *) &pSMBr->hdr.Protocol) +
2675 					   le16_to_cpu(pSMBr->t2.DataOffset);
2676 
2677 			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
2678 				is_unicode = true;
2679 			else
2680 				is_unicode = false;
2681 
2682 			/* BB FIXME investigate remapping reserved chars here */
2683 			*symlinkinfo = cifs_strndup_from_utf16(data_start,
2684 					count, is_unicode, nls_codepage);
2685 			if (!*symlinkinfo)
2686 				rc = -ENOMEM;
2687 		}
2688 	}
2689 	cifs_buf_release(pSMB);
2690 	if (rc == -EAGAIN)
2691 		goto querySymLinkRetry;
2692 	return rc;
2693 }
2694 
2695 int cifs_query_reparse_point(const unsigned int xid,
2696 			     struct cifs_tcon *tcon,
2697 			     struct cifs_sb_info *cifs_sb,
2698 			     const char *full_path,
2699 			     u32 *tag, struct kvec *rsp,
2700 			     int *rsp_buftype)
2701 {
2702 	struct cifs_open_parms oparms;
2703 	TRANSACT_IOCTL_REQ *io_req = NULL;
2704 	TRANSACT_IOCTL_RSP *io_rsp = NULL;
2705 	struct cifs_fid fid;
2706 	__u32 data_offset, data_count;
2707 	__u8 *start, *end;
2708 	int io_rsp_len;
2709 	int oplock = 0;
2710 	int rc;
2711 
2712 	cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
2713 
2714 	if (cap_unix(tcon->ses))
2715 		return -EOPNOTSUPP;
2716 
2717 	oparms = (struct cifs_open_parms) {
2718 		.tcon = tcon,
2719 		.cifs_sb = cifs_sb,
2720 		.desired_access = FILE_READ_ATTRIBUTES,
2721 		.create_options = cifs_create_options(cifs_sb,
2722 						      OPEN_REPARSE_POINT),
2723 		.disposition = FILE_OPEN,
2724 		.path = full_path,
2725 		.fid = &fid,
2726 	};
2727 
2728 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
2729 	if (rc)
2730 		return rc;
2731 
2732 	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
2733 		      (void **)&io_req, (void **)&io_rsp);
2734 	if (rc)
2735 		goto error;
2736 
2737 	io_req->TotalParameterCount = 0;
2738 	io_req->TotalDataCount = 0;
2739 	io_req->MaxParameterCount = cpu_to_le32(2);
2740 	/* BB find exact data count max from sess structure BB */
2741 	io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
2742 	io_req->MaxSetupCount = 4;
2743 	io_req->Reserved = 0;
2744 	io_req->ParameterOffset = 0;
2745 	io_req->DataCount = 0;
2746 	io_req->DataOffset = 0;
2747 	io_req->SetupCount = 4;
2748 	io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2749 	io_req->ParameterCount = io_req->TotalParameterCount;
2750 	io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
2751 	io_req->IsFsctl = 1;
2752 	io_req->IsRootFlag = 0;
2753 	io_req->Fid = fid.netfid;
2754 	io_req->ByteCount = 0;
2755 
2756 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req,
2757 			 (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
2758 	if (rc)
2759 		goto error;
2760 
2761 	data_offset = le32_to_cpu(io_rsp->DataOffset);
2762 	data_count = le32_to_cpu(io_rsp->DataCount);
2763 	if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
2764 	    !data_count || data_count > 2048) {
2765 		rc = -EIO;
2766 		goto error;
2767 	}
2768 
2769 	end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
2770 	start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
2771 	if (start >= end) {
2772 		rc = -EIO;
2773 		goto error;
2774 	}
2775 
2776 	*tag = le32_to_cpu(((struct reparse_data_buffer *)start)->ReparseTag);
2777 	rsp->iov_base = io_rsp;
2778 	rsp->iov_len = io_rsp_len;
2779 	*rsp_buftype = CIFS_LARGE_BUFFER;
2780 	CIFSSMBClose(xid, tcon, fid.netfid);
2781 	return 0;
2782 
2783 error:
2784 	cifs_buf_release(io_req);
2785 	CIFSSMBClose(xid, tcon, fid.netfid);
2786 	return rc;
2787 }
2788 
2789 int
2790 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2791 		    __u16 fid)
2792 {
2793 	int rc = 0;
2794 	int bytes_returned;
2795 	struct smb_com_transaction_compr_ioctl_req *pSMB;
2796 	struct smb_com_transaction_ioctl_rsp *pSMBr;
2797 
2798 	cifs_dbg(FYI, "Set compression for %u\n", fid);
2799 	rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2800 		      (void **) &pSMBr);
2801 	if (rc)
2802 		return rc;
2803 
2804 	pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
2805 
2806 	pSMB->TotalParameterCount = 0;
2807 	pSMB->TotalDataCount = cpu_to_le32(2);
2808 	pSMB->MaxParameterCount = 0;
2809 	pSMB->MaxDataCount = 0;
2810 	pSMB->MaxSetupCount = 4;
2811 	pSMB->Reserved = 0;
2812 	pSMB->ParameterOffset = 0;
2813 	pSMB->DataCount = cpu_to_le32(2);
2814 	pSMB->DataOffset =
2815 		cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
2816 				compression_state) - 4);  /* 84 */
2817 	pSMB->SetupCount = 4;
2818 	pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
2819 	pSMB->ParameterCount = 0;
2820 	pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
2821 	pSMB->IsFsctl = 1; /* FSCTL */
2822 	pSMB->IsRootFlag = 0;
2823 	pSMB->Fid = fid; /* file handle always le */
2824 	/* 3 byte pad, followed by 2 byte compress state */
2825 	pSMB->ByteCount = cpu_to_le16(5);
2826 	inc_rfc1001_len(pSMB, 5);
2827 
2828 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2829 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2830 	if (rc)
2831 		cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
2832 
2833 	cifs_buf_release(pSMB);
2834 
2835 	/*
2836 	 * Note: On -EAGAIN error only caller can retry on handle based calls
2837 	 * since file handle passed in no longer valid.
2838 	 */
2839 	return rc;
2840 }
2841 
2842 
2843 #ifdef CONFIG_CIFS_POSIX
2844 
2845 #ifdef CONFIG_FS_POSIX_ACL
2846 /**
2847  * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format
2848  * @ace: POSIX ACL entry to store converted ACL into
2849  * @cifs_ace: ACL in cifs format
2850  *
2851  * Convert an Access Control Entry from wire format to local POSIX xattr
2852  * format.
2853  *
2854  * Note that the @cifs_uid member is used to store both {g,u}id_t.
2855  */
2856 static void cifs_init_posix_acl(struct posix_acl_entry *ace,
2857 				struct cifs_posix_ace *cifs_ace)
2858 {
2859 	/* u8 cifs fields do not need le conversion */
2860 	ace->e_perm = cifs_ace->cifs_e_perm;
2861 	ace->e_tag = cifs_ace->cifs_e_tag;
2862 
2863 	switch (ace->e_tag) {
2864 	case ACL_USER:
2865 		ace->e_uid = make_kuid(&init_user_ns,
2866 				       le64_to_cpu(cifs_ace->cifs_uid));
2867 		break;
2868 	case ACL_GROUP:
2869 		ace->e_gid = make_kgid(&init_user_ns,
2870 				       le64_to_cpu(cifs_ace->cifs_uid));
2871 		break;
2872 	}
2873 	return;
2874 }
2875 
2876 /**
2877  * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format
2878  * @acl: ACLs returned in POSIX ACL format
2879  * @src: ACLs in cifs format
2880  * @acl_type: type of POSIX ACL requested
2881  * @size_of_data_area: size of SMB we got
2882  *
2883  * This function converts ACLs from cifs format to POSIX ACL format.
2884  * If @acl is NULL then the size of the buffer required to store POSIX ACLs in
2885  * their uapi format is returned.
2886  */
2887 static int cifs_to_posix_acl(struct posix_acl **acl, char *src,
2888 			     const int acl_type, const int size_of_data_area)
2889 {
2890 	int size =  0;
2891 	__u16 count;
2892 	struct cifs_posix_ace *pACE;
2893 	struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2894 	struct posix_acl *kacl = NULL;
2895 	struct posix_acl_entry *pa, *pe;
2896 
2897 	if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2898 		return -EOPNOTSUPP;
2899 
2900 	if (acl_type == ACL_TYPE_ACCESS) {
2901 		count = le16_to_cpu(cifs_acl->access_entry_count);
2902 		pACE = &cifs_acl->ace_array[0];
2903 		size = sizeof(struct cifs_posix_acl);
2904 		size += sizeof(struct cifs_posix_ace) * count;
2905 		/* check if we would go beyond end of SMB */
2906 		if (size_of_data_area < size) {
2907 			cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
2908 				 size_of_data_area, size);
2909 			return -EINVAL;
2910 		}
2911 	} else if (acl_type == ACL_TYPE_DEFAULT) {
2912 		count = le16_to_cpu(cifs_acl->access_entry_count);
2913 		size = sizeof(struct cifs_posix_acl);
2914 		size += sizeof(struct cifs_posix_ace) * count;
2915 		/* skip past access ACEs to get to default ACEs */
2916 		pACE = &cifs_acl->ace_array[count];
2917 		count = le16_to_cpu(cifs_acl->default_entry_count);
2918 		size += sizeof(struct cifs_posix_ace) * count;
2919 		/* check if we would go beyond end of SMB */
2920 		if (size_of_data_area < size)
2921 			return -EINVAL;
2922 	} else {
2923 		/* illegal type */
2924 		return -EINVAL;
2925 	}
2926 
2927 	/* Allocate number of POSIX ACLs to store in VFS format. */
2928 	kacl = posix_acl_alloc(count, GFP_NOFS);
2929 	if (!kacl)
2930 		return -ENOMEM;
2931 
2932 	FOREACH_ACL_ENTRY(pa, kacl, pe) {
2933 		cifs_init_posix_acl(pa, pACE);
2934 		pACE++;
2935 	}
2936 
2937 	*acl = kacl;
2938 	return 0;
2939 }
2940 
2941 /**
2942  * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format
2943  * @cifs_ace: the cifs ACL entry to store into
2944  * @local_ace: the POSIX ACL entry to convert
2945  */
2946 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
2947 			  const struct posix_acl_entry *local_ace)
2948 {
2949 	cifs_ace->cifs_e_perm = local_ace->e_perm;
2950 	cifs_ace->cifs_e_tag =  local_ace->e_tag;
2951 
2952 	switch (local_ace->e_tag) {
2953 	case ACL_USER:
2954 		cifs_ace->cifs_uid =
2955 			cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid));
2956 		break;
2957 	case ACL_GROUP:
2958 		cifs_ace->cifs_uid =
2959 			cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid));
2960 		break;
2961 	default:
2962 		cifs_ace->cifs_uid = cpu_to_le64(-1);
2963 	}
2964 }
2965 
2966 /**
2967  * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
2968  * @parm_data: ACLs in cifs format to conver to
2969  * @acl: ACLs in POSIX ACL format to convert from
2970  * @acl_type: the type of POSIX ACLs stored in @acl
2971  *
2972  * Return: the number cifs ACL entries after conversion
2973  */
2974 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl,
2975 			       const int acl_type)
2976 {
2977 	__u16 rc = 0;
2978 	struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2979 	const struct posix_acl_entry *pa, *pe;
2980 	int count;
2981 	int i = 0;
2982 
2983 	if ((acl == NULL) || (cifs_acl == NULL))
2984 		return 0;
2985 
2986 	count = acl->a_count;
2987 	cifs_dbg(FYI, "setting acl with %d entries\n", count);
2988 
2989 	/*
2990 	 * Note that the uapi POSIX ACL version is verified by the VFS and is
2991 	 * independent of the cifs ACL version. Changing the POSIX ACL version
2992 	 * is a uapi change and if it's changed we will pass down the POSIX ACL
2993 	 * version in struct posix_acl from the VFS. For now there's really
2994 	 * only one that all filesystems know how to deal with.
2995 	 */
2996 	cifs_acl->version = cpu_to_le16(1);
2997 	if (acl_type == ACL_TYPE_ACCESS) {
2998 		cifs_acl->access_entry_count = cpu_to_le16(count);
2999 		cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3000 	} else if (acl_type == ACL_TYPE_DEFAULT) {
3001 		cifs_acl->default_entry_count = cpu_to_le16(count);
3002 		cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3003 	} else {
3004 		cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3005 		return 0;
3006 	}
3007 	FOREACH_ACL_ENTRY(pa, acl, pe) {
3008 		cifs_init_ace(&cifs_acl->ace_array[i++], pa);
3009 	}
3010 	if (rc == 0) {
3011 		rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3012 		rc += sizeof(struct cifs_posix_acl);
3013 		/* BB add check to make sure ACL does not overflow SMB */
3014 	}
3015 	return rc;
3016 }
3017 
3018 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3019 		    const unsigned char *searchName, struct posix_acl **acl,
3020 		    const int acl_type, const struct nls_table *nls_codepage,
3021 		    int remap)
3022 {
3023 /* SMB_QUERY_POSIX_ACL */
3024 	TRANSACTION2_QPI_REQ *pSMB = NULL;
3025 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
3026 	int rc = 0;
3027 	int bytes_returned;
3028 	int name_len;
3029 	__u16 params, byte_count;
3030 
3031 	cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3032 
3033 queryAclRetry:
3034 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3035 		(void **) &pSMBr);
3036 	if (rc)
3037 		return rc;
3038 
3039 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3040 		name_len =
3041 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
3042 					   searchName, PATH_MAX, nls_codepage,
3043 					   remap);
3044 		name_len++;     /* trailing null */
3045 		name_len *= 2;
3046 		pSMB->FileName[name_len] = 0;
3047 		pSMB->FileName[name_len+1] = 0;
3048 	} else {
3049 		name_len = copy_path_name(pSMB->FileName, searchName);
3050 	}
3051 
3052 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3053 	pSMB->TotalDataCount = 0;
3054 	pSMB->MaxParameterCount = cpu_to_le16(2);
3055 	/* BB find exact max data count below from sess structure BB */
3056 	pSMB->MaxDataCount = cpu_to_le16(4000);
3057 	pSMB->MaxSetupCount = 0;
3058 	pSMB->Reserved = 0;
3059 	pSMB->Flags = 0;
3060 	pSMB->Timeout = 0;
3061 	pSMB->Reserved2 = 0;
3062 	pSMB->ParameterOffset = cpu_to_le16(
3063 		offsetof(struct smb_com_transaction2_qpi_req,
3064 			 InformationLevel) - 4);
3065 	pSMB->DataCount = 0;
3066 	pSMB->DataOffset = 0;
3067 	pSMB->SetupCount = 1;
3068 	pSMB->Reserved3 = 0;
3069 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3070 	byte_count = params + 1 /* pad */ ;
3071 	pSMB->TotalParameterCount = cpu_to_le16(params);
3072 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3073 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3074 	pSMB->Reserved4 = 0;
3075 	inc_rfc1001_len(pSMB, byte_count);
3076 	pSMB->ByteCount = cpu_to_le16(byte_count);
3077 
3078 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3079 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
3080 	cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3081 	if (rc) {
3082 		cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3083 	} else {
3084 		/* decode response */
3085 
3086 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3087 		/* BB also check enough total bytes returned */
3088 		if (rc || get_bcc(&pSMBr->hdr) < 2)
3089 			rc = -EIO;      /* bad smb */
3090 		else {
3091 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3092 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3093 			rc = cifs_to_posix_acl(acl,
3094 				(char *)&pSMBr->hdr.Protocol+data_offset,
3095 				acl_type, count);
3096 		}
3097 	}
3098 	cifs_buf_release(pSMB);
3099 	/*
3100 	 * The else branch after SendReceive() doesn't return EAGAIN so if we
3101 	 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return
3102 	 * here and don't leak POSIX ACLs.
3103 	 */
3104 	if (rc == -EAGAIN)
3105 		goto queryAclRetry;
3106 	return rc;
3107 }
3108 
3109 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3110 		    const unsigned char *fileName, const struct posix_acl *acl,
3111 		    const int acl_type, const struct nls_table *nls_codepage,
3112 		    int remap)
3113 {
3114 	struct smb_com_transaction2_spi_req *pSMB = NULL;
3115 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3116 	char *parm_data;
3117 	int name_len;
3118 	int rc = 0;
3119 	int bytes_returned = 0;
3120 	__u16 params, byte_count, data_count, param_offset, offset;
3121 
3122 	cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3123 setAclRetry:
3124 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3125 		      (void **) &pSMBr);
3126 	if (rc)
3127 		return rc;
3128 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3129 		name_len =
3130 			cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3131 					   PATH_MAX, nls_codepage, remap);
3132 		name_len++;     /* trailing null */
3133 		name_len *= 2;
3134 	} else {
3135 		name_len = copy_path_name(pSMB->FileName, fileName);
3136 	}
3137 	params = 6 + name_len;
3138 	pSMB->MaxParameterCount = cpu_to_le16(2);
3139 	/* BB find max SMB size from sess */
3140 	pSMB->MaxDataCount = cpu_to_le16(1000);
3141 	pSMB->MaxSetupCount = 0;
3142 	pSMB->Reserved = 0;
3143 	pSMB->Flags = 0;
3144 	pSMB->Timeout = 0;
3145 	pSMB->Reserved2 = 0;
3146 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
3147 				InformationLevel) - 4;
3148 	offset = param_offset + params;
3149 	parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset;
3150 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
3151 
3152 	/* convert to on the wire format for POSIX ACL */
3153 	data_count = posix_acl_to_cifs(parm_data, acl, acl_type);
3154 
3155 	if (data_count == 0) {
3156 		rc = -EOPNOTSUPP;
3157 		goto setACLerrorExit;
3158 	}
3159 	pSMB->DataOffset = cpu_to_le16(offset);
3160 	pSMB->SetupCount = 1;
3161 	pSMB->Reserved3 = 0;
3162 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3163 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3164 	byte_count = 3 /* pad */  + params + data_count;
3165 	pSMB->DataCount = cpu_to_le16(data_count);
3166 	pSMB->TotalDataCount = pSMB->DataCount;
3167 	pSMB->ParameterCount = cpu_to_le16(params);
3168 	pSMB->TotalParameterCount = pSMB->ParameterCount;
3169 	pSMB->Reserved4 = 0;
3170 	inc_rfc1001_len(pSMB, byte_count);
3171 	pSMB->ByteCount = cpu_to_le16(byte_count);
3172 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3173 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3174 	if (rc)
3175 		cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3176 
3177 setACLerrorExit:
3178 	cifs_buf_release(pSMB);
3179 	if (rc == -EAGAIN)
3180 		goto setAclRetry;
3181 	return rc;
3182 }
3183 #else
3184 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
3185 		    const unsigned char *searchName, struct posix_acl **acl,
3186 		    const int acl_type, const struct nls_table *nls_codepage,
3187 		    int remap)
3188 {
3189 	return -EOPNOTSUPP;
3190 }
3191 
3192 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
3193 		    const unsigned char *fileName, const struct posix_acl *acl,
3194 		    const int acl_type, const struct nls_table *nls_codepage,
3195 		    int remap)
3196 {
3197 	return -EOPNOTSUPP;
3198 }
3199 #endif /* CONFIG_FS_POSIX_ACL */
3200 
3201 int
3202 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3203 	       const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3204 {
3205 	int rc = 0;
3206 	struct smb_t2_qfi_req *pSMB = NULL;
3207 	struct smb_t2_qfi_rsp *pSMBr = NULL;
3208 	int bytes_returned;
3209 	__u16 params, byte_count;
3210 
3211 	cifs_dbg(FYI, "In GetExtAttr\n");
3212 	if (tcon == NULL)
3213 		return -ENODEV;
3214 
3215 GetExtAttrRetry:
3216 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3217 		      (void **) &pSMBr);
3218 	if (rc)
3219 		return rc;
3220 
3221 	params = 2 /* level */ + 2 /* fid */;
3222 	pSMB->t2.TotalDataCount = 0;
3223 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3224 	/* BB find exact max data count below from sess structure BB */
3225 	pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3226 	pSMB->t2.MaxSetupCount = 0;
3227 	pSMB->t2.Reserved = 0;
3228 	pSMB->t2.Flags = 0;
3229 	pSMB->t2.Timeout = 0;
3230 	pSMB->t2.Reserved2 = 0;
3231 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3232 					       Fid) - 4);
3233 	pSMB->t2.DataCount = 0;
3234 	pSMB->t2.DataOffset = 0;
3235 	pSMB->t2.SetupCount = 1;
3236 	pSMB->t2.Reserved3 = 0;
3237 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3238 	byte_count = params + 1 /* pad */ ;
3239 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3240 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3241 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3242 	pSMB->Pad = 0;
3243 	pSMB->Fid = netfid;
3244 	inc_rfc1001_len(pSMB, byte_count);
3245 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3246 
3247 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3248 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3249 	if (rc) {
3250 		cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3251 	} else {
3252 		/* decode response */
3253 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3254 		/* BB also check enough total bytes returned */
3255 		if (rc || get_bcc(&pSMBr->hdr) < 2)
3256 			/* If rc should we check for EOPNOSUPP and
3257 			   disable the srvino flag? or in caller? */
3258 			rc = -EIO;      /* bad smb */
3259 		else {
3260 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3261 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3262 			struct file_chattr_info *pfinfo;
3263 
3264 			if (count != 16) {
3265 				cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3266 				rc = -EIO;
3267 				goto GetExtAttrOut;
3268 			}
3269 			pfinfo = (struct file_chattr_info *)
3270 				 (data_offset + (char *) &pSMBr->hdr.Protocol);
3271 			*pExtAttrBits = le64_to_cpu(pfinfo->mode);
3272 			*pMask = le64_to_cpu(pfinfo->mask);
3273 		}
3274 	}
3275 GetExtAttrOut:
3276 	cifs_buf_release(pSMB);
3277 	if (rc == -EAGAIN)
3278 		goto GetExtAttrRetry;
3279 	return rc;
3280 }
3281 
3282 #endif /* CONFIG_POSIX */
3283 
3284 /*
3285  * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3286  * all NT TRANSACTS that we init here have total parm and data under about 400
3287  * bytes (to fit in small cifs buffer size), which is the case so far, it
3288  * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3289  * returned setup area) and MaxParameterCount (returned parms size) must be set
3290  * by caller
3291  */
3292 static int
3293 smb_init_nttransact(const __u16 sub_command, const int setup_count,
3294 		   const int parm_len, struct cifs_tcon *tcon,
3295 		   void **ret_buf)
3296 {
3297 	int rc;
3298 	__u32 temp_offset;
3299 	struct smb_com_ntransact_req *pSMB;
3300 
3301 	rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3302 				(void **)&pSMB);
3303 	if (rc)
3304 		return rc;
3305 	*ret_buf = (void *)pSMB;
3306 	pSMB->Reserved = 0;
3307 	pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3308 	pSMB->TotalDataCount  = 0;
3309 	pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3310 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3311 	pSMB->DataCount  = pSMB->TotalDataCount;
3312 	temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3313 			(setup_count * 2) - 4 /* for rfc1001 length itself */;
3314 	pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3315 	pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3316 	pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3317 	pSMB->SubCommand = cpu_to_le16(sub_command);
3318 	return 0;
3319 }
3320 
3321 static int
3322 validate_ntransact(char *buf, char **ppparm, char **ppdata,
3323 		   __u32 *pparmlen, __u32 *pdatalen)
3324 {
3325 	char *end_of_smb;
3326 	__u32 data_count, data_offset, parm_count, parm_offset;
3327 	struct smb_com_ntransact_rsp *pSMBr;
3328 	u16 bcc;
3329 
3330 	*pdatalen = 0;
3331 	*pparmlen = 0;
3332 
3333 	if (buf == NULL)
3334 		return -EINVAL;
3335 
3336 	pSMBr = (struct smb_com_ntransact_rsp *)buf;
3337 
3338 	bcc = get_bcc(&pSMBr->hdr);
3339 	end_of_smb = 2 /* sizeof byte count */ + bcc +
3340 			(char *)&pSMBr->ByteCount;
3341 
3342 	data_offset = le32_to_cpu(pSMBr->DataOffset);
3343 	data_count = le32_to_cpu(pSMBr->DataCount);
3344 	parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3345 	parm_count = le32_to_cpu(pSMBr->ParameterCount);
3346 
3347 	*ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3348 	*ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3349 
3350 	/* should we also check that parm and data areas do not overlap? */
3351 	if (*ppparm > end_of_smb) {
3352 		cifs_dbg(FYI, "parms start after end of smb\n");
3353 		return -EINVAL;
3354 	} else if (parm_count + *ppparm > end_of_smb) {
3355 		cifs_dbg(FYI, "parm end after end of smb\n");
3356 		return -EINVAL;
3357 	} else if (*ppdata > end_of_smb) {
3358 		cifs_dbg(FYI, "data starts after end of smb\n");
3359 		return -EINVAL;
3360 	} else if (data_count + *ppdata > end_of_smb) {
3361 		cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3362 			 *ppdata, data_count, (data_count + *ppdata),
3363 			 end_of_smb, pSMBr);
3364 		return -EINVAL;
3365 	} else if (parm_count + data_count > bcc) {
3366 		cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3367 		return -EINVAL;
3368 	}
3369 	*pdatalen = data_count;
3370 	*pparmlen = parm_count;
3371 	return 0;
3372 }
3373 
3374 /* Get Security Descriptor (by handle) from remote server for a file or dir */
3375 int
3376 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3377 		  struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3378 {
3379 	int rc = 0;
3380 	int buf_type = 0;
3381 	QUERY_SEC_DESC_REQ *pSMB;
3382 	struct kvec iov[1];
3383 	struct kvec rsp_iov;
3384 
3385 	cifs_dbg(FYI, "GetCifsACL\n");
3386 
3387 	*pbuflen = 0;
3388 	*acl_inf = NULL;
3389 
3390 	rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3391 			8 /* parm len */, tcon, (void **) &pSMB);
3392 	if (rc)
3393 		return rc;
3394 
3395 	pSMB->MaxParameterCount = cpu_to_le32(4);
3396 	/* BB TEST with big acls that might need to be e.g. larger than 16K */
3397 	pSMB->MaxSetupCount = 0;
3398 	pSMB->Fid = fid; /* file handle always le */
3399 	pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3400 				     CIFS_ACL_DACL);
3401 	pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3402 	inc_rfc1001_len(pSMB, 11);
3403 	iov[0].iov_base = (char *)pSMB;
3404 	iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3405 
3406 	rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3407 			  0, &rsp_iov);
3408 	cifs_small_buf_release(pSMB);
3409 	cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3410 	if (rc) {
3411 		cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3412 	} else {                /* decode response */
3413 		__le32 *parm;
3414 		__u32 parm_len;
3415 		__u32 acl_len;
3416 		struct smb_com_ntransact_rsp *pSMBr;
3417 		char *pdata;
3418 
3419 /* validate_nttransact */
3420 		rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3421 					&pdata, &parm_len, pbuflen);
3422 		if (rc)
3423 			goto qsec_out;
3424 		pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3425 
3426 		cifs_dbg(FYI, "smb %p parm %p data %p\n",
3427 			 pSMBr, parm, *acl_inf);
3428 
3429 		if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3430 			rc = -EIO;      /* bad smb */
3431 			*pbuflen = 0;
3432 			goto qsec_out;
3433 		}
3434 
3435 /* BB check that data area is minimum length and as big as acl_len */
3436 
3437 		acl_len = le32_to_cpu(*parm);
3438 		if (acl_len != *pbuflen) {
3439 			cifs_dbg(VFS, "acl length %d does not match %d\n",
3440 				 acl_len, *pbuflen);
3441 			if (*pbuflen > acl_len)
3442 				*pbuflen = acl_len;
3443 		}
3444 
3445 		/* check if buffer is big enough for the acl
3446 		   header followed by the smallest SID */
3447 		if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3448 		    (*pbuflen >= 64 * 1024)) {
3449 			cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3450 			rc = -EINVAL;
3451 			*pbuflen = 0;
3452 		} else {
3453 			*acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3454 			if (*acl_inf == NULL) {
3455 				*pbuflen = 0;
3456 				rc = -ENOMEM;
3457 			}
3458 		}
3459 	}
3460 qsec_out:
3461 	free_rsp_buf(buf_type, rsp_iov.iov_base);
3462 	return rc;
3463 }
3464 
3465 int
3466 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3467 			struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3468 {
3469 	__u16 byte_count, param_count, data_count, param_offset, data_offset;
3470 	int rc = 0;
3471 	int bytes_returned = 0;
3472 	SET_SEC_DESC_REQ *pSMB = NULL;
3473 	void *pSMBr;
3474 
3475 setCifsAclRetry:
3476 	rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3477 	if (rc)
3478 		return rc;
3479 
3480 	pSMB->MaxSetupCount = 0;
3481 	pSMB->Reserved = 0;
3482 
3483 	param_count = 8;
3484 	param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3485 	data_count = acllen;
3486 	data_offset = param_offset + param_count;
3487 	byte_count = 3 /* pad */  + param_count;
3488 
3489 	pSMB->DataCount = cpu_to_le32(data_count);
3490 	pSMB->TotalDataCount = pSMB->DataCount;
3491 	pSMB->MaxParameterCount = cpu_to_le32(4);
3492 	pSMB->MaxDataCount = cpu_to_le32(16384);
3493 	pSMB->ParameterCount = cpu_to_le32(param_count);
3494 	pSMB->ParameterOffset = cpu_to_le32(param_offset);
3495 	pSMB->TotalParameterCount = pSMB->ParameterCount;
3496 	pSMB->DataOffset = cpu_to_le32(data_offset);
3497 	pSMB->SetupCount = 0;
3498 	pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3499 	pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3500 
3501 	pSMB->Fid = fid; /* file handle always le */
3502 	pSMB->Reserved2 = 0;
3503 	pSMB->AclFlags = cpu_to_le32(aclflag);
3504 
3505 	if (pntsd && acllen) {
3506 		memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3507 				data_offset, pntsd, acllen);
3508 		inc_rfc1001_len(pSMB, byte_count + data_count);
3509 	} else
3510 		inc_rfc1001_len(pSMB, byte_count);
3511 
3512 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3513 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
3514 
3515 	cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3516 		 bytes_returned, rc);
3517 	if (rc)
3518 		cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3519 	cifs_buf_release(pSMB);
3520 
3521 	if (rc == -EAGAIN)
3522 		goto setCifsAclRetry;
3523 
3524 	return (rc);
3525 }
3526 
3527 
3528 /* Legacy Query Path Information call for lookup to old servers such
3529    as Win9x/WinME */
3530 int
3531 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3532 		    const char *search_name, FILE_ALL_INFO *data,
3533 		    const struct nls_table *nls_codepage, int remap)
3534 {
3535 	QUERY_INFORMATION_REQ *pSMB;
3536 	QUERY_INFORMATION_RSP *pSMBr;
3537 	int rc = 0;
3538 	int bytes_returned;
3539 	int name_len;
3540 
3541 	cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
3542 QInfRetry:
3543 	rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3544 		      (void **) &pSMBr);
3545 	if (rc)
3546 		return rc;
3547 
3548 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3549 		name_len =
3550 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
3551 					   search_name, PATH_MAX, nls_codepage,
3552 					   remap);
3553 		name_len++;     /* trailing null */
3554 		name_len *= 2;
3555 	} else {
3556 		name_len = copy_path_name(pSMB->FileName, search_name);
3557 	}
3558 	pSMB->BufferFormat = 0x04;
3559 	name_len++; /* account for buffer type byte */
3560 	inc_rfc1001_len(pSMB, (__u16)name_len);
3561 	pSMB->ByteCount = cpu_to_le16(name_len);
3562 
3563 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3564 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3565 	if (rc) {
3566 		cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
3567 	} else if (data) {
3568 		struct timespec64 ts;
3569 		__u32 time = le32_to_cpu(pSMBr->last_write_time);
3570 
3571 		/* decode response */
3572 		/* BB FIXME - add time zone adjustment BB */
3573 		memset(data, 0, sizeof(FILE_ALL_INFO));
3574 		ts.tv_nsec = 0;
3575 		ts.tv_sec = time;
3576 		/* decode time fields */
3577 		data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
3578 		data->LastWriteTime = data->ChangeTime;
3579 		data->LastAccessTime = 0;
3580 		data->AllocationSize =
3581 			cpu_to_le64(le32_to_cpu(pSMBr->size));
3582 		data->EndOfFile = data->AllocationSize;
3583 		data->Attributes =
3584 			cpu_to_le32(le16_to_cpu(pSMBr->attr));
3585 	} else
3586 		rc = -EIO; /* bad buffer passed in */
3587 
3588 	cifs_buf_release(pSMB);
3589 
3590 	if (rc == -EAGAIN)
3591 		goto QInfRetry;
3592 
3593 	return rc;
3594 }
3595 
3596 int
3597 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3598 		 u16 netfid, FILE_ALL_INFO *pFindData)
3599 {
3600 	struct smb_t2_qfi_req *pSMB = NULL;
3601 	struct smb_t2_qfi_rsp *pSMBr = NULL;
3602 	int rc = 0;
3603 	int bytes_returned;
3604 	__u16 params, byte_count;
3605 
3606 QFileInfoRetry:
3607 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3608 		      (void **) &pSMBr);
3609 	if (rc)
3610 		return rc;
3611 
3612 	params = 2 /* level */ + 2 /* fid */;
3613 	pSMB->t2.TotalDataCount = 0;
3614 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3615 	/* BB find exact max data count below from sess structure BB */
3616 	pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3617 	pSMB->t2.MaxSetupCount = 0;
3618 	pSMB->t2.Reserved = 0;
3619 	pSMB->t2.Flags = 0;
3620 	pSMB->t2.Timeout = 0;
3621 	pSMB->t2.Reserved2 = 0;
3622 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3623 					       Fid) - 4);
3624 	pSMB->t2.DataCount = 0;
3625 	pSMB->t2.DataOffset = 0;
3626 	pSMB->t2.SetupCount = 1;
3627 	pSMB->t2.Reserved3 = 0;
3628 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3629 	byte_count = params + 1 /* pad */ ;
3630 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3631 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3632 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3633 	pSMB->Pad = 0;
3634 	pSMB->Fid = netfid;
3635 	inc_rfc1001_len(pSMB, byte_count);
3636 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3637 
3638 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3639 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3640 	if (rc) {
3641 		cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
3642 	} else {		/* decode response */
3643 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3644 
3645 		if (rc) /* BB add auto retry on EOPNOTSUPP? */
3646 			rc = -EIO;
3647 		else if (get_bcc(&pSMBr->hdr) < 40)
3648 			rc = -EIO;	/* bad smb */
3649 		else if (pFindData) {
3650 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3651 			memcpy((char *) pFindData,
3652 			       (char *) &pSMBr->hdr.Protocol +
3653 			       data_offset, sizeof(FILE_ALL_INFO));
3654 		} else
3655 		    rc = -ENOMEM;
3656 	}
3657 	cifs_buf_release(pSMB);
3658 	if (rc == -EAGAIN)
3659 		goto QFileInfoRetry;
3660 
3661 	return rc;
3662 }
3663 
3664 int
3665 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3666 		 const char *search_name, FILE_ALL_INFO *data,
3667 		 int legacy /* old style infolevel */,
3668 		 const struct nls_table *nls_codepage, int remap)
3669 {
3670 	/* level 263 SMB_QUERY_FILE_ALL_INFO */
3671 	TRANSACTION2_QPI_REQ *pSMB = NULL;
3672 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
3673 	int rc = 0;
3674 	int bytes_returned;
3675 	int name_len;
3676 	__u16 params, byte_count;
3677 
3678 	/* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
3679 QPathInfoRetry:
3680 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3681 		      (void **) &pSMBr);
3682 	if (rc)
3683 		return rc;
3684 
3685 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3686 		name_len =
3687 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
3688 				       PATH_MAX, nls_codepage, remap);
3689 		name_len++;	/* trailing null */
3690 		name_len *= 2;
3691 	} else {
3692 		name_len = copy_path_name(pSMB->FileName, search_name);
3693 	}
3694 
3695 	params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3696 	pSMB->TotalDataCount = 0;
3697 	pSMB->MaxParameterCount = cpu_to_le16(2);
3698 	/* BB find exact max SMB PDU from sess structure BB */
3699 	pSMB->MaxDataCount = cpu_to_le16(4000);
3700 	pSMB->MaxSetupCount = 0;
3701 	pSMB->Reserved = 0;
3702 	pSMB->Flags = 0;
3703 	pSMB->Timeout = 0;
3704 	pSMB->Reserved2 = 0;
3705 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
3706 	struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3707 	pSMB->DataCount = 0;
3708 	pSMB->DataOffset = 0;
3709 	pSMB->SetupCount = 1;
3710 	pSMB->Reserved3 = 0;
3711 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3712 	byte_count = params + 1 /* pad */ ;
3713 	pSMB->TotalParameterCount = cpu_to_le16(params);
3714 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3715 	if (legacy)
3716 		pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3717 	else
3718 		pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3719 	pSMB->Reserved4 = 0;
3720 	inc_rfc1001_len(pSMB, byte_count);
3721 	pSMB->ByteCount = cpu_to_le16(byte_count);
3722 
3723 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3724 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3725 	if (rc) {
3726 		cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
3727 	} else {		/* decode response */
3728 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3729 
3730 		if (rc) /* BB add auto retry on EOPNOTSUPP? */
3731 			rc = -EIO;
3732 		else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3733 			rc = -EIO;	/* bad smb */
3734 		else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3735 			rc = -EIO;  /* 24 or 26 expected but we do not read
3736 					last field */
3737 		else if (data) {
3738 			int size;
3739 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3740 
3741 			/*
3742 			 * On legacy responses we do not read the last field,
3743 			 * EAsize, fortunately since it varies by subdialect and
3744 			 * also note it differs on Set vs Get, ie two bytes or 4
3745 			 * bytes depending but we don't care here.
3746 			 */
3747 			if (legacy)
3748 				size = sizeof(FILE_INFO_STANDARD);
3749 			else
3750 				size = sizeof(FILE_ALL_INFO);
3751 			memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
3752 			       data_offset, size);
3753 		} else
3754 		    rc = -ENOMEM;
3755 	}
3756 	cifs_buf_release(pSMB);
3757 	if (rc == -EAGAIN)
3758 		goto QPathInfoRetry;
3759 
3760 	return rc;
3761 }
3762 
3763 int
3764 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
3765 		 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3766 {
3767 	struct smb_t2_qfi_req *pSMB = NULL;
3768 	struct smb_t2_qfi_rsp *pSMBr = NULL;
3769 	int rc = 0;
3770 	int bytes_returned;
3771 	__u16 params, byte_count;
3772 
3773 UnixQFileInfoRetry:
3774 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3775 		      (void **) &pSMBr);
3776 	if (rc)
3777 		return rc;
3778 
3779 	params = 2 /* level */ + 2 /* fid */;
3780 	pSMB->t2.TotalDataCount = 0;
3781 	pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3782 	/* BB find exact max data count below from sess structure BB */
3783 	pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3784 	pSMB->t2.MaxSetupCount = 0;
3785 	pSMB->t2.Reserved = 0;
3786 	pSMB->t2.Flags = 0;
3787 	pSMB->t2.Timeout = 0;
3788 	pSMB->t2.Reserved2 = 0;
3789 	pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3790 					       Fid) - 4);
3791 	pSMB->t2.DataCount = 0;
3792 	pSMB->t2.DataOffset = 0;
3793 	pSMB->t2.SetupCount = 1;
3794 	pSMB->t2.Reserved3 = 0;
3795 	pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3796 	byte_count = params + 1 /* pad */ ;
3797 	pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3798 	pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3799 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3800 	pSMB->Pad = 0;
3801 	pSMB->Fid = netfid;
3802 	inc_rfc1001_len(pSMB, byte_count);
3803 	pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3804 
3805 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3806 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3807 	if (rc) {
3808 		cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
3809 	} else {		/* decode response */
3810 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3811 
3812 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3813 			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3814 			rc = -EIO;	/* bad smb */
3815 		} else {
3816 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3817 			memcpy((char *) pFindData,
3818 			       (char *) &pSMBr->hdr.Protocol +
3819 			       data_offset,
3820 			       sizeof(FILE_UNIX_BASIC_INFO));
3821 		}
3822 	}
3823 
3824 	cifs_buf_release(pSMB);
3825 	if (rc == -EAGAIN)
3826 		goto UnixQFileInfoRetry;
3827 
3828 	return rc;
3829 }
3830 
3831 int
3832 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
3833 		     const unsigned char *searchName,
3834 		     FILE_UNIX_BASIC_INFO *pFindData,
3835 		     const struct nls_table *nls_codepage, int remap)
3836 {
3837 /* SMB_QUERY_FILE_UNIX_BASIC */
3838 	TRANSACTION2_QPI_REQ *pSMB = NULL;
3839 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
3840 	int rc = 0;
3841 	int bytes_returned = 0;
3842 	int name_len;
3843 	__u16 params, byte_count;
3844 
3845 	cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
3846 UnixQPathInfoRetry:
3847 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3848 		      (void **) &pSMBr);
3849 	if (rc)
3850 		return rc;
3851 
3852 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3853 		name_len =
3854 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3855 				       PATH_MAX, nls_codepage, remap);
3856 		name_len++;	/* trailing null */
3857 		name_len *= 2;
3858 	} else {
3859 		name_len = copy_path_name(pSMB->FileName, searchName);
3860 	}
3861 
3862 	params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3863 	pSMB->TotalDataCount = 0;
3864 	pSMB->MaxParameterCount = cpu_to_le16(2);
3865 	/* BB find exact max SMB PDU from sess structure BB */
3866 	pSMB->MaxDataCount = cpu_to_le16(4000);
3867 	pSMB->MaxSetupCount = 0;
3868 	pSMB->Reserved = 0;
3869 	pSMB->Flags = 0;
3870 	pSMB->Timeout = 0;
3871 	pSMB->Reserved2 = 0;
3872 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
3873 	struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3874 	pSMB->DataCount = 0;
3875 	pSMB->DataOffset = 0;
3876 	pSMB->SetupCount = 1;
3877 	pSMB->Reserved3 = 0;
3878 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3879 	byte_count = params + 1 /* pad */ ;
3880 	pSMB->TotalParameterCount = cpu_to_le16(params);
3881 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3882 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3883 	pSMB->Reserved4 = 0;
3884 	inc_rfc1001_len(pSMB, byte_count);
3885 	pSMB->ByteCount = cpu_to_le16(byte_count);
3886 
3887 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3888 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3889 	if (rc) {
3890 		cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
3891 	} else {		/* decode response */
3892 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3893 
3894 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3895 			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
3896 			rc = -EIO;	/* bad smb */
3897 		} else {
3898 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3899 			memcpy((char *) pFindData,
3900 			       (char *) &pSMBr->hdr.Protocol +
3901 			       data_offset,
3902 			       sizeof(FILE_UNIX_BASIC_INFO));
3903 		}
3904 	}
3905 	cifs_buf_release(pSMB);
3906 	if (rc == -EAGAIN)
3907 		goto UnixQPathInfoRetry;
3908 
3909 	return rc;
3910 }
3911 
3912 /* xid, tcon, searchName and codepage are input parms, rest are returned */
3913 int
3914 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
3915 	      const char *searchName, struct cifs_sb_info *cifs_sb,
3916 	      __u16 *pnetfid, __u16 search_flags,
3917 	      struct cifs_search_info *psrch_inf, bool msearch)
3918 {
3919 /* level 257 SMB_ */
3920 	TRANSACTION2_FFIRST_REQ *pSMB = NULL;
3921 	TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
3922 	T2_FFIRST_RSP_PARMS *parms;
3923 	struct nls_table *nls_codepage;
3924 	unsigned int lnoff;
3925 	__u16 params, byte_count;
3926 	int bytes_returned = 0;
3927 	int name_len, remap;
3928 	int rc = 0;
3929 
3930 	cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
3931 
3932 findFirstRetry:
3933 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3934 		      (void **) &pSMBr);
3935 	if (rc)
3936 		return rc;
3937 
3938 	nls_codepage = cifs_sb->local_nls;
3939 	remap = cifs_remap(cifs_sb);
3940 
3941 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3942 		name_len =
3943 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
3944 				       PATH_MAX, nls_codepage, remap);
3945 		/* We can not add the asterik earlier in case
3946 		it got remapped to 0xF03A as if it were part of the
3947 		directory name instead of a wildcard */
3948 		name_len *= 2;
3949 		if (msearch) {
3950 			pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
3951 			pSMB->FileName[name_len+1] = 0;
3952 			pSMB->FileName[name_len+2] = '*';
3953 			pSMB->FileName[name_len+3] = 0;
3954 			name_len += 4; /* now the trailing null */
3955 			/* null terminate just in case */
3956 			pSMB->FileName[name_len] = 0;
3957 			pSMB->FileName[name_len+1] = 0;
3958 			name_len += 2;
3959 		}
3960 	} else {
3961 		name_len = copy_path_name(pSMB->FileName, searchName);
3962 		if (msearch) {
3963 			if (WARN_ON_ONCE(name_len > PATH_MAX-2))
3964 				name_len = PATH_MAX-2;
3965 			/* overwrite nul byte */
3966 			pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
3967 			pSMB->FileName[name_len] = '*';
3968 			pSMB->FileName[name_len+1] = 0;
3969 			name_len += 2;
3970 		}
3971 	}
3972 
3973 	params = 12 + name_len /* includes null */ ;
3974 	pSMB->TotalDataCount = 0;	/* no EAs */
3975 	pSMB->MaxParameterCount = cpu_to_le16(10);
3976 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
3977 	pSMB->MaxSetupCount = 0;
3978 	pSMB->Reserved = 0;
3979 	pSMB->Flags = 0;
3980 	pSMB->Timeout = 0;
3981 	pSMB->Reserved2 = 0;
3982 	byte_count = params + 1 /* pad */ ;
3983 	pSMB->TotalParameterCount = cpu_to_le16(params);
3984 	pSMB->ParameterCount = pSMB->TotalParameterCount;
3985 	pSMB->ParameterOffset = cpu_to_le16(
3986 	      offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3987 		- 4);
3988 	pSMB->DataCount = 0;
3989 	pSMB->DataOffset = 0;
3990 	pSMB->SetupCount = 1;	/* one byte, no need to make endian neutral */
3991 	pSMB->Reserved3 = 0;
3992 	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
3993 	pSMB->SearchAttributes =
3994 	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3995 			ATTR_DIRECTORY);
3996 	pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
3997 	pSMB->SearchFlags = cpu_to_le16(search_flags);
3998 	pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3999 
4000 	/* BB what should we set StorageType to? Does it matter? BB */
4001 	pSMB->SearchStorageType = 0;
4002 	inc_rfc1001_len(pSMB, byte_count);
4003 	pSMB->ByteCount = cpu_to_le16(byte_count);
4004 
4005 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4006 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4007 	cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4008 
4009 	if (rc) {
4010 		/*
4011 		 * BB: add logic to retry regular search if Unix search rejected
4012 		 * unexpectedly by server.
4013 		 */
4014 		/* BB: add code to handle unsupported level rc */
4015 		cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4016 		cifs_buf_release(pSMB);
4017 		/*
4018 		 * BB: eventually could optimize out free and realloc of buf for
4019 		 * this case.
4020 		 */
4021 		if (rc == -EAGAIN)
4022 			goto findFirstRetry;
4023 		return rc;
4024 	}
4025 	/* decode response */
4026 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4027 	if (rc) {
4028 		cifs_buf_release(pSMB);
4029 		return rc;
4030 	}
4031 
4032 	psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4033 	psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4034 	psrch_inf->smallBuf = false;
4035 	psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol +
4036 		le16_to_cpu(pSMBr->t2.DataOffset);
4037 
4038 	parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol +
4039 					le16_to_cpu(pSMBr->t2.ParameterOffset));
4040 	psrch_inf->endOfSearch = !!parms->EndofSearch;
4041 
4042 	psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4043 	psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4044 		psrch_inf->entries_in_buffer;
4045 	lnoff = le16_to_cpu(parms->LastNameOffset);
4046 	if (CIFSMaxBufSize < lnoff) {
4047 		cifs_dbg(VFS, "ignoring corrupt resume name\n");
4048 		psrch_inf->last_entry = NULL;
4049 	} else {
4050 		psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff;
4051 		if (pnetfid)
4052 			*pnetfid = parms->SearchHandle;
4053 	}
4054 	return 0;
4055 }
4056 
4057 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4058 		 __u16 searchHandle, __u16 search_flags,
4059 		 struct cifs_search_info *psrch_inf)
4060 {
4061 	TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4062 	TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4063 	T2_FNEXT_RSP_PARMS *parms;
4064 	unsigned int name_len;
4065 	unsigned int lnoff;
4066 	__u16 params, byte_count;
4067 	char *response_data;
4068 	int bytes_returned;
4069 	int rc = 0;
4070 
4071 	cifs_dbg(FYI, "In FindNext\n");
4072 
4073 	if (psrch_inf->endOfSearch)
4074 		return -ENOENT;
4075 
4076 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4077 		(void **) &pSMBr);
4078 	if (rc)
4079 		return rc;
4080 
4081 	params = 14; /* includes 2 bytes of null string, converted to LE below*/
4082 	byte_count = 0;
4083 	pSMB->TotalDataCount = 0;       /* no EAs */
4084 	pSMB->MaxParameterCount = cpu_to_le16(8);
4085 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4086 	pSMB->MaxSetupCount = 0;
4087 	pSMB->Reserved = 0;
4088 	pSMB->Flags = 0;
4089 	pSMB->Timeout = 0;
4090 	pSMB->Reserved2 = 0;
4091 	pSMB->ParameterOffset =  cpu_to_le16(
4092 	      offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4093 	pSMB->DataCount = 0;
4094 	pSMB->DataOffset = 0;
4095 	pSMB->SetupCount = 1;
4096 	pSMB->Reserved3 = 0;
4097 	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4098 	pSMB->SearchHandle = searchHandle;      /* always kept as le */
4099 	pSMB->SearchCount =
4100 		cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4101 	pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4102 	pSMB->ResumeKey = psrch_inf->resume_key;
4103 	pSMB->SearchFlags = cpu_to_le16(search_flags);
4104 
4105 	name_len = psrch_inf->resume_name_len;
4106 	params += name_len;
4107 	if (name_len < PATH_MAX) {
4108 		memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4109 		byte_count += name_len;
4110 		/* 14 byte parm len above enough for 2 byte null terminator */
4111 		pSMB->ResumeFileName[name_len] = 0;
4112 		pSMB->ResumeFileName[name_len+1] = 0;
4113 	} else {
4114 		cifs_buf_release(pSMB);
4115 		return -EINVAL;
4116 	}
4117 	byte_count = params + 1 /* pad */ ;
4118 	pSMB->TotalParameterCount = cpu_to_le16(params);
4119 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4120 	inc_rfc1001_len(pSMB, byte_count);
4121 	pSMB->ByteCount = cpu_to_le16(byte_count);
4122 
4123 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4124 			(struct smb_hdr *) pSMBr, &bytes_returned, 0);
4125 	cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4126 
4127 	if (rc) {
4128 		cifs_buf_release(pSMB);
4129 		if (rc == -EBADF) {
4130 			psrch_inf->endOfSearch = true;
4131 			rc = 0; /* search probably was closed at end of search*/
4132 		} else {
4133 			cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4134 		}
4135 		return rc;
4136 	}
4137 
4138 	/* decode response */
4139 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4140 	if (rc) {
4141 		cifs_buf_release(pSMB);
4142 		return rc;
4143 	}
4144 	/* BB fixme add lock for file (srch_info) struct here */
4145 	psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
4146 	response_data = (char *)&pSMBr->hdr.Protocol +
4147 		le16_to_cpu(pSMBr->t2.ParameterOffset);
4148 	parms = (T2_FNEXT_RSP_PARMS *)response_data;
4149 	response_data = (char *)&pSMBr->hdr.Protocol +
4150 		le16_to_cpu(pSMBr->t2.DataOffset);
4151 
4152 	if (psrch_inf->smallBuf)
4153 		cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
4154 	else
4155 		cifs_buf_release(psrch_inf->ntwrk_buf_start);
4156 
4157 	psrch_inf->srch_entries_start = response_data;
4158 	psrch_inf->ntwrk_buf_start = (char *)pSMB;
4159 	psrch_inf->smallBuf = false;
4160 	psrch_inf->endOfSearch = !!parms->EndofSearch;
4161 	psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
4162 	psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer;
4163 	lnoff = le16_to_cpu(parms->LastNameOffset);
4164 	if (CIFSMaxBufSize < lnoff) {
4165 		cifs_dbg(VFS, "ignoring corrupt resume name\n");
4166 		psrch_inf->last_entry = NULL;
4167 	} else {
4168 		psrch_inf->last_entry =
4169 			psrch_inf->srch_entries_start + lnoff;
4170 	}
4171 	/* BB fixme add unlock here */
4172 
4173 	/*
4174 	 * BB: On error, should we leave previous search buf
4175 	 * (and count and last entry fields) intact or free the previous one?
4176 	 *
4177 	 * Note: On -EAGAIN error only caller can retry on handle based calls
4178 	 * since file handle passed in no longer valid.
4179 	 */
4180 	return 0;
4181 }
4182 
4183 int
4184 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4185 	      const __u16 searchHandle)
4186 {
4187 	int rc = 0;
4188 	FINDCLOSE_REQ *pSMB = NULL;
4189 
4190 	cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4191 	rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4192 
4193 	/* no sense returning error if session restarted
4194 		as file handle has been closed */
4195 	if (rc == -EAGAIN)
4196 		return 0;
4197 	if (rc)
4198 		return rc;
4199 
4200 	pSMB->FileID = searchHandle;
4201 	pSMB->ByteCount = 0;
4202 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4203 	cifs_small_buf_release(pSMB);
4204 	if (rc)
4205 		cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4206 
4207 	cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4208 
4209 	/* Since session is dead, search handle closed on server already */
4210 	if (rc == -EAGAIN)
4211 		rc = 0;
4212 
4213 	return rc;
4214 }
4215 
4216 int
4217 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4218 		      const char *search_name, __u64 *inode_number,
4219 		      const struct nls_table *nls_codepage, int remap)
4220 {
4221 	int rc = 0;
4222 	TRANSACTION2_QPI_REQ *pSMB = NULL;
4223 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
4224 	int name_len, bytes_returned;
4225 	__u16 params, byte_count;
4226 
4227 	cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4228 	if (tcon == NULL)
4229 		return -ENODEV;
4230 
4231 GetInodeNumberRetry:
4232 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4233 		      (void **) &pSMBr);
4234 	if (rc)
4235 		return rc;
4236 
4237 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4238 		name_len =
4239 			cifsConvertToUTF16((__le16 *) pSMB->FileName,
4240 					   search_name, PATH_MAX, nls_codepage,
4241 					   remap);
4242 		name_len++;     /* trailing null */
4243 		name_len *= 2;
4244 	} else {
4245 		name_len = copy_path_name(pSMB->FileName, search_name);
4246 	}
4247 
4248 	params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4249 	pSMB->TotalDataCount = 0;
4250 	pSMB->MaxParameterCount = cpu_to_le16(2);
4251 	/* BB find exact max data count below from sess structure BB */
4252 	pSMB->MaxDataCount = cpu_to_le16(4000);
4253 	pSMB->MaxSetupCount = 0;
4254 	pSMB->Reserved = 0;
4255 	pSMB->Flags = 0;
4256 	pSMB->Timeout = 0;
4257 	pSMB->Reserved2 = 0;
4258 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4259 		struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4260 	pSMB->DataCount = 0;
4261 	pSMB->DataOffset = 0;
4262 	pSMB->SetupCount = 1;
4263 	pSMB->Reserved3 = 0;
4264 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4265 	byte_count = params + 1 /* pad */ ;
4266 	pSMB->TotalParameterCount = cpu_to_le16(params);
4267 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4268 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4269 	pSMB->Reserved4 = 0;
4270 	inc_rfc1001_len(pSMB, byte_count);
4271 	pSMB->ByteCount = cpu_to_le16(byte_count);
4272 
4273 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4274 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
4275 	if (rc) {
4276 		cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4277 	} else {
4278 		/* decode response */
4279 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4280 		/* BB also check enough total bytes returned */
4281 		if (rc || get_bcc(&pSMBr->hdr) < 2)
4282 			/* If rc should we check for EOPNOSUPP and
4283 			disable the srvino flag? or in caller? */
4284 			rc = -EIO;      /* bad smb */
4285 		else {
4286 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4287 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4288 			struct file_internal_info *pfinfo;
4289 			/* BB Do we need a cast or hash here ? */
4290 			if (count < 8) {
4291 				cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4292 				rc = -EIO;
4293 				goto GetInodeNumOut;
4294 			}
4295 			pfinfo = (struct file_internal_info *)
4296 				(data_offset + (char *) &pSMBr->hdr.Protocol);
4297 			*inode_number = le64_to_cpu(pfinfo->UniqueId);
4298 		}
4299 	}
4300 GetInodeNumOut:
4301 	cifs_buf_release(pSMB);
4302 	if (rc == -EAGAIN)
4303 		goto GetInodeNumberRetry;
4304 	return rc;
4305 }
4306 
4307 int
4308 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4309 		const char *search_name, struct dfs_info3_param **target_nodes,
4310 		unsigned int *num_of_nodes,
4311 		const struct nls_table *nls_codepage, int remap)
4312 {
4313 /* TRANS2_GET_DFS_REFERRAL */
4314 	TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4315 	TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4316 	int rc = 0;
4317 	int bytes_returned;
4318 	int name_len;
4319 	__u16 params, byte_count;
4320 	*num_of_nodes = 0;
4321 	*target_nodes = NULL;
4322 
4323 	cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4324 	if (ses == NULL || ses->tcon_ipc == NULL)
4325 		return -ENODEV;
4326 
4327 getDFSRetry:
4328 	/*
4329 	 * Use smb_init_no_reconnect() instead of smb_init() as
4330 	 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4331 	 * causing an infinite recursion.
4332 	 */
4333 	rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4334 				   (void **)&pSMB, (void **)&pSMBr);
4335 	if (rc)
4336 		return rc;
4337 
4338 	/* server pointer checked in called function,
4339 	but should never be null here anyway */
4340 	pSMB->hdr.Mid = get_next_mid(ses->server);
4341 	pSMB->hdr.Tid = ses->tcon_ipc->tid;
4342 	pSMB->hdr.Uid = ses->Suid;
4343 	if (ses->capabilities & CAP_STATUS32)
4344 		pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4345 	if (ses->capabilities & CAP_DFS)
4346 		pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4347 
4348 	if (ses->capabilities & CAP_UNICODE) {
4349 		pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4350 		name_len =
4351 		    cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4352 				       search_name, PATH_MAX, nls_codepage,
4353 				       remap);
4354 		name_len++;	/* trailing null */
4355 		name_len *= 2;
4356 	} else {	/* BB improve the check for buffer overruns BB */
4357 		name_len = copy_path_name(pSMB->RequestFileName, search_name);
4358 	}
4359 
4360 	if (ses->server->sign)
4361 		pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4362 
4363 	pSMB->hdr.Uid = ses->Suid;
4364 
4365 	params = 2 /* level */  + name_len /*includes null */ ;
4366 	pSMB->TotalDataCount = 0;
4367 	pSMB->DataCount = 0;
4368 	pSMB->DataOffset = 0;
4369 	pSMB->MaxParameterCount = 0;
4370 	/* BB find exact max SMB PDU from sess structure BB */
4371 	pSMB->MaxDataCount = cpu_to_le16(4000);
4372 	pSMB->MaxSetupCount = 0;
4373 	pSMB->Reserved = 0;
4374 	pSMB->Flags = 0;
4375 	pSMB->Timeout = 0;
4376 	pSMB->Reserved2 = 0;
4377 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4378 	  struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4379 	pSMB->SetupCount = 1;
4380 	pSMB->Reserved3 = 0;
4381 	pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4382 	byte_count = params + 3 /* pad */ ;
4383 	pSMB->ParameterCount = cpu_to_le16(params);
4384 	pSMB->TotalParameterCount = pSMB->ParameterCount;
4385 	pSMB->MaxReferralLevel = cpu_to_le16(3);
4386 	inc_rfc1001_len(pSMB, byte_count);
4387 	pSMB->ByteCount = cpu_to_le16(byte_count);
4388 
4389 	rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4390 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4391 	if (rc) {
4392 		cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4393 		goto GetDFSRefExit;
4394 	}
4395 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4396 
4397 	/* BB Also check if enough total bytes returned? */
4398 	if (rc || get_bcc(&pSMBr->hdr) < 17) {
4399 		rc = -EIO;      /* bad smb */
4400 		goto GetDFSRefExit;
4401 	}
4402 
4403 	cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4404 		 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4405 
4406 	/* parse returned result into more usable form */
4407 	rc = parse_dfs_referrals(&pSMBr->dfs_data,
4408 				 le16_to_cpu(pSMBr->t2.DataCount),
4409 				 num_of_nodes, target_nodes, nls_codepage,
4410 				 remap, search_name,
4411 				 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4412 
4413 GetDFSRefExit:
4414 	cifs_buf_release(pSMB);
4415 
4416 	if (rc == -EAGAIN)
4417 		goto getDFSRetry;
4418 
4419 	return rc;
4420 }
4421 
4422 /* Query File System Info such as free space to old servers such as Win 9x */
4423 int
4424 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4425 	      struct kstatfs *FSData)
4426 {
4427 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4428 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4429 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4430 	FILE_SYSTEM_ALLOC_INFO *response_data;
4431 	int rc = 0;
4432 	int bytes_returned = 0;
4433 	__u16 params, byte_count;
4434 
4435 	cifs_dbg(FYI, "OldQFSInfo\n");
4436 oldQFSInfoRetry:
4437 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4438 		(void **) &pSMBr);
4439 	if (rc)
4440 		return rc;
4441 
4442 	params = 2;     /* level */
4443 	pSMB->TotalDataCount = 0;
4444 	pSMB->MaxParameterCount = cpu_to_le16(2);
4445 	pSMB->MaxDataCount = cpu_to_le16(1000);
4446 	pSMB->MaxSetupCount = 0;
4447 	pSMB->Reserved = 0;
4448 	pSMB->Flags = 0;
4449 	pSMB->Timeout = 0;
4450 	pSMB->Reserved2 = 0;
4451 	byte_count = params + 1 /* pad */ ;
4452 	pSMB->TotalParameterCount = cpu_to_le16(params);
4453 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4454 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4455 	struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4456 	pSMB->DataCount = 0;
4457 	pSMB->DataOffset = 0;
4458 	pSMB->SetupCount = 1;
4459 	pSMB->Reserved3 = 0;
4460 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4461 	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4462 	inc_rfc1001_len(pSMB, byte_count);
4463 	pSMB->ByteCount = cpu_to_le16(byte_count);
4464 
4465 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4466 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
4467 	if (rc) {
4468 		cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4469 	} else {                /* decode response */
4470 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4471 
4472 		if (rc || get_bcc(&pSMBr->hdr) < 18)
4473 			rc = -EIO;      /* bad smb */
4474 		else {
4475 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4476 			cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
4477 				 get_bcc(&pSMBr->hdr), data_offset);
4478 
4479 			response_data = (FILE_SYSTEM_ALLOC_INFO *)
4480 				(((char *) &pSMBr->hdr.Protocol) + data_offset);
4481 			FSData->f_bsize =
4482 				le16_to_cpu(response_data->BytesPerSector) *
4483 				le32_to_cpu(response_data->
4484 					SectorsPerAllocationUnit);
4485 			/*
4486 			 * much prefer larger but if server doesn't report
4487 			 * a valid size than 4K is a reasonable minimum
4488 			 */
4489 			if (FSData->f_bsize < 512)
4490 				FSData->f_bsize = 4096;
4491 
4492 			FSData->f_blocks =
4493 			       le32_to_cpu(response_data->TotalAllocationUnits);
4494 			FSData->f_bfree = FSData->f_bavail =
4495 				le32_to_cpu(response_data->FreeAllocationUnits);
4496 			cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4497 				 (unsigned long long)FSData->f_blocks,
4498 				 (unsigned long long)FSData->f_bfree,
4499 				 FSData->f_bsize);
4500 		}
4501 	}
4502 	cifs_buf_release(pSMB);
4503 
4504 	if (rc == -EAGAIN)
4505 		goto oldQFSInfoRetry;
4506 
4507 	return rc;
4508 }
4509 
4510 int
4511 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4512 	       struct kstatfs *FSData)
4513 {
4514 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4515 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4516 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4517 	FILE_SYSTEM_INFO *response_data;
4518 	int rc = 0;
4519 	int bytes_returned = 0;
4520 	__u16 params, byte_count;
4521 
4522 	cifs_dbg(FYI, "In QFSInfo\n");
4523 QFSInfoRetry:
4524 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4525 		      (void **) &pSMBr);
4526 	if (rc)
4527 		return rc;
4528 
4529 	params = 2;	/* level */
4530 	pSMB->TotalDataCount = 0;
4531 	pSMB->MaxParameterCount = cpu_to_le16(2);
4532 	pSMB->MaxDataCount = cpu_to_le16(1000);
4533 	pSMB->MaxSetupCount = 0;
4534 	pSMB->Reserved = 0;
4535 	pSMB->Flags = 0;
4536 	pSMB->Timeout = 0;
4537 	pSMB->Reserved2 = 0;
4538 	byte_count = params + 1 /* pad */ ;
4539 	pSMB->TotalParameterCount = cpu_to_le16(params);
4540 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4541 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4542 		struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4543 	pSMB->DataCount = 0;
4544 	pSMB->DataOffset = 0;
4545 	pSMB->SetupCount = 1;
4546 	pSMB->Reserved3 = 0;
4547 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4548 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4549 	inc_rfc1001_len(pSMB, byte_count);
4550 	pSMB->ByteCount = cpu_to_le16(byte_count);
4551 
4552 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4553 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4554 	if (rc) {
4555 		cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4556 	} else {		/* decode response */
4557 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4558 
4559 		if (rc || get_bcc(&pSMBr->hdr) < 24)
4560 			rc = -EIO;	/* bad smb */
4561 		else {
4562 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4563 
4564 			response_data =
4565 			    (FILE_SYSTEM_INFO
4566 			     *) (((char *) &pSMBr->hdr.Protocol) +
4567 				 data_offset);
4568 			FSData->f_bsize =
4569 			    le32_to_cpu(response_data->BytesPerSector) *
4570 			    le32_to_cpu(response_data->
4571 					SectorsPerAllocationUnit);
4572 			/*
4573 			 * much prefer larger but if server doesn't report
4574 			 * a valid size than 4K is a reasonable minimum
4575 			 */
4576 			if (FSData->f_bsize < 512)
4577 				FSData->f_bsize = 4096;
4578 
4579 			FSData->f_blocks =
4580 			    le64_to_cpu(response_data->TotalAllocationUnits);
4581 			FSData->f_bfree = FSData->f_bavail =
4582 			    le64_to_cpu(response_data->FreeAllocationUnits);
4583 			cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4584 				 (unsigned long long)FSData->f_blocks,
4585 				 (unsigned long long)FSData->f_bfree,
4586 				 FSData->f_bsize);
4587 		}
4588 	}
4589 	cifs_buf_release(pSMB);
4590 
4591 	if (rc == -EAGAIN)
4592 		goto QFSInfoRetry;
4593 
4594 	return rc;
4595 }
4596 
4597 int
4598 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
4599 {
4600 /* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
4601 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4602 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4603 	FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
4604 	int rc = 0;
4605 	int bytes_returned = 0;
4606 	__u16 params, byte_count;
4607 
4608 	cifs_dbg(FYI, "In QFSAttributeInfo\n");
4609 QFSAttributeRetry:
4610 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4611 		      (void **) &pSMBr);
4612 	if (rc)
4613 		return rc;
4614 
4615 	params = 2;	/* level */
4616 	pSMB->TotalDataCount = 0;
4617 	pSMB->MaxParameterCount = cpu_to_le16(2);
4618 	/* BB find exact max SMB PDU from sess structure BB */
4619 	pSMB->MaxDataCount = cpu_to_le16(1000);
4620 	pSMB->MaxSetupCount = 0;
4621 	pSMB->Reserved = 0;
4622 	pSMB->Flags = 0;
4623 	pSMB->Timeout = 0;
4624 	pSMB->Reserved2 = 0;
4625 	byte_count = params + 1 /* pad */ ;
4626 	pSMB->TotalParameterCount = cpu_to_le16(params);
4627 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4628 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4629 		struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4630 	pSMB->DataCount = 0;
4631 	pSMB->DataOffset = 0;
4632 	pSMB->SetupCount = 1;
4633 	pSMB->Reserved3 = 0;
4634 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4635 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4636 	inc_rfc1001_len(pSMB, byte_count);
4637 	pSMB->ByteCount = cpu_to_le16(byte_count);
4638 
4639 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4640 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4641 	if (rc) {
4642 		cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
4643 	} else {		/* decode response */
4644 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4645 
4646 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
4647 			/* BB also check if enough bytes returned */
4648 			rc = -EIO;	/* bad smb */
4649 		} else {
4650 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4651 			response_data =
4652 			    (FILE_SYSTEM_ATTRIBUTE_INFO
4653 			     *) (((char *) &pSMBr->hdr.Protocol) +
4654 				 data_offset);
4655 			memcpy(&tcon->fsAttrInfo, response_data,
4656 			       sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
4657 		}
4658 	}
4659 	cifs_buf_release(pSMB);
4660 
4661 	if (rc == -EAGAIN)
4662 		goto QFSAttributeRetry;
4663 
4664 	return rc;
4665 }
4666 
4667 int
4668 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
4669 {
4670 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4671 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4672 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4673 	FILE_SYSTEM_DEVICE_INFO *response_data;
4674 	int rc = 0;
4675 	int bytes_returned = 0;
4676 	__u16 params, byte_count;
4677 
4678 	cifs_dbg(FYI, "In QFSDeviceInfo\n");
4679 QFSDeviceRetry:
4680 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4681 		      (void **) &pSMBr);
4682 	if (rc)
4683 		return rc;
4684 
4685 	params = 2;	/* level */
4686 	pSMB->TotalDataCount = 0;
4687 	pSMB->MaxParameterCount = cpu_to_le16(2);
4688 	/* BB find exact max SMB PDU from sess structure BB */
4689 	pSMB->MaxDataCount = cpu_to_le16(1000);
4690 	pSMB->MaxSetupCount = 0;
4691 	pSMB->Reserved = 0;
4692 	pSMB->Flags = 0;
4693 	pSMB->Timeout = 0;
4694 	pSMB->Reserved2 = 0;
4695 	byte_count = params + 1 /* pad */ ;
4696 	pSMB->TotalParameterCount = cpu_to_le16(params);
4697 	pSMB->ParameterCount = pSMB->TotalParameterCount;
4698 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
4699 		struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4700 
4701 	pSMB->DataCount = 0;
4702 	pSMB->DataOffset = 0;
4703 	pSMB->SetupCount = 1;
4704 	pSMB->Reserved3 = 0;
4705 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4706 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4707 	inc_rfc1001_len(pSMB, byte_count);
4708 	pSMB->ByteCount = cpu_to_le16(byte_count);
4709 
4710 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4711 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4712 	if (rc) {
4713 		cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
4714 	} else {		/* decode response */
4715 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4716 
4717 		if (rc || get_bcc(&pSMBr->hdr) <
4718 			  sizeof(FILE_SYSTEM_DEVICE_INFO))
4719 			rc = -EIO;	/* bad smb */
4720 		else {
4721 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4722 			response_data =
4723 			    (FILE_SYSTEM_DEVICE_INFO *)
4724 				(((char *) &pSMBr->hdr.Protocol) +
4725 				 data_offset);
4726 			memcpy(&tcon->fsDevInfo, response_data,
4727 			       sizeof(FILE_SYSTEM_DEVICE_INFO));
4728 		}
4729 	}
4730 	cifs_buf_release(pSMB);
4731 
4732 	if (rc == -EAGAIN)
4733 		goto QFSDeviceRetry;
4734 
4735 	return rc;
4736 }
4737 
4738 int
4739 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
4740 {
4741 /* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
4742 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4743 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4744 	FILE_SYSTEM_UNIX_INFO *response_data;
4745 	int rc = 0;
4746 	int bytes_returned = 0;
4747 	__u16 params, byte_count;
4748 
4749 	cifs_dbg(FYI, "In QFSUnixInfo\n");
4750 QFSUnixRetry:
4751 	rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4752 				   (void **) &pSMB, (void **) &pSMBr);
4753 	if (rc)
4754 		return rc;
4755 
4756 	params = 2;	/* level */
4757 	pSMB->TotalDataCount = 0;
4758 	pSMB->DataCount = 0;
4759 	pSMB->DataOffset = 0;
4760 	pSMB->MaxParameterCount = cpu_to_le16(2);
4761 	/* BB find exact max SMB PDU from sess structure BB */
4762 	pSMB->MaxDataCount = cpu_to_le16(100);
4763 	pSMB->MaxSetupCount = 0;
4764 	pSMB->Reserved = 0;
4765 	pSMB->Flags = 0;
4766 	pSMB->Timeout = 0;
4767 	pSMB->Reserved2 = 0;
4768 	byte_count = params + 1 /* pad */ ;
4769 	pSMB->ParameterCount = cpu_to_le16(params);
4770 	pSMB->TotalParameterCount = pSMB->ParameterCount;
4771 	pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4772 			smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4773 	pSMB->SetupCount = 1;
4774 	pSMB->Reserved3 = 0;
4775 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4776 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4777 	inc_rfc1001_len(pSMB, byte_count);
4778 	pSMB->ByteCount = cpu_to_le16(byte_count);
4779 
4780 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4781 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4782 	if (rc) {
4783 		cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
4784 	} else {		/* decode response */
4785 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4786 
4787 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
4788 			rc = -EIO;	/* bad smb */
4789 		} else {
4790 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4791 			response_data =
4792 			    (FILE_SYSTEM_UNIX_INFO
4793 			     *) (((char *) &pSMBr->hdr.Protocol) +
4794 				 data_offset);
4795 			memcpy(&tcon->fsUnixInfo, response_data,
4796 			       sizeof(FILE_SYSTEM_UNIX_INFO));
4797 		}
4798 	}
4799 	cifs_buf_release(pSMB);
4800 
4801 	if (rc == -EAGAIN)
4802 		goto QFSUnixRetry;
4803 
4804 
4805 	return rc;
4806 }
4807 
4808 int
4809 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
4810 {
4811 /* level 0x200  SMB_SET_CIFS_UNIX_INFO */
4812 	TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4813 	TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
4814 	int rc = 0;
4815 	int bytes_returned = 0;
4816 	__u16 params, param_offset, offset, byte_count;
4817 
4818 	cifs_dbg(FYI, "In SETFSUnixInfo\n");
4819 SETFSUnixRetry:
4820 	/* BB switch to small buf init to save memory */
4821 	rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
4822 					(void **) &pSMB, (void **) &pSMBr);
4823 	if (rc)
4824 		return rc;
4825 
4826 	params = 4;	/* 2 bytes zero followed by info level. */
4827 	pSMB->MaxSetupCount = 0;
4828 	pSMB->Reserved = 0;
4829 	pSMB->Flags = 0;
4830 	pSMB->Timeout = 0;
4831 	pSMB->Reserved2 = 0;
4832 	param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4833 				- 4;
4834 	offset = param_offset + params;
4835 
4836 	pSMB->MaxParameterCount = cpu_to_le16(4);
4837 	/* BB find exact max SMB PDU from sess structure BB */
4838 	pSMB->MaxDataCount = cpu_to_le16(100);
4839 	pSMB->SetupCount = 1;
4840 	pSMB->Reserved3 = 0;
4841 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
4842 	byte_count = 1 /* pad */ + params + 12;
4843 
4844 	pSMB->DataCount = cpu_to_le16(12);
4845 	pSMB->ParameterCount = cpu_to_le16(params);
4846 	pSMB->TotalDataCount = pSMB->DataCount;
4847 	pSMB->TotalParameterCount = pSMB->ParameterCount;
4848 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
4849 	pSMB->DataOffset = cpu_to_le16(offset);
4850 
4851 	/* Params. */
4852 	pSMB->FileNum = 0;
4853 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
4854 
4855 	/* Data. */
4856 	pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
4857 	pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4858 	pSMB->ClientUnixCap = cpu_to_le64(cap);
4859 
4860 	inc_rfc1001_len(pSMB, byte_count);
4861 	pSMB->ByteCount = cpu_to_le16(byte_count);
4862 
4863 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4864 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4865 	if (rc) {
4866 		cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
4867 	} else {		/* decode response */
4868 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4869 		if (rc)
4870 			rc = -EIO;	/* bad smb */
4871 	}
4872 	cifs_buf_release(pSMB);
4873 
4874 	if (rc == -EAGAIN)
4875 		goto SETFSUnixRetry;
4876 
4877 	return rc;
4878 }
4879 
4880 
4881 
4882 int
4883 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
4884 		   struct kstatfs *FSData)
4885 {
4886 /* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
4887 	TRANSACTION2_QFSI_REQ *pSMB = NULL;
4888 	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4889 	FILE_SYSTEM_POSIX_INFO *response_data;
4890 	int rc = 0;
4891 	int bytes_returned = 0;
4892 	__u16 params, byte_count;
4893 
4894 	cifs_dbg(FYI, "In QFSPosixInfo\n");
4895 QFSPosixRetry:
4896 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4897 		      (void **) &pSMBr);
4898 	if (rc)
4899 		return rc;
4900 
4901 	params = 2;	/* level */
4902 	pSMB->TotalDataCount = 0;
4903 	pSMB->DataCount = 0;
4904 	pSMB->DataOffset = 0;
4905 	pSMB->MaxParameterCount = cpu_to_le16(2);
4906 	/* BB find exact max SMB PDU from sess structure BB */
4907 	pSMB->MaxDataCount = cpu_to_le16(100);
4908 	pSMB->MaxSetupCount = 0;
4909 	pSMB->Reserved = 0;
4910 	pSMB->Flags = 0;
4911 	pSMB->Timeout = 0;
4912 	pSMB->Reserved2 = 0;
4913 	byte_count = params + 1 /* pad */ ;
4914 	pSMB->ParameterCount = cpu_to_le16(params);
4915 	pSMB->TotalParameterCount = pSMB->ParameterCount;
4916 	pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4917 			smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4918 	pSMB->SetupCount = 1;
4919 	pSMB->Reserved3 = 0;
4920 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4921 	pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4922 	inc_rfc1001_len(pSMB, byte_count);
4923 	pSMB->ByteCount = cpu_to_le16(byte_count);
4924 
4925 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4926 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4927 	if (rc) {
4928 		cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
4929 	} else {		/* decode response */
4930 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4931 
4932 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
4933 			rc = -EIO;	/* bad smb */
4934 		} else {
4935 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4936 			response_data =
4937 			    (FILE_SYSTEM_POSIX_INFO
4938 			     *) (((char *) &pSMBr->hdr.Protocol) +
4939 				 data_offset);
4940 			FSData->f_bsize =
4941 					le32_to_cpu(response_data->BlockSize);
4942 			/*
4943 			 * much prefer larger but if server doesn't report
4944 			 * a valid size than 4K is a reasonable minimum
4945 			 */
4946 			if (FSData->f_bsize < 512)
4947 				FSData->f_bsize = 4096;
4948 
4949 			FSData->f_blocks =
4950 					le64_to_cpu(response_data->TotalBlocks);
4951 			FSData->f_bfree =
4952 			    le64_to_cpu(response_data->BlocksAvail);
4953 			if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4954 				FSData->f_bavail = FSData->f_bfree;
4955 			} else {
4956 				FSData->f_bavail =
4957 				    le64_to_cpu(response_data->UserBlocksAvail);
4958 			}
4959 			if (response_data->TotalFileNodes != cpu_to_le64(-1))
4960 				FSData->f_files =
4961 				     le64_to_cpu(response_data->TotalFileNodes);
4962 			if (response_data->FreeFileNodes != cpu_to_le64(-1))
4963 				FSData->f_ffree =
4964 				      le64_to_cpu(response_data->FreeFileNodes);
4965 		}
4966 	}
4967 	cifs_buf_release(pSMB);
4968 
4969 	if (rc == -EAGAIN)
4970 		goto QFSPosixRetry;
4971 
4972 	return rc;
4973 }
4974 
4975 
4976 /*
4977  * We can not use write of zero bytes trick to set file size due to need for
4978  * large file support. Also note that this SetPathInfo is preferred to
4979  * SetFileInfo based method in next routine which is only needed to work around
4980  * a sharing violation bugin Samba which this routine can run into.
4981  */
4982 int
4983 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
4984 	      const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
4985 	      bool set_allocation)
4986 {
4987 	struct smb_com_transaction2_spi_req *pSMB = NULL;
4988 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
4989 	struct file_end_of_file_info *parm_data;
4990 	int name_len;
4991 	int rc = 0;
4992 	int bytes_returned = 0;
4993 	int remap = cifs_remap(cifs_sb);
4994 
4995 	__u16 params, byte_count, data_count, param_offset, offset;
4996 
4997 	cifs_dbg(FYI, "In SetEOF\n");
4998 SetEOFRetry:
4999 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5000 		      (void **) &pSMBr);
5001 	if (rc)
5002 		return rc;
5003 
5004 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5005 		name_len =
5006 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5007 				       PATH_MAX, cifs_sb->local_nls, remap);
5008 		name_len++;	/* trailing null */
5009 		name_len *= 2;
5010 	} else {
5011 		name_len = copy_path_name(pSMB->FileName, file_name);
5012 	}
5013 	params = 6 + name_len;
5014 	data_count = sizeof(struct file_end_of_file_info);
5015 	pSMB->MaxParameterCount = cpu_to_le16(2);
5016 	pSMB->MaxDataCount = cpu_to_le16(4100);
5017 	pSMB->MaxSetupCount = 0;
5018 	pSMB->Reserved = 0;
5019 	pSMB->Flags = 0;
5020 	pSMB->Timeout = 0;
5021 	pSMB->Reserved2 = 0;
5022 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
5023 				InformationLevel) - 4;
5024 	offset = param_offset + params;
5025 	if (set_allocation) {
5026 		if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5027 			pSMB->InformationLevel =
5028 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5029 		else
5030 			pSMB->InformationLevel =
5031 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5032 	} else /* Set File Size */  {
5033 	    if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5034 		    pSMB->InformationLevel =
5035 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5036 	    else
5037 		    pSMB->InformationLevel =
5038 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5039 	}
5040 
5041 	parm_data =
5042 	    (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5043 				       offset);
5044 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5045 	pSMB->DataOffset = cpu_to_le16(offset);
5046 	pSMB->SetupCount = 1;
5047 	pSMB->Reserved3 = 0;
5048 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5049 	byte_count = 3 /* pad */  + params + data_count;
5050 	pSMB->DataCount = cpu_to_le16(data_count);
5051 	pSMB->TotalDataCount = pSMB->DataCount;
5052 	pSMB->ParameterCount = cpu_to_le16(params);
5053 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5054 	pSMB->Reserved4 = 0;
5055 	inc_rfc1001_len(pSMB, byte_count);
5056 	parm_data->FileSize = cpu_to_le64(size);
5057 	pSMB->ByteCount = cpu_to_le16(byte_count);
5058 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5059 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5060 	if (rc)
5061 		cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5062 
5063 	cifs_buf_release(pSMB);
5064 
5065 	if (rc == -EAGAIN)
5066 		goto SetEOFRetry;
5067 
5068 	return rc;
5069 }
5070 
5071 int
5072 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5073 		   struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5074 {
5075 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5076 	struct file_end_of_file_info *parm_data;
5077 	int rc = 0;
5078 	__u16 params, param_offset, offset, byte_count, count;
5079 
5080 	cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5081 		 (long long)size);
5082 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5083 
5084 	if (rc)
5085 		return rc;
5086 
5087 	pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5088 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5089 
5090 	params = 6;
5091 	pSMB->MaxSetupCount = 0;
5092 	pSMB->Reserved = 0;
5093 	pSMB->Flags = 0;
5094 	pSMB->Timeout = 0;
5095 	pSMB->Reserved2 = 0;
5096 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5097 	offset = param_offset + params;
5098 
5099 	count = sizeof(struct file_end_of_file_info);
5100 	pSMB->MaxParameterCount = cpu_to_le16(2);
5101 	/* BB find exact max SMB PDU from sess structure BB */
5102 	pSMB->MaxDataCount = cpu_to_le16(1000);
5103 	pSMB->SetupCount = 1;
5104 	pSMB->Reserved3 = 0;
5105 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5106 	byte_count = 3 /* pad */  + params + count;
5107 	pSMB->DataCount = cpu_to_le16(count);
5108 	pSMB->ParameterCount = cpu_to_le16(params);
5109 	pSMB->TotalDataCount = pSMB->DataCount;
5110 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5111 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5112 	/* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5113 	parm_data =
5114 		(struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5115 	pSMB->DataOffset = cpu_to_le16(offset);
5116 	parm_data->FileSize = cpu_to_le64(size);
5117 	pSMB->Fid = cfile->fid.netfid;
5118 	if (set_allocation) {
5119 		if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5120 			pSMB->InformationLevel =
5121 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5122 		else
5123 			pSMB->InformationLevel =
5124 				cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5125 	} else /* Set File Size */  {
5126 	    if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5127 		    pSMB->InformationLevel =
5128 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5129 	    else
5130 		    pSMB->InformationLevel =
5131 				cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5132 	}
5133 	pSMB->Reserved4 = 0;
5134 	inc_rfc1001_len(pSMB, byte_count);
5135 	pSMB->ByteCount = cpu_to_le16(byte_count);
5136 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5137 	cifs_small_buf_release(pSMB);
5138 	if (rc) {
5139 		cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5140 			 rc);
5141 	}
5142 
5143 	/* Note: On -EAGAIN error only caller can retry on handle based calls
5144 		since file handle passed in no longer valid */
5145 
5146 	return rc;
5147 }
5148 
5149 /* Some legacy servers such as NT4 require that the file times be set on
5150    an open handle, rather than by pathname - this is awkward due to
5151    potential access conflicts on the open, but it is unavoidable for these
5152    old servers since the only other choice is to go from 100 nanosecond DCE
5153    time and resort to the original setpathinfo level which takes the ancient
5154    DOS time format with 2 second granularity */
5155 int
5156 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5157 		    const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5158 {
5159 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5160 	char *data_offset;
5161 	int rc = 0;
5162 	__u16 params, param_offset, offset, byte_count, count;
5163 
5164 	cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5165 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5166 
5167 	if (rc)
5168 		return rc;
5169 
5170 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5171 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5172 
5173 	params = 6;
5174 	pSMB->MaxSetupCount = 0;
5175 	pSMB->Reserved = 0;
5176 	pSMB->Flags = 0;
5177 	pSMB->Timeout = 0;
5178 	pSMB->Reserved2 = 0;
5179 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5180 	offset = param_offset + params;
5181 
5182 	data_offset = (char *)pSMB +
5183 			offsetof(struct smb_hdr, Protocol) + offset;
5184 
5185 	count = sizeof(FILE_BASIC_INFO);
5186 	pSMB->MaxParameterCount = cpu_to_le16(2);
5187 	/* BB find max SMB PDU from sess */
5188 	pSMB->MaxDataCount = cpu_to_le16(1000);
5189 	pSMB->SetupCount = 1;
5190 	pSMB->Reserved3 = 0;
5191 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5192 	byte_count = 3 /* pad */  + params + count;
5193 	pSMB->DataCount = cpu_to_le16(count);
5194 	pSMB->ParameterCount = cpu_to_le16(params);
5195 	pSMB->TotalDataCount = pSMB->DataCount;
5196 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5197 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5198 	pSMB->DataOffset = cpu_to_le16(offset);
5199 	pSMB->Fid = fid;
5200 	if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5201 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5202 	else
5203 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5204 	pSMB->Reserved4 = 0;
5205 	inc_rfc1001_len(pSMB, byte_count);
5206 	pSMB->ByteCount = cpu_to_le16(byte_count);
5207 	memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5208 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5209 	cifs_small_buf_release(pSMB);
5210 	if (rc)
5211 		cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5212 			 rc);
5213 
5214 	/* Note: On -EAGAIN error only caller can retry on handle based calls
5215 		since file handle passed in no longer valid */
5216 
5217 	return rc;
5218 }
5219 
5220 int
5221 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5222 			  bool delete_file, __u16 fid, __u32 pid_of_opener)
5223 {
5224 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5225 	char *data_offset;
5226 	int rc = 0;
5227 	__u16 params, param_offset, offset, byte_count, count;
5228 
5229 	cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5230 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5231 
5232 	if (rc)
5233 		return rc;
5234 
5235 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5236 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5237 
5238 	params = 6;
5239 	pSMB->MaxSetupCount = 0;
5240 	pSMB->Reserved = 0;
5241 	pSMB->Flags = 0;
5242 	pSMB->Timeout = 0;
5243 	pSMB->Reserved2 = 0;
5244 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5245 	offset = param_offset + params;
5246 
5247 	/* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5248 	data_offset = (char *)(pSMB) + offset + 4;
5249 
5250 	count = 1;
5251 	pSMB->MaxParameterCount = cpu_to_le16(2);
5252 	/* BB find max SMB PDU from sess */
5253 	pSMB->MaxDataCount = cpu_to_le16(1000);
5254 	pSMB->SetupCount = 1;
5255 	pSMB->Reserved3 = 0;
5256 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5257 	byte_count = 3 /* pad */  + params + count;
5258 	pSMB->DataCount = cpu_to_le16(count);
5259 	pSMB->ParameterCount = cpu_to_le16(params);
5260 	pSMB->TotalDataCount = pSMB->DataCount;
5261 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5262 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5263 	pSMB->DataOffset = cpu_to_le16(offset);
5264 	pSMB->Fid = fid;
5265 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5266 	pSMB->Reserved4 = 0;
5267 	inc_rfc1001_len(pSMB, byte_count);
5268 	pSMB->ByteCount = cpu_to_le16(byte_count);
5269 	*data_offset = delete_file ? 1 : 0;
5270 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5271 	cifs_small_buf_release(pSMB);
5272 	if (rc)
5273 		cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5274 
5275 	return rc;
5276 }
5277 
5278 static int
5279 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5280 		     const char *fileName, const FILE_BASIC_INFO *data,
5281 		     const struct nls_table *nls_codepage,
5282 		     struct cifs_sb_info *cifs_sb)
5283 {
5284 	int oplock = 0;
5285 	struct cifs_open_parms oparms;
5286 	struct cifs_fid fid;
5287 	int rc;
5288 
5289 	oparms = (struct cifs_open_parms) {
5290 		.tcon = tcon,
5291 		.cifs_sb = cifs_sb,
5292 		.desired_access = GENERIC_WRITE,
5293 		.create_options = cifs_create_options(cifs_sb, 0),
5294 		.disposition = FILE_OPEN,
5295 		.path = fileName,
5296 		.fid = &fid,
5297 	};
5298 
5299 	rc = CIFS_open(xid, &oparms, &oplock, NULL);
5300 	if (rc)
5301 		goto out;
5302 
5303 	rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5304 	CIFSSMBClose(xid, tcon, fid.netfid);
5305 out:
5306 
5307 	return rc;
5308 }
5309 
5310 int
5311 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5312 		   const char *fileName, const FILE_BASIC_INFO *data,
5313 		   const struct nls_table *nls_codepage,
5314 		     struct cifs_sb_info *cifs_sb)
5315 {
5316 	TRANSACTION2_SPI_REQ *pSMB = NULL;
5317 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
5318 	int name_len;
5319 	int rc = 0;
5320 	int bytes_returned = 0;
5321 	char *data_offset;
5322 	__u16 params, param_offset, offset, byte_count, count;
5323 	int remap = cifs_remap(cifs_sb);
5324 
5325 	cifs_dbg(FYI, "In SetTimes\n");
5326 
5327 SetTimesRetry:
5328 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5329 		      (void **) &pSMBr);
5330 	if (rc)
5331 		return rc;
5332 
5333 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5334 		name_len =
5335 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5336 				       PATH_MAX, nls_codepage, remap);
5337 		name_len++;	/* trailing null */
5338 		name_len *= 2;
5339 	} else {
5340 		name_len = copy_path_name(pSMB->FileName, fileName);
5341 	}
5342 
5343 	params = 6 + name_len;
5344 	count = sizeof(FILE_BASIC_INFO);
5345 	pSMB->MaxParameterCount = cpu_to_le16(2);
5346 	/* BB find max SMB PDU from sess structure BB */
5347 	pSMB->MaxDataCount = cpu_to_le16(1000);
5348 	pSMB->MaxSetupCount = 0;
5349 	pSMB->Reserved = 0;
5350 	pSMB->Flags = 0;
5351 	pSMB->Timeout = 0;
5352 	pSMB->Reserved2 = 0;
5353 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
5354 				InformationLevel) - 4;
5355 	offset = param_offset + params;
5356 	data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5357 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5358 	pSMB->DataOffset = cpu_to_le16(offset);
5359 	pSMB->SetupCount = 1;
5360 	pSMB->Reserved3 = 0;
5361 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5362 	byte_count = 3 /* pad */  + params + count;
5363 
5364 	pSMB->DataCount = cpu_to_le16(count);
5365 	pSMB->ParameterCount = cpu_to_le16(params);
5366 	pSMB->TotalDataCount = pSMB->DataCount;
5367 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5368 	if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5369 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5370 	else
5371 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5372 	pSMB->Reserved4 = 0;
5373 	inc_rfc1001_len(pSMB, byte_count);
5374 	memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5375 	pSMB->ByteCount = cpu_to_le16(byte_count);
5376 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5377 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5378 	if (rc)
5379 		cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5380 
5381 	cifs_buf_release(pSMB);
5382 
5383 	if (rc == -EAGAIN)
5384 		goto SetTimesRetry;
5385 
5386 	if (rc == -EOPNOTSUPP)
5387 		return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5388 					    nls_codepage, cifs_sb);
5389 
5390 	return rc;
5391 }
5392 
5393 static void
5394 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5395 			const struct cifs_unix_set_info_args *args)
5396 {
5397 	u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5398 	u64 mode = args->mode;
5399 
5400 	if (uid_valid(args->uid))
5401 		uid = from_kuid(&init_user_ns, args->uid);
5402 	if (gid_valid(args->gid))
5403 		gid = from_kgid(&init_user_ns, args->gid);
5404 
5405 	/*
5406 	 * Samba server ignores set of file size to zero due to bugs in some
5407 	 * older clients, but we should be precise - we use SetFileSize to
5408 	 * set file size and do not want to truncate file size to zero
5409 	 * accidentally as happened on one Samba server beta by putting
5410 	 * zero instead of -1 here
5411 	 */
5412 	data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5413 	data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5414 	data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5415 	data_offset->LastAccessTime = cpu_to_le64(args->atime);
5416 	data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5417 	data_offset->Uid = cpu_to_le64(uid);
5418 	data_offset->Gid = cpu_to_le64(gid);
5419 	/* better to leave device as zero when it is  */
5420 	data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5421 	data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5422 	data_offset->Permissions = cpu_to_le64(mode);
5423 
5424 	if (S_ISREG(mode))
5425 		data_offset->Type = cpu_to_le32(UNIX_FILE);
5426 	else if (S_ISDIR(mode))
5427 		data_offset->Type = cpu_to_le32(UNIX_DIR);
5428 	else if (S_ISLNK(mode))
5429 		data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5430 	else if (S_ISCHR(mode))
5431 		data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5432 	else if (S_ISBLK(mode))
5433 		data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5434 	else if (S_ISFIFO(mode))
5435 		data_offset->Type = cpu_to_le32(UNIX_FIFO);
5436 	else if (S_ISSOCK(mode))
5437 		data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5438 }
5439 
5440 int
5441 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5442 		       const struct cifs_unix_set_info_args *args,
5443 		       u16 fid, u32 pid_of_opener)
5444 {
5445 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5446 	char *data_offset;
5447 	int rc = 0;
5448 	u16 params, param_offset, offset, byte_count, count;
5449 
5450 	cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5451 	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5452 
5453 	if (rc)
5454 		return rc;
5455 
5456 	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5457 	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5458 
5459 	params = 6;
5460 	pSMB->MaxSetupCount = 0;
5461 	pSMB->Reserved = 0;
5462 	pSMB->Flags = 0;
5463 	pSMB->Timeout = 0;
5464 	pSMB->Reserved2 = 0;
5465 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5466 	offset = param_offset + params;
5467 
5468 	data_offset = (char *)pSMB +
5469 			offsetof(struct smb_hdr, Protocol) + offset;
5470 
5471 	count = sizeof(FILE_UNIX_BASIC_INFO);
5472 
5473 	pSMB->MaxParameterCount = cpu_to_le16(2);
5474 	/* BB find max SMB PDU from sess */
5475 	pSMB->MaxDataCount = cpu_to_le16(1000);
5476 	pSMB->SetupCount = 1;
5477 	pSMB->Reserved3 = 0;
5478 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5479 	byte_count = 3 /* pad */  + params + count;
5480 	pSMB->DataCount = cpu_to_le16(count);
5481 	pSMB->ParameterCount = cpu_to_le16(params);
5482 	pSMB->TotalDataCount = pSMB->DataCount;
5483 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5484 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5485 	pSMB->DataOffset = cpu_to_le16(offset);
5486 	pSMB->Fid = fid;
5487 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5488 	pSMB->Reserved4 = 0;
5489 	inc_rfc1001_len(pSMB, byte_count);
5490 	pSMB->ByteCount = cpu_to_le16(byte_count);
5491 
5492 	cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5493 
5494 	rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5495 	cifs_small_buf_release(pSMB);
5496 	if (rc)
5497 		cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5498 			 rc);
5499 
5500 	/* Note: On -EAGAIN error only caller can retry on handle based calls
5501 		since file handle passed in no longer valid */
5502 
5503 	return rc;
5504 }
5505 
5506 int
5507 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5508 		       const char *file_name,
5509 		       const struct cifs_unix_set_info_args *args,
5510 		       const struct nls_table *nls_codepage, int remap)
5511 {
5512 	TRANSACTION2_SPI_REQ *pSMB = NULL;
5513 	TRANSACTION2_SPI_RSP *pSMBr = NULL;
5514 	int name_len;
5515 	int rc = 0;
5516 	int bytes_returned = 0;
5517 	FILE_UNIX_BASIC_INFO *data_offset;
5518 	__u16 params, param_offset, offset, count, byte_count;
5519 
5520 	cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5521 setPermsRetry:
5522 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5523 		      (void **) &pSMBr);
5524 	if (rc)
5525 		return rc;
5526 
5527 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5528 		name_len =
5529 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5530 				       PATH_MAX, nls_codepage, remap);
5531 		name_len++;	/* trailing null */
5532 		name_len *= 2;
5533 	} else {
5534 		name_len = copy_path_name(pSMB->FileName, file_name);
5535 	}
5536 
5537 	params = 6 + name_len;
5538 	count = sizeof(FILE_UNIX_BASIC_INFO);
5539 	pSMB->MaxParameterCount = cpu_to_le16(2);
5540 	/* BB find max SMB PDU from sess structure BB */
5541 	pSMB->MaxDataCount = cpu_to_le16(1000);
5542 	pSMB->MaxSetupCount = 0;
5543 	pSMB->Reserved = 0;
5544 	pSMB->Flags = 0;
5545 	pSMB->Timeout = 0;
5546 	pSMB->Reserved2 = 0;
5547 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
5548 				InformationLevel) - 4;
5549 	offset = param_offset + params;
5550 	/* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5551 	data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
5552 	memset(data_offset, 0, count);
5553 	pSMB->DataOffset = cpu_to_le16(offset);
5554 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5555 	pSMB->SetupCount = 1;
5556 	pSMB->Reserved3 = 0;
5557 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5558 	byte_count = 3 /* pad */  + params + count;
5559 	pSMB->ParameterCount = cpu_to_le16(params);
5560 	pSMB->DataCount = cpu_to_le16(count);
5561 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5562 	pSMB->TotalDataCount = pSMB->DataCount;
5563 	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5564 	pSMB->Reserved4 = 0;
5565 	inc_rfc1001_len(pSMB, byte_count);
5566 
5567 	cifs_fill_unix_set_info(data_offset, args);
5568 
5569 	pSMB->ByteCount = cpu_to_le16(byte_count);
5570 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5571 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5572 	if (rc)
5573 		cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
5574 
5575 	cifs_buf_release(pSMB);
5576 	if (rc == -EAGAIN)
5577 		goto setPermsRetry;
5578 	return rc;
5579 }
5580 
5581 #ifdef CONFIG_CIFS_XATTR
5582 /*
5583  * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5584  * function used by listxattr and getxattr type calls. When ea_name is set,
5585  * it looks for that attribute name and stuffs that value into the EAData
5586  * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
5587  * buffer. In both cases, the return value is either the length of the
5588  * resulting data or a negative error code. If EAData is a NULL pointer then
5589  * the data isn't copied to it, but the length is returned.
5590  */
5591 ssize_t
5592 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
5593 		const unsigned char *searchName, const unsigned char *ea_name,
5594 		char *EAData, size_t buf_size,
5595 		struct cifs_sb_info *cifs_sb)
5596 {
5597 		/* BB assumes one setup word */
5598 	TRANSACTION2_QPI_REQ *pSMB = NULL;
5599 	TRANSACTION2_QPI_RSP *pSMBr = NULL;
5600 	int remap = cifs_remap(cifs_sb);
5601 	struct nls_table *nls_codepage = cifs_sb->local_nls;
5602 	int rc = 0;
5603 	int bytes_returned;
5604 	int list_len;
5605 	struct fealist *ea_response_data;
5606 	struct fea *temp_fea;
5607 	char *temp_ptr;
5608 	char *end_of_smb;
5609 	__u16 params, byte_count, data_offset;
5610 	unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
5611 
5612 	cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
5613 QAllEAsRetry:
5614 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5615 		      (void **) &pSMBr);
5616 	if (rc)
5617 		return rc;
5618 
5619 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5620 		list_len =
5621 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
5622 				       PATH_MAX, nls_codepage, remap);
5623 		list_len++;	/* trailing null */
5624 		list_len *= 2;
5625 	} else {
5626 		list_len = copy_path_name(pSMB->FileName, searchName);
5627 	}
5628 
5629 	params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
5630 	pSMB->TotalDataCount = 0;
5631 	pSMB->MaxParameterCount = cpu_to_le16(2);
5632 	/* BB find exact max SMB PDU from sess structure BB */
5633 	pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
5634 	pSMB->MaxSetupCount = 0;
5635 	pSMB->Reserved = 0;
5636 	pSMB->Flags = 0;
5637 	pSMB->Timeout = 0;
5638 	pSMB->Reserved2 = 0;
5639 	pSMB->ParameterOffset = cpu_to_le16(offsetof(
5640 	struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5641 	pSMB->DataCount = 0;
5642 	pSMB->DataOffset = 0;
5643 	pSMB->SetupCount = 1;
5644 	pSMB->Reserved3 = 0;
5645 	pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
5646 	byte_count = params + 1 /* pad */ ;
5647 	pSMB->TotalParameterCount = cpu_to_le16(params);
5648 	pSMB->ParameterCount = pSMB->TotalParameterCount;
5649 	pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5650 	pSMB->Reserved4 = 0;
5651 	inc_rfc1001_len(pSMB, byte_count);
5652 	pSMB->ByteCount = cpu_to_le16(byte_count);
5653 
5654 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5655 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5656 	if (rc) {
5657 		cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
5658 		goto QAllEAsOut;
5659 	}
5660 
5661 
5662 	/* BB also check enough total bytes returned */
5663 	/* BB we need to improve the validity checking
5664 	of these trans2 responses */
5665 
5666 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5667 	if (rc || get_bcc(&pSMBr->hdr) < 4) {
5668 		rc = -EIO;	/* bad smb */
5669 		goto QAllEAsOut;
5670 	}
5671 
5672 	/* check that length of list is not more than bcc */
5673 	/* check that each entry does not go beyond length
5674 	   of list */
5675 	/* check that each element of each entry does not
5676 	   go beyond end of list */
5677 	/* validate_trans2_offsets() */
5678 	/* BB check if start of smb + data_offset > &bcc+ bcc */
5679 
5680 	data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5681 	ea_response_data = (struct fealist *)
5682 				(((char *) &pSMBr->hdr.Protocol) + data_offset);
5683 
5684 	list_len = le32_to_cpu(ea_response_data->list_len);
5685 	cifs_dbg(FYI, "ea length %d\n", list_len);
5686 	if (list_len <= 8) {
5687 		cifs_dbg(FYI, "empty EA list returned from server\n");
5688 		/* didn't find the named attribute */
5689 		if (ea_name)
5690 			rc = -ENODATA;
5691 		goto QAllEAsOut;
5692 	}
5693 
5694 	/* make sure list_len doesn't go past end of SMB */
5695 	end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5696 	if ((char *)ea_response_data + list_len > end_of_smb) {
5697 		cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
5698 		rc = -EIO;
5699 		goto QAllEAsOut;
5700 	}
5701 
5702 	/* account for ea list len */
5703 	list_len -= 4;
5704 	temp_fea = &ea_response_data->list;
5705 	temp_ptr = (char *)temp_fea;
5706 	while (list_len > 0) {
5707 		unsigned int name_len;
5708 		__u16 value_len;
5709 
5710 		list_len -= 4;
5711 		temp_ptr += 4;
5712 		/* make sure we can read name_len and value_len */
5713 		if (list_len < 0) {
5714 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5715 			rc = -EIO;
5716 			goto QAllEAsOut;
5717 		}
5718 
5719 		name_len = temp_fea->name_len;
5720 		value_len = le16_to_cpu(temp_fea->value_len);
5721 		list_len -= name_len + 1 + value_len;
5722 		if (list_len < 0) {
5723 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
5724 			rc = -EIO;
5725 			goto QAllEAsOut;
5726 		}
5727 
5728 		if (ea_name) {
5729 			if (ea_name_len == name_len &&
5730 			    memcmp(ea_name, temp_ptr, name_len) == 0) {
5731 				temp_ptr += name_len + 1;
5732 				rc = value_len;
5733 				if (buf_size == 0)
5734 					goto QAllEAsOut;
5735 				if ((size_t)value_len > buf_size) {
5736 					rc = -ERANGE;
5737 					goto QAllEAsOut;
5738 				}
5739 				memcpy(EAData, temp_ptr, value_len);
5740 				goto QAllEAsOut;
5741 			}
5742 		} else {
5743 			/* account for prefix user. and trailing null */
5744 			rc += (5 + 1 + name_len);
5745 			if (rc < (int) buf_size) {
5746 				memcpy(EAData, "user.", 5);
5747 				EAData += 5;
5748 				memcpy(EAData, temp_ptr, name_len);
5749 				EAData += name_len;
5750 				/* null terminate name */
5751 				*EAData = 0;
5752 				++EAData;
5753 			} else if (buf_size == 0) {
5754 				/* skip copy - calc size only */
5755 			} else {
5756 				/* stop before overrun buffer */
5757 				rc = -ERANGE;
5758 				break;
5759 			}
5760 		}
5761 		temp_ptr += name_len + 1 + value_len;
5762 		temp_fea = (struct fea *)temp_ptr;
5763 	}
5764 
5765 	/* didn't find the named attribute */
5766 	if (ea_name)
5767 		rc = -ENODATA;
5768 
5769 QAllEAsOut:
5770 	cifs_buf_release(pSMB);
5771 	if (rc == -EAGAIN)
5772 		goto QAllEAsRetry;
5773 
5774 	return (ssize_t)rc;
5775 }
5776 
5777 int
5778 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
5779 	     const char *fileName, const char *ea_name, const void *ea_value,
5780 	     const __u16 ea_value_len, const struct nls_table *nls_codepage,
5781 	     struct cifs_sb_info *cifs_sb)
5782 {
5783 	struct smb_com_transaction2_spi_req *pSMB = NULL;
5784 	struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5785 	struct fealist *parm_data;
5786 	int name_len;
5787 	int rc = 0;
5788 	int bytes_returned = 0;
5789 	__u16 params, param_offset, byte_count, offset, count;
5790 	int remap = cifs_remap(cifs_sb);
5791 
5792 	cifs_dbg(FYI, "In SetEA\n");
5793 SetEARetry:
5794 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5795 		      (void **) &pSMBr);
5796 	if (rc)
5797 		return rc;
5798 
5799 	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5800 		name_len =
5801 		    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5802 				       PATH_MAX, nls_codepage, remap);
5803 		name_len++;	/* trailing null */
5804 		name_len *= 2;
5805 	} else {
5806 		name_len = copy_path_name(pSMB->FileName, fileName);
5807 	}
5808 
5809 	params = 6 + name_len;
5810 
5811 	/* done calculating parms using name_len of file name,
5812 	now use name_len to calculate length of ea name
5813 	we are going to create in the inode xattrs */
5814 	if (ea_name == NULL)
5815 		name_len = 0;
5816 	else
5817 		name_len = strnlen(ea_name, 255);
5818 
5819 	count = sizeof(*parm_data) + 1 + ea_value_len + name_len;
5820 	pSMB->MaxParameterCount = cpu_to_le16(2);
5821 	/* BB find max SMB PDU from sess */
5822 	pSMB->MaxDataCount = cpu_to_le16(1000);
5823 	pSMB->MaxSetupCount = 0;
5824 	pSMB->Reserved = 0;
5825 	pSMB->Flags = 0;
5826 	pSMB->Timeout = 0;
5827 	pSMB->Reserved2 = 0;
5828 	param_offset = offsetof(struct smb_com_transaction2_spi_req,
5829 				InformationLevel) - 4;
5830 	offset = param_offset + params;
5831 	pSMB->InformationLevel =
5832 		cpu_to_le16(SMB_SET_FILE_EA);
5833 
5834 	parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
5835 	pSMB->ParameterOffset = cpu_to_le16(param_offset);
5836 	pSMB->DataOffset = cpu_to_le16(offset);
5837 	pSMB->SetupCount = 1;
5838 	pSMB->Reserved3 = 0;
5839 	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5840 	byte_count = 3 /* pad */  + params + count;
5841 	pSMB->DataCount = cpu_to_le16(count);
5842 	parm_data->list_len = cpu_to_le32(count);
5843 	parm_data->list.EA_flags = 0;
5844 	/* we checked above that name len is less than 255 */
5845 	parm_data->list.name_len = (__u8)name_len;
5846 	/* EA names are always ASCII */
5847 	if (ea_name)
5848 		strncpy(parm_data->list.name, ea_name, name_len);
5849 	parm_data->list.name[name_len] = '\0';
5850 	parm_data->list.value_len = cpu_to_le16(ea_value_len);
5851 	/* caller ensures that ea_value_len is less than 64K but
5852 	we need to ensure that it fits within the smb */
5853 
5854 	/*BB add length check to see if it would fit in
5855 	     negotiated SMB buffer size BB */
5856 	/* if (ea_value_len > buffer_size - 512 (enough for header)) */
5857 	if (ea_value_len)
5858 		memcpy(parm_data->list.name + name_len + 1,
5859 		       ea_value, ea_value_len);
5860 
5861 	pSMB->TotalDataCount = pSMB->DataCount;
5862 	pSMB->ParameterCount = cpu_to_le16(params);
5863 	pSMB->TotalParameterCount = pSMB->ParameterCount;
5864 	pSMB->Reserved4 = 0;
5865 	inc_rfc1001_len(pSMB, byte_count);
5866 	pSMB->ByteCount = cpu_to_le16(byte_count);
5867 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5868 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5869 	if (rc)
5870 		cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
5871 
5872 	cifs_buf_release(pSMB);
5873 
5874 	if (rc == -EAGAIN)
5875 		goto SetEARetry;
5876 
5877 	return rc;
5878 }
5879 #endif
5880