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