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