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