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