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