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