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