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