xref: /openbmc/linux/fs/smb/client/cifsglob.h (revision 07e76ea1)
138c8a9a5SSteve French /* SPDX-License-Identifier: LGPL-2.1 */
238c8a9a5SSteve French /*
338c8a9a5SSteve French  *
438c8a9a5SSteve French  *   Copyright (C) International Business Machines  Corp., 2002,2008
538c8a9a5SSteve French  *   Author(s): Steve French (sfrench@us.ibm.com)
638c8a9a5SSteve French  *              Jeremy Allison (jra@samba.org)
738c8a9a5SSteve French  *
838c8a9a5SSteve French  */
938c8a9a5SSteve French #ifndef _CIFS_GLOB_H
1038c8a9a5SSteve French #define _CIFS_GLOB_H
1138c8a9a5SSteve French 
1238c8a9a5SSteve French #include <linux/in.h>
1338c8a9a5SSteve French #include <linux/in6.h>
1438c8a9a5SSteve French #include <linux/inet.h>
1538c8a9a5SSteve French #include <linux/slab.h>
1638c8a9a5SSteve French #include <linux/scatterlist.h>
1738c8a9a5SSteve French #include <linux/mm.h>
1838c8a9a5SSteve French #include <linux/mempool.h>
1938c8a9a5SSteve French #include <linux/workqueue.h>
2038c8a9a5SSteve French #include <linux/utsname.h>
2138c8a9a5SSteve French #include <linux/sched/mm.h>
2238c8a9a5SSteve French #include <linux/netfs.h>
2338c8a9a5SSteve French #include "cifs_fs_sb.h"
2438c8a9a5SSteve French #include "cifsacl.h"
2538c8a9a5SSteve French #include <crypto/internal/hash.h>
2638c8a9a5SSteve French #include <uapi/linux/cifs/cifs_mount.h>
2738c8a9a5SSteve French #include "../common/smb2pdu.h"
2838c8a9a5SSteve French #include "smb2pdu.h"
2938c8a9a5SSteve French #include <linux/filelock.h>
3038c8a9a5SSteve French 
3138c8a9a5SSteve French #define SMB_PATH_MAX 260
3238c8a9a5SSteve French #define CIFS_PORT 445
3338c8a9a5SSteve French #define RFC1001_PORT 139
3438c8a9a5SSteve French 
3538c8a9a5SSteve French /*
3638c8a9a5SSteve French  * The sizes of various internal tables and strings
3738c8a9a5SSteve French  */
3838c8a9a5SSteve French #define MAX_UID_INFO 16
3938c8a9a5SSteve French #define MAX_SES_INFO 2
4038c8a9a5SSteve French #define MAX_TCON_INFO 4
4138c8a9a5SSteve French 
4238c8a9a5SSteve French #define MAX_TREE_SIZE (2 + CIFS_NI_MAXHOST + 1 + CIFS_MAX_SHARE_LEN + 1)
4338c8a9a5SSteve French 
4438c8a9a5SSteve French #define CIFS_MIN_RCV_POOL 4
4538c8a9a5SSteve French 
4638c8a9a5SSteve French #define MAX_REOPEN_ATT	5 /* these many maximum attempts to reopen a file */
4738c8a9a5SSteve French /*
4838c8a9a5SSteve French  * default attribute cache timeout (jiffies)
4938c8a9a5SSteve French  */
5038c8a9a5SSteve French #define CIFS_DEF_ACTIMEO (1 * HZ)
5138c8a9a5SSteve French 
5238c8a9a5SSteve French /*
53433042a9SShyam Prasad N  * max sleep time before retry to server
54433042a9SShyam Prasad N  */
55433042a9SShyam Prasad N #define CIFS_MAX_SLEEP 2000
56433042a9SShyam Prasad N 
57433042a9SShyam Prasad N /*
5838c8a9a5SSteve French  * max attribute cache timeout (jiffies) - 2^30
5938c8a9a5SSteve French  */
6038c8a9a5SSteve French #define CIFS_MAX_ACTIMEO (1 << 30)
6138c8a9a5SSteve French 
6238c8a9a5SSteve French /*
6338c8a9a5SSteve French  * Max persistent and resilient handle timeout (milliseconds).
6438c8a9a5SSteve French  * Windows durable max was 960000 (16 minutes)
6538c8a9a5SSteve French  */
6638c8a9a5SSteve French #define SMB3_MAX_HANDLE_TIMEOUT 960000
6738c8a9a5SSteve French 
6838c8a9a5SSteve French /*
6938c8a9a5SSteve French  * MAX_REQ is the maximum number of requests that WE will send
7038c8a9a5SSteve French  * on one socket concurrently.
7138c8a9a5SSteve French  */
7238c8a9a5SSteve French #define CIFS_MAX_REQ 32767
7338c8a9a5SSteve French 
7438c8a9a5SSteve French #define RFC1001_NAME_LEN 15
7538c8a9a5SSteve French #define RFC1001_NAME_LEN_WITH_NULL (RFC1001_NAME_LEN + 1)
7638c8a9a5SSteve French 
7738c8a9a5SSteve French /* maximum length of ip addr as a string (including ipv6 and sctp) */
7838c8a9a5SSteve French #define SERVER_NAME_LENGTH 80
7938c8a9a5SSteve French #define SERVER_NAME_LEN_WITH_NULL     (SERVER_NAME_LENGTH + 1)
8038c8a9a5SSteve French 
8138c8a9a5SSteve French /* echo interval in seconds */
8238c8a9a5SSteve French #define SMB_ECHO_INTERVAL_MIN 1
8338c8a9a5SSteve French #define SMB_ECHO_INTERVAL_MAX 600
8438c8a9a5SSteve French #define SMB_ECHO_INTERVAL_DEFAULT 60
8538c8a9a5SSteve French 
8638c8a9a5SSteve French /* smb multichannel query server interfaces interval in seconds */
8738c8a9a5SSteve French #define SMB_INTERFACE_POLL_INTERVAL	600
8838c8a9a5SSteve French 
8938c8a9a5SSteve French /* maximum number of PDUs in one compound */
902fdb5551SPaulo Alcantara #define MAX_COMPOUND 7
9138c8a9a5SSteve French 
9238c8a9a5SSteve French /*
9338c8a9a5SSteve French  * Default number of credits to keep available for SMB3.
9438c8a9a5SSteve French  * This value is chosen somewhat arbitrarily. The Windows client
9538c8a9a5SSteve French  * defaults to 128 credits, the Windows server allows clients up to
9638c8a9a5SSteve French  * 512 credits (or 8K for later versions), and the NetApp server
9738c8a9a5SSteve French  * does not limit clients at all.  Choose a high enough default value
9838c8a9a5SSteve French  * such that the client shouldn't limit performance, but allow mount
9938c8a9a5SSteve French  * to override (until you approach 64K, where we limit credits to 65000
10038c8a9a5SSteve French  * to reduce possibility of seeing more server credit overflow bugs.
10138c8a9a5SSteve French  */
10238c8a9a5SSteve French #define SMB2_MAX_CREDITS_AVAILABLE 32000
10338c8a9a5SSteve French 
10438c8a9a5SSteve French #include "cifspdu.h"
10538c8a9a5SSteve French 
10638c8a9a5SSteve French #ifndef XATTR_DOS_ATTRIB
10738c8a9a5SSteve French #define XATTR_DOS_ATTRIB "user.DOSATTRIB"
10838c8a9a5SSteve French #endif
10938c8a9a5SSteve French 
11038c8a9a5SSteve French #define CIFS_MAX_WORKSTATION_LEN  (__NEW_UTS_LEN + 1)  /* reasonable max for client */
11138c8a9a5SSteve French 
11238c8a9a5SSteve French #define CIFS_DFS_ROOT_SES(ses) ((ses)->dfs_root_ses ?: (ses))
11338c8a9a5SSteve French 
11438c8a9a5SSteve French /*
11538c8a9a5SSteve French  * CIFS vfs client Status information (based on what we know.)
11638c8a9a5SSteve French  */
11738c8a9a5SSteve French 
11838c8a9a5SSteve French /* associated with each connection */
11938c8a9a5SSteve French enum statusEnum {
12038c8a9a5SSteve French 	CifsNew = 0,
12138c8a9a5SSteve French 	CifsGood,
12238c8a9a5SSteve French 	CifsExiting,
12338c8a9a5SSteve French 	CifsNeedReconnect,
12438c8a9a5SSteve French 	CifsNeedNegotiate,
12538c8a9a5SSteve French 	CifsInNegotiate,
12638c8a9a5SSteve French };
12738c8a9a5SSteve French 
12838c8a9a5SSteve French /* associated with each smb session */
12938c8a9a5SSteve French enum ses_status_enum {
13038c8a9a5SSteve French 	SES_NEW = 0,
13138c8a9a5SSteve French 	SES_GOOD,
13238c8a9a5SSteve French 	SES_EXITING,
13338c8a9a5SSteve French 	SES_NEED_RECON,
13438c8a9a5SSteve French 	SES_IN_SETUP
13538c8a9a5SSteve French };
13638c8a9a5SSteve French 
13738c8a9a5SSteve French /* associated with each tree connection to the server */
13838c8a9a5SSteve French enum tid_status_enum {
13938c8a9a5SSteve French 	TID_NEW = 0,
14038c8a9a5SSteve French 	TID_GOOD,
14138c8a9a5SSteve French 	TID_EXITING,
14238c8a9a5SSteve French 	TID_NEED_RECON,
14338c8a9a5SSteve French 	TID_NEED_TCON,
14438c8a9a5SSteve French 	TID_IN_TCON,
14538c8a9a5SSteve French 	TID_NEED_FILES_INVALIDATE, /* currently unused */
14638c8a9a5SSteve French 	TID_IN_FILES_INVALIDATE
14738c8a9a5SSteve French };
14838c8a9a5SSteve French 
14938c8a9a5SSteve French enum securityEnum {
15038c8a9a5SSteve French 	Unspecified = 0,	/* not specified */
15138c8a9a5SSteve French 	NTLMv2,			/* Legacy NTLM auth with NTLMv2 hash */
15238c8a9a5SSteve French 	RawNTLMSSP,		/* NTLMSSP without SPNEGO, NTLMv2 hash */
15338c8a9a5SSteve French 	Kerberos,		/* Kerberos via SPNEGO */
15438c8a9a5SSteve French };
15538c8a9a5SSteve French 
156c1468c7eSPaulo Alcantara enum cifs_reparse_type {
157c1468c7eSPaulo Alcantara 	CIFS_REPARSE_TYPE_NFS,
158c1468c7eSPaulo Alcantara 	CIFS_REPARSE_TYPE_WSL,
159c1468c7eSPaulo Alcantara 	CIFS_REPARSE_TYPE_DEFAULT = CIFS_REPARSE_TYPE_NFS,
160c1468c7eSPaulo Alcantara };
161c1468c7eSPaulo Alcantara 
cifs_reparse_type_str(enum cifs_reparse_type type)162c057a809SPaulo Alcantara static inline const char *cifs_reparse_type_str(enum cifs_reparse_type type)
163c057a809SPaulo Alcantara {
164c057a809SPaulo Alcantara 	switch (type) {
165c057a809SPaulo Alcantara 	case CIFS_REPARSE_TYPE_NFS:
166c057a809SPaulo Alcantara 		return "nfs";
167c057a809SPaulo Alcantara 	case CIFS_REPARSE_TYPE_WSL:
168c057a809SPaulo Alcantara 		return "wsl";
169c057a809SPaulo Alcantara 	default:
170c057a809SPaulo Alcantara 		return "unknown";
171c057a809SPaulo Alcantara 	}
172c057a809SPaulo Alcantara }
173c057a809SPaulo Alcantara 
17438c8a9a5SSteve French struct session_key {
17538c8a9a5SSteve French 	unsigned int len;
17638c8a9a5SSteve French 	char *response;
17738c8a9a5SSteve French };
17838c8a9a5SSteve French 
17938c8a9a5SSteve French /* crypto hashing related structure/fields, not specific to a sec mech */
18038c8a9a5SSteve French struct cifs_secmech {
18138c8a9a5SSteve French 	struct shash_desc *hmacmd5; /* hmacmd5 hash function, for NTLMv2/CR1 hashes */
18238c8a9a5SSteve French 	struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */
18338c8a9a5SSteve French 	struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */
18438c8a9a5SSteve French 	struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */
18538c8a9a5SSteve French 	struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */
18638c8a9a5SSteve French 
18738c8a9a5SSteve French 	struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
18838c8a9a5SSteve French 	struct crypto_aead *dec; /* smb3 decryption AEAD TFM (AES-CCM and AES-GCM) */
18938c8a9a5SSteve French };
19038c8a9a5SSteve French 
19138c8a9a5SSteve French /* per smb session structure/fields */
19238c8a9a5SSteve French struct ntlmssp_auth {
19338c8a9a5SSteve French 	bool sesskey_per_smbsess; /* whether session key is per smb session */
19438c8a9a5SSteve French 	__u32 client_flags; /* sent by client in type 1 ntlmsssp exchange */
19538c8a9a5SSteve French 	__u32 server_flags; /* sent by server in type 2 ntlmssp exchange */
19638c8a9a5SSteve French 	unsigned char ciphertext[CIFS_CPHTXT_SIZE]; /* sent to server */
19738c8a9a5SSteve French 	char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlmssp */
19838c8a9a5SSteve French };
19938c8a9a5SSteve French 
20038c8a9a5SSteve French struct cifs_cred {
20138c8a9a5SSteve French 	int uid;
20238c8a9a5SSteve French 	int gid;
20338c8a9a5SSteve French 	int mode;
20438c8a9a5SSteve French 	int cecount;
20538c8a9a5SSteve French 	struct cifs_sid osid;
20638c8a9a5SSteve French 	struct cifs_sid gsid;
20738c8a9a5SSteve French 	struct cifs_ntace *ntaces;
20838c8a9a5SSteve French 	struct cifs_ace *aces;
20938c8a9a5SSteve French };
21038c8a9a5SSteve French 
21138c8a9a5SSteve French struct cifs_open_info_data {
2128b4e285dSPaulo Alcantara 	bool adjust_tz;
2138b4e285dSPaulo Alcantara 	union {
2148b4e285dSPaulo Alcantara 		bool reparse_point;
2158b4e285dSPaulo Alcantara 		bool symlink;
2168b4e285dSPaulo Alcantara 	};
217df32e887SPaulo Alcantara 	struct {
218a158bb66SSteve French 		/* ioctl response buffer */
219a158bb66SSteve French 		struct {
220a158bb66SSteve French 			int buftype;
221a158bb66SSteve French 			struct kvec iov;
222a158bb66SSteve French 		} io;
223df32e887SPaulo Alcantara 		__u32 tag;
224df32e887SPaulo Alcantara 		union {
225df32e887SPaulo Alcantara 			struct reparse_data_buffer *buf;
226df32e887SPaulo Alcantara 			struct reparse_posix_data *posix;
227df32e887SPaulo Alcantara 		};
228df32e887SPaulo Alcantara 	} reparse;
2297449d736SSteve French 	struct {
2307449d736SSteve French 		__u8		eas[SMB2_WSL_MAX_QUERY_EA_RESP_SIZE];
2317449d736SSteve French 		unsigned int	eas_len;
2327449d736SSteve French 	} wsl;
23338c8a9a5SSteve French 	char *symlink_target;
234a90f37e3SSteve French 	struct cifs_sid posix_owner;
235a90f37e3SSteve French 	struct cifs_sid posix_group;
23638c8a9a5SSteve French 	union {
23738c8a9a5SSteve French 		struct smb2_file_all_info fi;
23838c8a9a5SSteve French 		struct smb311_posix_qinfo posix_fi;
23938c8a9a5SSteve French 	};
24038c8a9a5SSteve French };
24138c8a9a5SSteve French 
24238c8a9a5SSteve French /*
24338c8a9a5SSteve French  *****************************************************************
24438c8a9a5SSteve French  * Except the CIFS PDUs themselves all the
24538c8a9a5SSteve French  * globally interesting structs should go here
24638c8a9a5SSteve French  *****************************************************************
24738c8a9a5SSteve French  */
24838c8a9a5SSteve French 
24938c8a9a5SSteve French /*
25038c8a9a5SSteve French  * A smb_rqst represents a complete request to be issued to a server. It's
25138c8a9a5SSteve French  * formed by a kvec array, followed by an array of pages. Page data is assumed
25238c8a9a5SSteve French  * to start at the beginning of the first page.
25338c8a9a5SSteve French  */
25438c8a9a5SSteve French struct smb_rqst {
25538c8a9a5SSteve French 	struct kvec	*rq_iov;	/* array of kvecs */
25638c8a9a5SSteve French 	unsigned int	rq_nvec;	/* number of kvecs in array */
25738c8a9a5SSteve French 	size_t		rq_iter_size;	/* Amount of data in ->rq_iter */
25838c8a9a5SSteve French 	struct iov_iter	rq_iter;	/* Data iterator */
25938c8a9a5SSteve French 	struct xarray	rq_buffer;	/* Page buffer for encryption */
26038c8a9a5SSteve French };
26138c8a9a5SSteve French 
26238c8a9a5SSteve French struct mid_q_entry;
26338c8a9a5SSteve French struct TCP_Server_Info;
26438c8a9a5SSteve French struct cifsFileInfo;
26538c8a9a5SSteve French struct cifs_ses;
26638c8a9a5SSteve French struct cifs_tcon;
26738c8a9a5SSteve French struct dfs_info3_param;
26838c8a9a5SSteve French struct cifs_fattr;
26938c8a9a5SSteve French struct smb3_fs_context;
27038c8a9a5SSteve French struct cifs_fid;
27138c8a9a5SSteve French struct cifs_readdata;
27238c8a9a5SSteve French struct cifs_writedata;
27338c8a9a5SSteve French struct cifs_io_parms;
27438c8a9a5SSteve French struct cifs_search_info;
27538c8a9a5SSteve French struct cifsInodeInfo;
27638c8a9a5SSteve French struct cifs_open_parms;
27738c8a9a5SSteve French struct cifs_credits;
27838c8a9a5SSteve French 
27938c8a9a5SSteve French struct smb_version_operations {
28038c8a9a5SSteve French 	int (*send_cancel)(struct TCP_Server_Info *, struct smb_rqst *,
28138c8a9a5SSteve French 			   struct mid_q_entry *);
28238c8a9a5SSteve French 	bool (*compare_fids)(struct cifsFileInfo *, struct cifsFileInfo *);
28338c8a9a5SSteve French 	/* setup request: allocate mid, sign message */
28438c8a9a5SSteve French 	struct mid_q_entry *(*setup_request)(struct cifs_ses *,
28538c8a9a5SSteve French 					     struct TCP_Server_Info *,
28638c8a9a5SSteve French 					     struct smb_rqst *);
28738c8a9a5SSteve French 	/* setup async request: allocate mid, sign message */
28838c8a9a5SSteve French 	struct mid_q_entry *(*setup_async_request)(struct TCP_Server_Info *,
28938c8a9a5SSteve French 						struct smb_rqst *);
29038c8a9a5SSteve French 	/* check response: verify signature, map error */
29138c8a9a5SSteve French 	int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
29238c8a9a5SSteve French 			     bool);
29338c8a9a5SSteve French 	void (*add_credits)(struct TCP_Server_Info *server,
29438c8a9a5SSteve French 			    const struct cifs_credits *credits,
29538c8a9a5SSteve French 			    const int optype);
29638c8a9a5SSteve French 	void (*set_credits)(struct TCP_Server_Info *, const int);
29738c8a9a5SSteve French 	int * (*get_credits_field)(struct TCP_Server_Info *, const int);
29838c8a9a5SSteve French 	unsigned int (*get_credits)(struct mid_q_entry *);
29938c8a9a5SSteve French 	__u64 (*get_next_mid)(struct TCP_Server_Info *);
30038c8a9a5SSteve French 	void (*revert_current_mid)(struct TCP_Server_Info *server,
30138c8a9a5SSteve French 				   const unsigned int val);
30238c8a9a5SSteve French 	/* data offset from read response message */
30338c8a9a5SSteve French 	unsigned int (*read_data_offset)(char *);
30438c8a9a5SSteve French 	/*
30538c8a9a5SSteve French 	 * Data length from read response message
30638c8a9a5SSteve French 	 * When in_remaining is true, the returned data length is in
30738c8a9a5SSteve French 	 * message field DataRemaining for out-of-band data read (e.g through
30838c8a9a5SSteve French 	 * Memory Registration RDMA write in SMBD).
30938c8a9a5SSteve French 	 * Otherwise, the returned data length is in message field DataLength.
31038c8a9a5SSteve French 	 */
31138c8a9a5SSteve French 	unsigned int (*read_data_length)(char *, bool in_remaining);
31238c8a9a5SSteve French 	/* map smb to linux error */
31338c8a9a5SSteve French 	int (*map_error)(char *, bool);
31438c8a9a5SSteve French 	/* find mid corresponding to the response message */
31538c8a9a5SSteve French 	struct mid_q_entry * (*find_mid)(struct TCP_Server_Info *, char *);
31638c8a9a5SSteve French 	void (*dump_detail)(void *buf, struct TCP_Server_Info *ptcp_info);
31738c8a9a5SSteve French 	void (*clear_stats)(struct cifs_tcon *);
31838c8a9a5SSteve French 	void (*print_stats)(struct seq_file *m, struct cifs_tcon *);
31938c8a9a5SSteve French 	void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *);
32038c8a9a5SSteve French 	/* verify the message */
32138c8a9a5SSteve French 	int (*check_message)(char *, unsigned int, struct TCP_Server_Info *);
32238c8a9a5SSteve French 	bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
32338c8a9a5SSteve French 	int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *);
32438c8a9a5SSteve French 	void (*downgrade_oplock)(struct TCP_Server_Info *server,
32538c8a9a5SSteve French 				 struct cifsInodeInfo *cinode, __u32 oplock,
32638c8a9a5SSteve French 				 unsigned int epoch, bool *purge_cache);
32738c8a9a5SSteve French 	/* process transaction2 response */
32838c8a9a5SSteve French 	bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
32938c8a9a5SSteve French 			     char *, int);
33038c8a9a5SSteve French 	/* check if we need to negotiate */
33138c8a9a5SSteve French 	bool (*need_neg)(struct TCP_Server_Info *);
33238c8a9a5SSteve French 	/* negotiate to the server */
33338c8a9a5SSteve French 	int (*negotiate)(const unsigned int xid,
33438c8a9a5SSteve French 			 struct cifs_ses *ses,
33538c8a9a5SSteve French 			 struct TCP_Server_Info *server);
33638c8a9a5SSteve French 	/* set negotiated write size */
33738c8a9a5SSteve French 	unsigned int (*negotiate_wsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx);
33838c8a9a5SSteve French 	/* set negotiated read size */
33938c8a9a5SSteve French 	unsigned int (*negotiate_rsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx);
34038c8a9a5SSteve French 	/* setup smb sessionn */
34138c8a9a5SSteve French 	int (*sess_setup)(const unsigned int, struct cifs_ses *,
34238c8a9a5SSteve French 			  struct TCP_Server_Info *server,
34338c8a9a5SSteve French 			  const struct nls_table *);
34438c8a9a5SSteve French 	/* close smb session */
34538c8a9a5SSteve French 	int (*logoff)(const unsigned int, struct cifs_ses *);
34638c8a9a5SSteve French 	/* connect to a server share */
34738c8a9a5SSteve French 	int (*tree_connect)(const unsigned int, struct cifs_ses *, const char *,
34838c8a9a5SSteve French 			    struct cifs_tcon *, const struct nls_table *);
34938c8a9a5SSteve French 	/* close tree connecion */
35038c8a9a5SSteve French 	int (*tree_disconnect)(const unsigned int, struct cifs_tcon *);
35138c8a9a5SSteve French 	/* get DFS referrals */
35238c8a9a5SSteve French 	int (*get_dfs_refer)(const unsigned int, struct cifs_ses *,
35338c8a9a5SSteve French 			     const char *, struct dfs_info3_param **,
35438c8a9a5SSteve French 			     unsigned int *, const struct nls_table *, int);
35538c8a9a5SSteve French 	/* informational QFS call */
35638c8a9a5SSteve French 	void (*qfs_tcon)(const unsigned int, struct cifs_tcon *,
35738c8a9a5SSteve French 			 struct cifs_sb_info *);
35866c2940cSShyam Prasad N 	/* query for server interfaces */
35966c2940cSShyam Prasad N 	int (*query_server_interfaces)(const unsigned int, struct cifs_tcon *,
36066c2940cSShyam Prasad N 				       bool);
36138c8a9a5SSteve French 	/* check if a path is accessible or not */
36238c8a9a5SSteve French 	int (*is_path_accessible)(const unsigned int, struct cifs_tcon *,
36338c8a9a5SSteve French 				  struct cifs_sb_info *, const char *);
36438c8a9a5SSteve French 	/* query path data from the server */
3658b4e285dSPaulo Alcantara 	int (*query_path_info)(const unsigned int xid,
3668b4e285dSPaulo Alcantara 			       struct cifs_tcon *tcon,
3678b4e285dSPaulo Alcantara 			       struct cifs_sb_info *cifs_sb,
3688b4e285dSPaulo Alcantara 			       const char *full_path,
3698b4e285dSPaulo Alcantara 			       struct cifs_open_info_data *data);
37038c8a9a5SSteve French 	/* query file data from the server */
37138c8a9a5SSteve French 	int (*query_file_info)(const unsigned int xid, struct cifs_tcon *tcon,
37238c8a9a5SSteve French 			       struct cifsFileInfo *cfile, struct cifs_open_info_data *data);
3739a49e221SPaulo Alcantara 	/* query reparse point to determine which type of special file */
3749a49e221SPaulo Alcantara 	int (*query_reparse_point)(const unsigned int xid,
3759a49e221SPaulo Alcantara 				   struct cifs_tcon *tcon,
3769a49e221SPaulo Alcantara 				   struct cifs_sb_info *cifs_sb,
3779a49e221SPaulo Alcantara 				   const char *full_path,
3789a49e221SPaulo Alcantara 				   u32 *tag, struct kvec *rsp,
3799a49e221SPaulo Alcantara 				   int *rsp_buftype);
38038c8a9a5SSteve French 	/* get server index number */
38138c8a9a5SSteve French 	int (*get_srv_inum)(const unsigned int xid, struct cifs_tcon *tcon,
38238c8a9a5SSteve French 			    struct cifs_sb_info *cifs_sb, const char *full_path, u64 *uniqueid,
38338c8a9a5SSteve French 			    struct cifs_open_info_data *data);
38438c8a9a5SSteve French 	/* set size by path */
38538c8a9a5SSteve French 	int (*set_path_size)(const unsigned int, struct cifs_tcon *,
386f93d145fSMeetakshi Setiya 			     const char *, __u64, struct cifs_sb_info *, bool,
387f93d145fSMeetakshi Setiya 				 struct dentry *);
38838c8a9a5SSteve French 	/* set size by file handle */
38938c8a9a5SSteve French 	int (*set_file_size)(const unsigned int, struct cifs_tcon *,
39038c8a9a5SSteve French 			     struct cifsFileInfo *, __u64, bool);
39138c8a9a5SSteve French 	/* set attributes */
39238c8a9a5SSteve French 	int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *,
39338c8a9a5SSteve French 			     const unsigned int);
39438c8a9a5SSteve French 	int (*set_compression)(const unsigned int, struct cifs_tcon *,
39538c8a9a5SSteve French 			       struct cifsFileInfo *);
39638c8a9a5SSteve French 	/* check if we can send an echo or nor */
39738c8a9a5SSteve French 	bool (*can_echo)(struct TCP_Server_Info *);
39838c8a9a5SSteve French 	/* send echo request */
39938c8a9a5SSteve French 	int (*echo)(struct TCP_Server_Info *);
40038c8a9a5SSteve French 	/* create directory */
40138c8a9a5SSteve French 	int (*posix_mkdir)(const unsigned int xid, struct inode *inode,
40238c8a9a5SSteve French 			umode_t mode, struct cifs_tcon *tcon,
40338c8a9a5SSteve French 			const char *full_path,
40438c8a9a5SSteve French 			struct cifs_sb_info *cifs_sb);
40538c8a9a5SSteve French 	int (*mkdir)(const unsigned int xid, struct inode *inode, umode_t mode,
40638c8a9a5SSteve French 		     struct cifs_tcon *tcon, const char *name,
40738c8a9a5SSteve French 		     struct cifs_sb_info *sb);
40838c8a9a5SSteve French 	/* set info on created directory */
40938c8a9a5SSteve French 	void (*mkdir_setinfo)(struct inode *, const char *,
41038c8a9a5SSteve French 			      struct cifs_sb_info *, struct cifs_tcon *,
41138c8a9a5SSteve French 			      const unsigned int);
41238c8a9a5SSteve French 	/* remove directory */
41338c8a9a5SSteve French 	int (*rmdir)(const unsigned int, struct cifs_tcon *, const char *,
41438c8a9a5SSteve French 		     struct cifs_sb_info *);
41538c8a9a5SSteve French 	/* unlink file */
41638c8a9a5SSteve French 	int (*unlink)(const unsigned int, struct cifs_tcon *, const char *,
417f93d145fSMeetakshi Setiya 		      struct cifs_sb_info *, struct dentry *);
41838c8a9a5SSteve French 	/* open, rename and delete file */
41938c8a9a5SSteve French 	int (*rename_pending_delete)(const char *, struct dentry *,
42038c8a9a5SSteve French 				     const unsigned int);
42138c8a9a5SSteve French 	/* send rename request */
422c586b0c7SPaulo Alcantara 	int (*rename)(const unsigned int xid,
423c586b0c7SPaulo Alcantara 		      struct cifs_tcon *tcon,
424c586b0c7SPaulo Alcantara 		      struct dentry *source_dentry,
425c586b0c7SPaulo Alcantara 		      const char *from_name, const char *to_name,
426c586b0c7SPaulo Alcantara 		      struct cifs_sb_info *cifs_sb);
42738c8a9a5SSteve French 	/* send create hardlink request */
4288c944f8aSPaulo Alcantara 	int (*create_hardlink)(const unsigned int xid,
4298c944f8aSPaulo Alcantara 			       struct cifs_tcon *tcon,
4308c944f8aSPaulo Alcantara 			       struct dentry *source_dentry,
4318c944f8aSPaulo Alcantara 			       const char *from_name, const char *to_name,
4328c944f8aSPaulo Alcantara 			       struct cifs_sb_info *cifs_sb);
43338c8a9a5SSteve French 	/* query symlink target */
4349a49e221SPaulo Alcantara 	int (*query_symlink)(const unsigned int xid,
4359a49e221SPaulo Alcantara 			     struct cifs_tcon *tcon,
4369a49e221SPaulo Alcantara 			     struct cifs_sb_info *cifs_sb,
4379a49e221SPaulo Alcantara 			     const char *full_path,
4384d07e5dfSPaulo Alcantara 			     char **target_path);
43938c8a9a5SSteve French 	/* open a file for non-posix mounts */
44038c8a9a5SSteve French 	int (*open)(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
44138c8a9a5SSteve French 		    void *buf);
44238c8a9a5SSteve French 	/* set fid protocol-specific info */
44338c8a9a5SSteve French 	void (*set_fid)(struct cifsFileInfo *, struct cifs_fid *, __u32);
44438c8a9a5SSteve French 	/* close a file */
4456f17163bSRitvik Budhiraja 	int (*close)(const unsigned int, struct cifs_tcon *,
44638c8a9a5SSteve French 		      struct cifs_fid *);
44738c8a9a5SSteve French 	/* close a file, returning file attributes and timestamps */
4486f17163bSRitvik Budhiraja 	int (*close_getattr)(const unsigned int xid, struct cifs_tcon *tcon,
44938c8a9a5SSteve French 		      struct cifsFileInfo *pfile_info);
45038c8a9a5SSteve French 	/* send a flush request to the server */
45138c8a9a5SSteve French 	int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *);
45238c8a9a5SSteve French 	/* async read from the server */
45338c8a9a5SSteve French 	int (*async_readv)(struct cifs_readdata *);
45438c8a9a5SSteve French 	/* async write to the server */
45538c8a9a5SSteve French 	int (*async_writev)(struct cifs_writedata *,
45638c8a9a5SSteve French 			    void (*release)(struct kref *));
45738c8a9a5SSteve French 	/* sync read from the server */
45838c8a9a5SSteve French 	int (*sync_read)(const unsigned int, struct cifs_fid *,
45938c8a9a5SSteve French 			 struct cifs_io_parms *, unsigned int *, char **,
46038c8a9a5SSteve French 			 int *);
46138c8a9a5SSteve French 	/* sync write to the server */
46238c8a9a5SSteve French 	int (*sync_write)(const unsigned int, struct cifs_fid *,
46338c8a9a5SSteve French 			  struct cifs_io_parms *, unsigned int *, struct kvec *,
46438c8a9a5SSteve French 			  unsigned long);
46538c8a9a5SSteve French 	/* open dir, start readdir */
46638c8a9a5SSteve French 	int (*query_dir_first)(const unsigned int, struct cifs_tcon *,
46738c8a9a5SSteve French 			       const char *, struct cifs_sb_info *,
46838c8a9a5SSteve French 			       struct cifs_fid *, __u16,
46938c8a9a5SSteve French 			       struct cifs_search_info *);
47038c8a9a5SSteve French 	/* continue readdir */
47138c8a9a5SSteve French 	int (*query_dir_next)(const unsigned int, struct cifs_tcon *,
47238c8a9a5SSteve French 			      struct cifs_fid *,
47338c8a9a5SSteve French 			      __u16, struct cifs_search_info *srch_inf);
47438c8a9a5SSteve French 	/* close dir */
47538c8a9a5SSteve French 	int (*close_dir)(const unsigned int, struct cifs_tcon *,
47638c8a9a5SSteve French 			 struct cifs_fid *);
47738c8a9a5SSteve French 	/* calculate a size of SMB message */
47838c8a9a5SSteve French 	unsigned int (*calc_smb_size)(void *buf);
47938c8a9a5SSteve French 	/* check for STATUS_PENDING and process the response if yes */
48038c8a9a5SSteve French 	bool (*is_status_pending)(char *buf, struct TCP_Server_Info *server);
48138c8a9a5SSteve French 	/* check for STATUS_NETWORK_SESSION_EXPIRED */
48238c8a9a5SSteve French 	bool (*is_session_expired)(char *);
48338c8a9a5SSteve French 	/* send oplock break response */
48438c8a9a5SSteve French 	int (*oplock_response)(struct cifs_tcon *tcon, __u64 persistent_fid, __u64 volatile_fid,
48538c8a9a5SSteve French 			__u16 net_fid, struct cifsInodeInfo *cifs_inode);
48638c8a9a5SSteve French 	/* query remote filesystem */
48738c8a9a5SSteve French 	int (*queryfs)(const unsigned int, struct cifs_tcon *,
48838c8a9a5SSteve French 		       struct cifs_sb_info *, struct kstatfs *);
48938c8a9a5SSteve French 	/* send mandatory brlock to the server */
49038c8a9a5SSteve French 	int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64,
49138c8a9a5SSteve French 			 __u64, __u32, int, int, bool);
49238c8a9a5SSteve French 	/* unlock range of mandatory locks */
49338c8a9a5SSteve French 	int (*mand_unlock_range)(struct cifsFileInfo *, struct file_lock *,
49438c8a9a5SSteve French 				 const unsigned int);
49538c8a9a5SSteve French 	/* push brlocks from the cache to the server */
49638c8a9a5SSteve French 	int (*push_mand_locks)(struct cifsFileInfo *);
49738c8a9a5SSteve French 	/* get lease key of the inode */
49838c8a9a5SSteve French 	void (*get_lease_key)(struct inode *, struct cifs_fid *);
49938c8a9a5SSteve French 	/* set lease key of the inode */
50038c8a9a5SSteve French 	void (*set_lease_key)(struct inode *, struct cifs_fid *);
50138c8a9a5SSteve French 	/* generate new lease key */
50238c8a9a5SSteve French 	void (*new_lease_key)(struct cifs_fid *);
50338c8a9a5SSteve French 	int (*generate_signingkey)(struct cifs_ses *ses,
50438c8a9a5SSteve French 				   struct TCP_Server_Info *server);
50538c8a9a5SSteve French 	int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *,
50638c8a9a5SSteve French 				bool allocate_crypto);
50738c8a9a5SSteve French 	int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon,
50838c8a9a5SSteve French 			     struct cifsFileInfo *src_file);
50938c8a9a5SSteve French 	int (*enum_snapshots)(const unsigned int xid, struct cifs_tcon *tcon,
51038c8a9a5SSteve French 			     struct cifsFileInfo *src_file, void __user *);
51138c8a9a5SSteve French 	int (*notify)(const unsigned int xid, struct file *pfile,
51238c8a9a5SSteve French 			     void __user *pbuf, bool return_changes);
51338c8a9a5SSteve French 	int (*query_mf_symlink)(unsigned int, struct cifs_tcon *,
51438c8a9a5SSteve French 				struct cifs_sb_info *, const unsigned char *,
51538c8a9a5SSteve French 				char *, unsigned int *);
51638c8a9a5SSteve French 	int (*create_mf_symlink)(unsigned int, struct cifs_tcon *,
51738c8a9a5SSteve French 				 struct cifs_sb_info *, const unsigned char *,
51838c8a9a5SSteve French 				 char *, unsigned int *);
51938c8a9a5SSteve French 	/* if we can do cache read operations */
52038c8a9a5SSteve French 	bool (*is_read_op)(__u32);
52138c8a9a5SSteve French 	/* set oplock level for the inode */
52238c8a9a5SSteve French 	void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int,
52338c8a9a5SSteve French 				 bool *);
52438c8a9a5SSteve French 	/* create lease context buffer for CREATE request */
52538c8a9a5SSteve French 	char * (*create_lease_buf)(u8 *lease_key, u8 oplock);
52638c8a9a5SSteve French 	/* parse lease context buffer and return oplock/epoch info */
52738c8a9a5SSteve French 	__u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey);
52838c8a9a5SSteve French 	ssize_t (*copychunk_range)(const unsigned int,
52938c8a9a5SSteve French 			struct cifsFileInfo *src_file,
53038c8a9a5SSteve French 			struct cifsFileInfo *target_file,
53138c8a9a5SSteve French 			u64 src_off, u64 len, u64 dest_off);
53238c8a9a5SSteve French 	int (*duplicate_extents)(const unsigned int, struct cifsFileInfo *src,
53338c8a9a5SSteve French 			struct cifsFileInfo *target_file, u64 src_off, u64 len,
53438c8a9a5SSteve French 			u64 dest_off);
53538c8a9a5SSteve French 	int (*validate_negotiate)(const unsigned int, struct cifs_tcon *);
53638c8a9a5SSteve French 	ssize_t (*query_all_EAs)(const unsigned int, struct cifs_tcon *,
53738c8a9a5SSteve French 			const unsigned char *, const unsigned char *, char *,
53838c8a9a5SSteve French 			size_t, struct cifs_sb_info *);
53938c8a9a5SSteve French 	int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *,
54038c8a9a5SSteve French 			const char *, const void *, const __u16,
54138c8a9a5SSteve French 			const struct nls_table *, struct cifs_sb_info *);
54238c8a9a5SSteve French 	struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *,
54338c8a9a5SSteve French 			const char *, u32 *, u32);
54438c8a9a5SSteve French 	struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *,
54538c8a9a5SSteve French 			const struct cifs_fid *, u32 *, u32);
54638c8a9a5SSteve French 	int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *,
54738c8a9a5SSteve French 			int);
54838c8a9a5SSteve French 	/* writepages retry size */
54938c8a9a5SSteve French 	unsigned int (*wp_retry_size)(struct inode *);
55038c8a9a5SSteve French 	/* get mtu credits */
55138c8a9a5SSteve French 	int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int,
55238c8a9a5SSteve French 				unsigned int *, struct cifs_credits *);
55338c8a9a5SSteve French 	/* adjust previously taken mtu credits to request size */
55438c8a9a5SSteve French 	int (*adjust_credits)(struct TCP_Server_Info *server,
55538c8a9a5SSteve French 			      struct cifs_credits *credits,
55638c8a9a5SSteve French 			      const unsigned int payload_size);
55738c8a9a5SSteve French 	/* check if we need to issue closedir */
55838c8a9a5SSteve French 	bool (*dir_needs_close)(struct cifsFileInfo *);
55938c8a9a5SSteve French 	long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t,
56038c8a9a5SSteve French 			  loff_t);
56138c8a9a5SSteve French 	/* init transform request - used for encryption for now */
56238c8a9a5SSteve French 	int (*init_transform_rq)(struct TCP_Server_Info *, int num_rqst,
56338c8a9a5SSteve French 				 struct smb_rqst *, struct smb_rqst *);
56438c8a9a5SSteve French 	int (*is_transform_hdr)(void *buf);
56538c8a9a5SSteve French 	int (*receive_transform)(struct TCP_Server_Info *,
56638c8a9a5SSteve French 				 struct mid_q_entry **, char **, int *);
56738c8a9a5SSteve French 	enum securityEnum (*select_sectype)(struct TCP_Server_Info *,
56838c8a9a5SSteve French 			    enum securityEnum);
569c0e98de9SPaulo Alcantara 	int (*next_header)(struct TCP_Server_Info *server, char *buf,
570c0e98de9SPaulo Alcantara 			   unsigned int *noff);
57138c8a9a5SSteve French 	/* ioctl passthrough for query_info */
57238c8a9a5SSteve French 	int (*ioctl_query_info)(const unsigned int xid,
57338c8a9a5SSteve French 				struct cifs_tcon *tcon,
57438c8a9a5SSteve French 				struct cifs_sb_info *cifs_sb,
57538c8a9a5SSteve French 				__le16 *path, int is_dir,
57638c8a9a5SSteve French 				unsigned long p);
57738c8a9a5SSteve French 	/* make unix special files (block, char, fifo, socket) */
57838c8a9a5SSteve French 	int (*make_node)(unsigned int xid,
57938c8a9a5SSteve French 			 struct inode *inode,
58038c8a9a5SSteve French 			 struct dentry *dentry,
58138c8a9a5SSteve French 			 struct cifs_tcon *tcon,
58238c8a9a5SSteve French 			 const char *full_path,
58338c8a9a5SSteve French 			 umode_t mode,
58438c8a9a5SSteve French 			 dev_t device_number);
58538c8a9a5SSteve French 	/* version specific fiemap implementation */
58638c8a9a5SSteve French 	int (*fiemap)(struct cifs_tcon *tcon, struct cifsFileInfo *,
58738c8a9a5SSteve French 		      struct fiemap_extent_info *, u64, u64);
58838c8a9a5SSteve French 	/* version specific llseek implementation */
58938c8a9a5SSteve French 	loff_t (*llseek)(struct file *, struct cifs_tcon *, loff_t, int);
59038c8a9a5SSteve French 	/* Check for STATUS_IO_TIMEOUT */
59138c8a9a5SSteve French 	bool (*is_status_io_timeout)(char *buf);
59238c8a9a5SSteve French 	/* Check for STATUS_NETWORK_NAME_DELETED */
593c071b34fSShyam Prasad N 	bool (*is_network_name_deleted)(char *buf, struct TCP_Server_Info *srv);
5944d07e5dfSPaulo Alcantara 	int (*parse_reparse_point)(struct cifs_sb_info *cifs_sb,
5954d07e5dfSPaulo Alcantara 				   struct kvec *rsp_iov,
5964d07e5dfSPaulo Alcantara 				   struct cifs_open_info_data *data);
59700ecebcbSPaulo Alcantara 	int (*create_reparse_symlink)(const unsigned int xid,
59800ecebcbSPaulo Alcantara 				      struct inode *inode,
59900ecebcbSPaulo Alcantara 				      struct dentry *dentry,
60000ecebcbSPaulo Alcantara 				      struct cifs_tcon *tcon,
60100ecebcbSPaulo Alcantara 				      const char *full_path,
60200ecebcbSPaulo Alcantara 				      const char *symname);
60338c8a9a5SSteve French };
60438c8a9a5SSteve French 
60538c8a9a5SSteve French struct smb_version_values {
60638c8a9a5SSteve French 	char		*version_string;
60738c8a9a5SSteve French 	__u16		protocol_id;
60838c8a9a5SSteve French 	__u32		req_capabilities;
60938c8a9a5SSteve French 	__u32		large_lock_type;
61038c8a9a5SSteve French 	__u32		exclusive_lock_type;
61138c8a9a5SSteve French 	__u32		shared_lock_type;
61238c8a9a5SSteve French 	__u32		unlock_lock_type;
61338c8a9a5SSteve French 	size_t		header_preamble_size;
61438c8a9a5SSteve French 	size_t		header_size;
61538c8a9a5SSteve French 	size_t		max_header_size;
61638c8a9a5SSteve French 	size_t		read_rsp_size;
61738c8a9a5SSteve French 	__le16		lock_cmd;
61838c8a9a5SSteve French 	unsigned int	cap_unix;
61938c8a9a5SSteve French 	unsigned int	cap_nt_find;
62038c8a9a5SSteve French 	unsigned int	cap_large_files;
62138c8a9a5SSteve French 	__u16		signing_enabled;
62238c8a9a5SSteve French 	__u16		signing_required;
62338c8a9a5SSteve French 	size_t		create_lease_size;
62438c8a9a5SSteve French };
62538c8a9a5SSteve French 
62638c8a9a5SSteve French #define HEADER_SIZE(server) (server->vals->header_size)
62738c8a9a5SSteve French #define MAX_HEADER_SIZE(server) (server->vals->max_header_size)
62838c8a9a5SSteve French #define HEADER_PREAMBLE_SIZE(server) (server->vals->header_preamble_size)
62938c8a9a5SSteve French #define MID_HEADER_SIZE(server) (HEADER_SIZE(server) - 1 - HEADER_PREAMBLE_SIZE(server))
63038c8a9a5SSteve French 
63138c8a9a5SSteve French /**
63238c8a9a5SSteve French  * CIFS superblock mount flags (mnt_cifs_flags) to consider when
63338c8a9a5SSteve French  * trying to reuse existing superblock for a new mount
63438c8a9a5SSteve French  */
63538c8a9a5SSteve French #define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
63638c8a9a5SSteve French 			 CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
63738c8a9a5SSteve French 			 CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
63838c8a9a5SSteve French 			 CIFS_MOUNT_MAP_SFM_CHR | \
63938c8a9a5SSteve French 			 CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
64038c8a9a5SSteve French 			 CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
64138c8a9a5SSteve French 			 CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
64238c8a9a5SSteve French 			 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
64338c8a9a5SSteve French 			 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
64438c8a9a5SSteve French 			 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
64538c8a9a5SSteve French 			 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \
64638c8a9a5SSteve French 			 CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \
64738c8a9a5SSteve French 			 CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID | \
64838c8a9a5SSteve French 			 CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE)
64938c8a9a5SSteve French 
65038c8a9a5SSteve French /**
65138c8a9a5SSteve French  * Generic VFS superblock mount flags (s_flags) to consider when
65238c8a9a5SSteve French  * trying to reuse existing superblock for a new mount
65338c8a9a5SSteve French  */
65438c8a9a5SSteve French #define CIFS_MS_MASK (SB_RDONLY | SB_MANDLOCK | SB_NOEXEC | SB_NOSUID | \
65538c8a9a5SSteve French 		      SB_NODEV | SB_SYNCHRONOUS)
65638c8a9a5SSteve French 
65738c8a9a5SSteve French struct cifs_mnt_data {
65838c8a9a5SSteve French 	struct cifs_sb_info *cifs_sb;
65938c8a9a5SSteve French 	struct smb3_fs_context *ctx;
66038c8a9a5SSteve French 	int flags;
66138c8a9a5SSteve French };
66238c8a9a5SSteve French 
66338c8a9a5SSteve French static inline unsigned int
get_rfc1002_length(void * buf)66438c8a9a5SSteve French get_rfc1002_length(void *buf)
66538c8a9a5SSteve French {
66638c8a9a5SSteve French 	return be32_to_cpu(*((__be32 *)buf)) & 0xffffff;
66738c8a9a5SSteve French }
66838c8a9a5SSteve French 
66938c8a9a5SSteve French static inline void
inc_rfc1001_len(void * buf,int count)67038c8a9a5SSteve French inc_rfc1001_len(void *buf, int count)
67138c8a9a5SSteve French {
67238c8a9a5SSteve French 	be32_add_cpu((__be32 *)buf, count);
67338c8a9a5SSteve French }
67438c8a9a5SSteve French 
67538c8a9a5SSteve French struct TCP_Server_Info {
67638c8a9a5SSteve French 	struct list_head tcp_ses_list;
67738c8a9a5SSteve French 	struct list_head smb_ses_list;
67838c8a9a5SSteve French 	spinlock_t srv_lock;  /* protect anything here that is not protected */
67938c8a9a5SSteve French 	__u64 conn_id; /* connection identifier (useful for debugging) */
68038c8a9a5SSteve French 	int srv_count; /* reference counter */
68138c8a9a5SSteve French 	/* 15 character server name + 0x20 16th byte indicating type = srv */
68238c8a9a5SSteve French 	char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
68338c8a9a5SSteve French 	struct smb_version_operations	*ops;
68438c8a9a5SSteve French 	struct smb_version_values	*vals;
68538c8a9a5SSteve French 	/* updates to tcpStatus protected by cifs_tcp_ses_lock */
68638c8a9a5SSteve French 	enum statusEnum tcpStatus; /* what we think the status is */
68738c8a9a5SSteve French 	char *hostname; /* hostname portion of UNC string */
68838c8a9a5SSteve French 	struct socket *ssocket;
68938c8a9a5SSteve French 	struct sockaddr_storage dstaddr;
69038c8a9a5SSteve French 	struct sockaddr_storage srcaddr; /* locally bind to this IP */
69138c8a9a5SSteve French #ifdef CONFIG_NET_NS
69238c8a9a5SSteve French 	struct net *net;
69338c8a9a5SSteve French #endif
69438c8a9a5SSteve French 	wait_queue_head_t response_q;
69538c8a9a5SSteve French 	wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
69638c8a9a5SSteve French 	spinlock_t mid_lock;  /* protect mid queue and it's entries */
69738c8a9a5SSteve French 	struct list_head pending_mid_q;
69838c8a9a5SSteve French 	bool noblocksnd;		/* use blocking sendmsg */
69938c8a9a5SSteve French 	bool noautotune;		/* do not autotune send buf sizes */
70038c8a9a5SSteve French 	bool nosharesock;
70138c8a9a5SSteve French 	bool tcp_nodelay;
7023e161536SShyam Prasad N 	bool terminate;
70338c8a9a5SSteve French 	unsigned int credits;  /* send no more requests at once */
70438c8a9a5SSteve French 	unsigned int max_credits; /* can override large 32000 default at mnt */
70538c8a9a5SSteve French 	unsigned int in_flight;  /* number of requests on the wire to server */
70638c8a9a5SSteve French 	unsigned int max_in_flight; /* max number of requests that were on wire */
70738c8a9a5SSteve French 	spinlock_t req_lock;  /* protect the two values above */
70838c8a9a5SSteve French 	struct mutex _srv_mutex;
70938c8a9a5SSteve French 	unsigned int nofs_flag;
71038c8a9a5SSteve French 	struct task_struct *tsk;
71138c8a9a5SSteve French 	char server_GUID[16];
71238c8a9a5SSteve French 	__u16 sec_mode;
71338c8a9a5SSteve French 	bool sign; /* is signing enabled on this connection? */
71438c8a9a5SSteve French 	bool ignore_signature:1; /* skip validation of signatures in SMB2/3 rsp */
71538c8a9a5SSteve French 	bool session_estab; /* mark when very first sess is established */
71638c8a9a5SSteve French 	int echo_credits;  /* echo reserved slots */
71738c8a9a5SSteve French 	int oplock_credits;  /* oplock break reserved slots */
71838c8a9a5SSteve French 	bool echoes:1; /* enable echoes */
71938c8a9a5SSteve French 	__u8 client_guid[SMB2_CLIENT_GUID_SIZE]; /* Client GUID */
72038c8a9a5SSteve French 	u16 dialect; /* dialect index that server chose */
72138c8a9a5SSteve French 	bool oplocks:1; /* enable oplocks */
72238c8a9a5SSteve French 	unsigned int maxReq;	/* Clients should submit no more */
72338c8a9a5SSteve French 	/* than maxReq distinct unanswered SMBs to the server when using  */
72438c8a9a5SSteve French 	/* multiplexed reads or writes (for SMB1/CIFS only, not SMB2/SMB3) */
72538c8a9a5SSteve French 	unsigned int maxBuf;	/* maxBuf specifies the maximum */
72638c8a9a5SSteve French 	/* message size the server can send or receive for non-raw SMBs */
72738c8a9a5SSteve French 	/* maxBuf is returned by SMB NegotiateProtocol so maxBuf is only 0 */
72838c8a9a5SSteve French 	/* when socket is setup (and during reconnect) before NegProt sent */
72938c8a9a5SSteve French 	unsigned int max_rw;	/* maxRw specifies the maximum */
73038c8a9a5SSteve French 	/* message size the server can send or receive for */
73138c8a9a5SSteve French 	/* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
73238c8a9a5SSteve French 	unsigned int capabilities; /* selective disabling of caps by smb sess */
73338c8a9a5SSteve French 	int timeAdj;  /* Adjust for difference in server time zone in sec */
73438c8a9a5SSteve French 	__u64 CurrentMid;         /* multiplex id - rotating counter, protected by GlobalMid_Lock */
73538c8a9a5SSteve French 	char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
73638c8a9a5SSteve French 	/* 16th byte of RFC1001 workstation name is always null */
73738c8a9a5SSteve French 	char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
73838c8a9a5SSteve French 	__u32 sequence_number; /* for signing, protected by srv_mutex */
73938c8a9a5SSteve French 	__u32 reconnect_instance; /* incremented on each reconnect */
74038c8a9a5SSteve French 	struct session_key session_key;
74138c8a9a5SSteve French 	unsigned long lstrp; /* when we got last response from this server */
74238c8a9a5SSteve French 	struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */
74338c8a9a5SSteve French #define	CIFS_NEGFLAVOR_UNENCAP	1	/* wct == 17, but no ext_sec */
74438c8a9a5SSteve French #define	CIFS_NEGFLAVOR_EXTENDED	2	/* wct == 17, ext_sec bit set */
74538c8a9a5SSteve French 	char	negflavor;	/* NEGOTIATE response flavor */
74638c8a9a5SSteve French 	/* extended security flavors that server supports */
74738c8a9a5SSteve French 	bool	sec_ntlmssp;		/* supports NTLMSSP */
74838c8a9a5SSteve French 	bool	sec_kerberosu2u;	/* supports U2U Kerberos */
74938c8a9a5SSteve French 	bool	sec_kerberos;		/* supports plain Kerberos */
75038c8a9a5SSteve French 	bool	sec_mskerberos;		/* supports legacy MS Kerberos */
75138c8a9a5SSteve French 	bool	large_buf;		/* is current buffer large? */
75238c8a9a5SSteve French 	/* use SMBD connection instead of socket */
75338c8a9a5SSteve French 	bool	rdma;
75438c8a9a5SSteve French 	/* point to the SMBD connection if RDMA is used instead of socket */
75538c8a9a5SSteve French 	struct smbd_connection *smbd_conn;
75638c8a9a5SSteve French 	struct delayed_work	echo; /* echo ping workqueue job */
75738c8a9a5SSteve French 	char	*smallbuf;	/* pointer to current "small" buffer */
75838c8a9a5SSteve French 	char	*bigbuf;	/* pointer to current "big" buffer */
75938c8a9a5SSteve French 	/* Total size of this PDU. Only valid from cifs_demultiplex_thread */
76038c8a9a5SSteve French 	unsigned int pdu_size;
76138c8a9a5SSteve French 	unsigned int total_read; /* total amount of data read in this pass */
76238c8a9a5SSteve French 	atomic_t in_send; /* requests trying to send */
76338c8a9a5SSteve French 	atomic_t num_waiters;   /* blocked waiting to get in sendrecv */
76438c8a9a5SSteve French #ifdef CONFIG_CIFS_STATS2
76538c8a9a5SSteve French 	atomic_t num_cmds[NUMBER_OF_SMB2_COMMANDS]; /* total requests by cmd */
76638c8a9a5SSteve French 	atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */
76738c8a9a5SSteve French 	__u64 time_per_cmd[NUMBER_OF_SMB2_COMMANDS]; /* total time per cmd */
76838c8a9a5SSteve French 	__u32 slowest_cmd[NUMBER_OF_SMB2_COMMANDS];
76938c8a9a5SSteve French 	__u32 fastest_cmd[NUMBER_OF_SMB2_COMMANDS];
77038c8a9a5SSteve French #endif /* STATS2 */
77138c8a9a5SSteve French 	unsigned int	max_read;
77238c8a9a5SSteve French 	unsigned int	max_write;
77338c8a9a5SSteve French 	unsigned int	min_offload;
774b4ca2942SShyam Prasad N 	unsigned int	retrans;
775e8aee4f4SEnzo Matsumiya 	struct {
776e8aee4f4SEnzo Matsumiya 		bool requested; /* "compress" mount option set*/
777e8aee4f4SEnzo Matsumiya 		bool enabled; /* actually negotiated with server */
778e8aee4f4SEnzo Matsumiya 		__le16 alg; /* preferred alg negotiated with server */
779e8aee4f4SEnzo Matsumiya 	} compression;
78038c8a9a5SSteve French 	__u16	signing_algorithm;
78138c8a9a5SSteve French 	__le16	cipher_type;
78238c8a9a5SSteve French 	 /* save initital negprot hash */
78338c8a9a5SSteve French 	__u8	preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
78438c8a9a5SSteve French 	bool	signing_negotiated; /* true if valid signing context rcvd from server */
78538c8a9a5SSteve French 	bool	posix_ext_supported;
78638c8a9a5SSteve French 	struct delayed_work reconnect; /* reconnect workqueue job */
78738c8a9a5SSteve French 	struct mutex reconnect_mutex; /* prevent simultaneous reconnects */
78838c8a9a5SSteve French 	unsigned long echo_interval;
78938c8a9a5SSteve French 
79038c8a9a5SSteve French 	/*
79138c8a9a5SSteve French 	 * Number of targets available for reconnect. The more targets
79238c8a9a5SSteve French 	 * the more tasks have to wait to let the demultiplex thread
79338c8a9a5SSteve French 	 * reconnect.
79438c8a9a5SSteve French 	 */
79538c8a9a5SSteve French 	int nr_targets;
79638c8a9a5SSteve French 	bool noblockcnt; /* use non-blocking connect() */
79738c8a9a5SSteve French 
79838c8a9a5SSteve French 	/*
79938c8a9a5SSteve French 	 * If this is a session channel,
80038c8a9a5SSteve French 	 * primary_server holds the ref-counted
80138c8a9a5SSteve French 	 * pointer to primary channel connection for the session.
80238c8a9a5SSteve French 	 */
803b3773b19SSteve French #define SERVER_IS_CHAN(server)	(!!(server)->primary_server)
80438c8a9a5SSteve French 	struct TCP_Server_Info *primary_server;
80509ee7a3bSSteve French 	__u16 channel_sequence_num;  /* incremented on primary channel on each chan reconnect */
80638c8a9a5SSteve French 
80738c8a9a5SSteve French #ifdef CONFIG_CIFS_SWN_UPCALL
80838c8a9a5SSteve French 	bool use_swn_dstaddr;
80938c8a9a5SSteve French 	struct sockaddr_storage swn_dstaddr;
81038c8a9a5SSteve French #endif
81138c8a9a5SSteve French 	struct mutex refpath_lock; /* protects leaf_fullpath */
81238c8a9a5SSteve French 	/*
81338c8a9a5SSteve French 	 * leaf_fullpath: Canonical DFS referral path related to this
81438c8a9a5SSteve French 	 *                connection.
81538c8a9a5SSteve French 	 *                It is used in DFS cache refresher, reconnect and may
81638c8a9a5SSteve French 	 *                change due to nested DFS links.
81738c8a9a5SSteve French 	 *
8183ae872deSPaulo Alcantara 	 * Protected by @refpath_lock and @srv_lock.  The @refpath_lock is
8193ae872deSPaulo Alcantara 	 * mostly used for not requiring a copy of @leaf_fullpath when getting
82038c8a9a5SSteve French 	 * cached or new DFS referrals (which might also sleep during I/O).
82138c8a9a5SSteve French 	 * While @srv_lock is held for making string and NULL comparions against
82238c8a9a5SSteve French 	 * both fields as in mount(2) and cache refresh.
82338c8a9a5SSteve French 	 *
82438c8a9a5SSteve French 	 * format: \\HOST\SHARE[\OPTIONAL PATH]
82538c8a9a5SSteve French 	 */
8263ae872deSPaulo Alcantara 	char *leaf_fullpath;
82738c8a9a5SSteve French };
82838c8a9a5SSteve French 
is_smb1(struct TCP_Server_Info * server)82938c8a9a5SSteve French static inline bool is_smb1(struct TCP_Server_Info *server)
83038c8a9a5SSteve French {
83138c8a9a5SSteve French 	return HEADER_PREAMBLE_SIZE(server) != 0;
83238c8a9a5SSteve French }
83338c8a9a5SSteve French 
cifs_server_lock(struct TCP_Server_Info * server)83438c8a9a5SSteve French static inline void cifs_server_lock(struct TCP_Server_Info *server)
83538c8a9a5SSteve French {
83638c8a9a5SSteve French 	unsigned int nofs_flag = memalloc_nofs_save();
83738c8a9a5SSteve French 
83838c8a9a5SSteve French 	mutex_lock(&server->_srv_mutex);
83938c8a9a5SSteve French 	server->nofs_flag = nofs_flag;
84038c8a9a5SSteve French }
84138c8a9a5SSteve French 
cifs_server_unlock(struct TCP_Server_Info * server)84238c8a9a5SSteve French static inline void cifs_server_unlock(struct TCP_Server_Info *server)
84338c8a9a5SSteve French {
84438c8a9a5SSteve French 	unsigned int nofs_flag = server->nofs_flag;
84538c8a9a5SSteve French 
84638c8a9a5SSteve French 	mutex_unlock(&server->_srv_mutex);
84738c8a9a5SSteve French 	memalloc_nofs_restore(nofs_flag);
84838c8a9a5SSteve French }
84938c8a9a5SSteve French 
85038c8a9a5SSteve French struct cifs_credits {
85138c8a9a5SSteve French 	unsigned int value;
85238c8a9a5SSteve French 	unsigned int instance;
85338c8a9a5SSteve French };
85438c8a9a5SSteve French 
85538c8a9a5SSteve French static inline unsigned int
in_flight(struct TCP_Server_Info * server)85638c8a9a5SSteve French in_flight(struct TCP_Server_Info *server)
85738c8a9a5SSteve French {
85838c8a9a5SSteve French 	unsigned int num;
85938c8a9a5SSteve French 
86038c8a9a5SSteve French 	spin_lock(&server->req_lock);
86138c8a9a5SSteve French 	num = server->in_flight;
86238c8a9a5SSteve French 	spin_unlock(&server->req_lock);
86338c8a9a5SSteve French 	return num;
86438c8a9a5SSteve French }
86538c8a9a5SSteve French 
86638c8a9a5SSteve French static inline bool
has_credits(struct TCP_Server_Info * server,int * credits,int num_credits)86738c8a9a5SSteve French has_credits(struct TCP_Server_Info *server, int *credits, int num_credits)
86838c8a9a5SSteve French {
86938c8a9a5SSteve French 	int num;
87038c8a9a5SSteve French 
87138c8a9a5SSteve French 	spin_lock(&server->req_lock);
87238c8a9a5SSteve French 	num = *credits;
87338c8a9a5SSteve French 	spin_unlock(&server->req_lock);
87438c8a9a5SSteve French 	return num >= num_credits;
87538c8a9a5SSteve French }
87638c8a9a5SSteve French 
87738c8a9a5SSteve French static inline void
add_credits(struct TCP_Server_Info * server,const struct cifs_credits * credits,const int optype)87838c8a9a5SSteve French add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits,
87938c8a9a5SSteve French 	    const int optype)
88038c8a9a5SSteve French {
88138c8a9a5SSteve French 	server->ops->add_credits(server, credits, optype);
88238c8a9a5SSteve French }
88338c8a9a5SSteve French 
88438c8a9a5SSteve French static inline void
add_credits_and_wake_if(struct TCP_Server_Info * server,const struct cifs_credits * credits,const int optype)88538c8a9a5SSteve French add_credits_and_wake_if(struct TCP_Server_Info *server,
88638c8a9a5SSteve French 			const struct cifs_credits *credits, const int optype)
88738c8a9a5SSteve French {
88838c8a9a5SSteve French 	if (credits->value) {
88938c8a9a5SSteve French 		server->ops->add_credits(server, credits, optype);
89038c8a9a5SSteve French 		wake_up(&server->request_q);
89138c8a9a5SSteve French 	}
89238c8a9a5SSteve French }
89338c8a9a5SSteve French 
89438c8a9a5SSteve French static inline void
set_credits(struct TCP_Server_Info * server,const int val)89538c8a9a5SSteve French set_credits(struct TCP_Server_Info *server, const int val)
89638c8a9a5SSteve French {
89738c8a9a5SSteve French 	server->ops->set_credits(server, val);
89838c8a9a5SSteve French }
89938c8a9a5SSteve French 
90038c8a9a5SSteve French static inline int
adjust_credits(struct TCP_Server_Info * server,struct cifs_credits * credits,const unsigned int payload_size)90138c8a9a5SSteve French adjust_credits(struct TCP_Server_Info *server, struct cifs_credits *credits,
90238c8a9a5SSteve French 	       const unsigned int payload_size)
90338c8a9a5SSteve French {
90438c8a9a5SSteve French 	return server->ops->adjust_credits ?
90538c8a9a5SSteve French 		server->ops->adjust_credits(server, credits, payload_size) : 0;
90638c8a9a5SSteve French }
90738c8a9a5SSteve French 
90838c8a9a5SSteve French static inline __le64
get_next_mid64(struct TCP_Server_Info * server)90938c8a9a5SSteve French get_next_mid64(struct TCP_Server_Info *server)
91038c8a9a5SSteve French {
91138c8a9a5SSteve French 	return cpu_to_le64(server->ops->get_next_mid(server));
91238c8a9a5SSteve French }
91338c8a9a5SSteve French 
91438c8a9a5SSteve French static inline __le16
get_next_mid(struct TCP_Server_Info * server)91538c8a9a5SSteve French get_next_mid(struct TCP_Server_Info *server)
91638c8a9a5SSteve French {
91738c8a9a5SSteve French 	__u16 mid = server->ops->get_next_mid(server);
91838c8a9a5SSteve French 	/*
91938c8a9a5SSteve French 	 * The value in the SMB header should be little endian for easy
92038c8a9a5SSteve French 	 * on-the-wire decoding.
92138c8a9a5SSteve French 	 */
92238c8a9a5SSteve French 	return cpu_to_le16(mid);
92338c8a9a5SSteve French }
92438c8a9a5SSteve French 
92538c8a9a5SSteve French static inline void
revert_current_mid(struct TCP_Server_Info * server,const unsigned int val)92638c8a9a5SSteve French revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
92738c8a9a5SSteve French {
92838c8a9a5SSteve French 	if (server->ops->revert_current_mid)
92938c8a9a5SSteve French 		server->ops->revert_current_mid(server, val);
93038c8a9a5SSteve French }
93138c8a9a5SSteve French 
93238c8a9a5SSteve French static inline void
revert_current_mid_from_hdr(struct TCP_Server_Info * server,const struct smb2_hdr * shdr)93338c8a9a5SSteve French revert_current_mid_from_hdr(struct TCP_Server_Info *server,
93438c8a9a5SSteve French 			    const struct smb2_hdr *shdr)
93538c8a9a5SSteve French {
93638c8a9a5SSteve French 	unsigned int num = le16_to_cpu(shdr->CreditCharge);
93738c8a9a5SSteve French 
93838c8a9a5SSteve French 	return revert_current_mid(server, num > 0 ? num : 1);
93938c8a9a5SSteve French }
94038c8a9a5SSteve French 
94138c8a9a5SSteve French static inline __u16
get_mid(const struct smb_hdr * smb)94238c8a9a5SSteve French get_mid(const struct smb_hdr *smb)
94338c8a9a5SSteve French {
94438c8a9a5SSteve French 	return le16_to_cpu(smb->Mid);
94538c8a9a5SSteve French }
94638c8a9a5SSteve French 
94738c8a9a5SSteve French static inline bool
compare_mid(__u16 mid,const struct smb_hdr * smb)94838c8a9a5SSteve French compare_mid(__u16 mid, const struct smb_hdr *smb)
94938c8a9a5SSteve French {
95038c8a9a5SSteve French 	return mid == le16_to_cpu(smb->Mid);
95138c8a9a5SSteve French }
95238c8a9a5SSteve French 
95338c8a9a5SSteve French /*
95438c8a9a5SSteve French  * When the server supports very large reads and writes via POSIX extensions,
95538c8a9a5SSteve French  * we can allow up to 2^24-1, minus the size of a READ/WRITE_AND_X header, not
95638c8a9a5SSteve French  * including the RFC1001 length.
95738c8a9a5SSteve French  *
95838c8a9a5SSteve French  * Note that this might make for "interesting" allocation problems during
95938c8a9a5SSteve French  * writeback however as we have to allocate an array of pointers for the
96038c8a9a5SSteve French  * pages. A 16M write means ~32kb page array with PAGE_SIZE == 4096.
96138c8a9a5SSteve French  *
96238c8a9a5SSteve French  * For reads, there is a similar problem as we need to allocate an array
96338c8a9a5SSteve French  * of kvecs to handle the receive, though that should only need to be done
96438c8a9a5SSteve French  * once.
96538c8a9a5SSteve French  */
96638c8a9a5SSteve French #define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4)
96738c8a9a5SSteve French #define CIFS_MAX_RSIZE ((1<<24) - sizeof(READ_RSP) + 4)
96838c8a9a5SSteve French 
96938c8a9a5SSteve French /*
97038c8a9a5SSteve French  * When the server doesn't allow large posix writes, only allow a rsize/wsize
97138c8a9a5SSteve French  * of 2^17-1 minus the size of the call header. That allows for a read or
97238c8a9a5SSteve French  * write up to the maximum size described by RFC1002.
97338c8a9a5SSteve French  */
97438c8a9a5SSteve French #define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4)
97538c8a9a5SSteve French #define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4)
97638c8a9a5SSteve French 
97738c8a9a5SSteve French #define CIFS_DEFAULT_IOSIZE (1024 * 1024)
97838c8a9a5SSteve French 
97938c8a9a5SSteve French /*
98038c8a9a5SSteve French  * Windows only supports a max of 60kb reads and 65535 byte writes. Default to
98138c8a9a5SSteve French  * those values when posix extensions aren't in force. In actuality here, we
98238c8a9a5SSteve French  * use 65536 to allow for a write that is a multiple of 4k. Most servers seem
98338c8a9a5SSteve French  * to be ok with the extra byte even though Windows doesn't send writes that
98438c8a9a5SSteve French  * are that large.
98538c8a9a5SSteve French  *
98638c8a9a5SSteve French  * Citation:
98738c8a9a5SSteve French  *
98838c8a9a5SSteve French  * https://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx
98938c8a9a5SSteve French  */
99038c8a9a5SSteve French #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
99138c8a9a5SSteve French #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
99238c8a9a5SSteve French 
99338c8a9a5SSteve French /*
99438c8a9a5SSteve French  * Macros to allow the TCP_Server_Info->net field and related code to drop out
99538c8a9a5SSteve French  * when CONFIG_NET_NS isn't set.
99638c8a9a5SSteve French  */
99738c8a9a5SSteve French 
99838c8a9a5SSteve French #ifdef CONFIG_NET_NS
99938c8a9a5SSteve French 
cifs_net_ns(struct TCP_Server_Info * srv)100038c8a9a5SSteve French static inline struct net *cifs_net_ns(struct TCP_Server_Info *srv)
100138c8a9a5SSteve French {
100238c8a9a5SSteve French 	return srv->net;
100338c8a9a5SSteve French }
100438c8a9a5SSteve French 
cifs_set_net_ns(struct TCP_Server_Info * srv,struct net * net)100538c8a9a5SSteve French static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
100638c8a9a5SSteve French {
100738c8a9a5SSteve French 	srv->net = net;
100838c8a9a5SSteve French }
100938c8a9a5SSteve French 
101038c8a9a5SSteve French #else
101138c8a9a5SSteve French 
cifs_net_ns(struct TCP_Server_Info * srv)101238c8a9a5SSteve French static inline struct net *cifs_net_ns(struct TCP_Server_Info *srv)
101338c8a9a5SSteve French {
101438c8a9a5SSteve French 	return &init_net;
101538c8a9a5SSteve French }
101638c8a9a5SSteve French 
cifs_set_net_ns(struct TCP_Server_Info * srv,struct net * net)101738c8a9a5SSteve French static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
101838c8a9a5SSteve French {
101938c8a9a5SSteve French }
102038c8a9a5SSteve French 
102138c8a9a5SSteve French #endif
102238c8a9a5SSteve French 
102338c8a9a5SSteve French struct cifs_server_iface {
102438c8a9a5SSteve French 	struct list_head iface_head;
102538c8a9a5SSteve French 	struct kref refcount;
102638c8a9a5SSteve French 	size_t speed;
10271cd8c353SShyam Prasad N 	size_t weight_fulfilled;
10281cd8c353SShyam Prasad N 	unsigned int num_channels;
102938c8a9a5SSteve French 	unsigned int rdma_capable : 1;
103038c8a9a5SSteve French 	unsigned int rss_capable : 1;
103138c8a9a5SSteve French 	unsigned int is_active : 1; /* unset if non existent */
103238c8a9a5SSteve French 	struct sockaddr_storage sockaddr;
103338c8a9a5SSteve French };
103438c8a9a5SSteve French 
103538c8a9a5SSteve French /* release iface when last ref is dropped */
103638c8a9a5SSteve French static inline void
release_iface(struct kref * ref)103738c8a9a5SSteve French release_iface(struct kref *ref)
103838c8a9a5SSteve French {
103938c8a9a5SSteve French 	struct cifs_server_iface *iface = container_of(ref,
104038c8a9a5SSteve French 						       struct cifs_server_iface,
104138c8a9a5SSteve French 						       refcount);
104238c8a9a5SSteve French 	kfree(iface);
104338c8a9a5SSteve French }
104438c8a9a5SSteve French 
104538c8a9a5SSteve French struct cifs_chan {
104638c8a9a5SSteve French 	unsigned int in_reconnect : 1; /* if session setup in progress for this channel */
104738c8a9a5SSteve French 	struct TCP_Server_Info *server;
104838c8a9a5SSteve French 	struct cifs_server_iface *iface; /* interface in use */
104938c8a9a5SSteve French 	__u8 signkey[SMB3_SIGN_KEY_SIZE];
105038c8a9a5SSteve French };
105138c8a9a5SSteve French 
1052567f1b1dSShyam Prasad N #define CIFS_SES_FLAG_SCALE_CHANNELS (0x1)
1053567f1b1dSShyam Prasad N 
105438c8a9a5SSteve French /*
105538c8a9a5SSteve French  * Session structure.  One of these for each uid session with a particular host
105638c8a9a5SSteve French  */
105738c8a9a5SSteve French struct cifs_ses {
105838c8a9a5SSteve French 	struct list_head smb_ses_list;
105938c8a9a5SSteve French 	struct list_head rlist; /* reconnect list */
106038c8a9a5SSteve French 	struct list_head tcon_list;
106138c8a9a5SSteve French 	struct cifs_tcon *tcon_ipc;
106238c8a9a5SSteve French 	spinlock_t ses_lock;  /* protect anything here that is not protected */
106338c8a9a5SSteve French 	struct mutex session_mutex;
106438c8a9a5SSteve French 	struct TCP_Server_Info *server;	/* pointer to server info */
106538c8a9a5SSteve French 	int ses_count;		/* reference counter */
106638c8a9a5SSteve French 	enum ses_status_enum ses_status;  /* updates protected by cifs_tcp_ses_lock */
106738c8a9a5SSteve French 	unsigned int overrideSecFlg; /* if non-zero override global sec flags */
106838c8a9a5SSteve French 	char *serverOS;		/* name of operating system underlying server */
106938c8a9a5SSteve French 	char *serverNOS;	/* name of network operating system of server */
107038c8a9a5SSteve French 	char *serverDomain;	/* security realm of server */
107138c8a9a5SSteve French 	__u64 Suid;		/* remote smb uid  */
107238c8a9a5SSteve French 	kuid_t linux_uid;	/* overriding owner of files on the mount */
107338c8a9a5SSteve French 	kuid_t cred_uid;	/* owner of credentials */
107438c8a9a5SSteve French 	unsigned int capabilities;
107538c8a9a5SSteve French 	char ip_addr[INET6_ADDRSTRLEN + 1]; /* Max ipv6 (or v4) addr string len */
107638c8a9a5SSteve French 	char *user_name;	/* must not be null except during init of sess
107738c8a9a5SSteve French 				   and after mount option parsing we fill it */
107838c8a9a5SSteve French 	char *domainName;
107938c8a9a5SSteve French 	char *password;
108008bedfbcSSteve French 	char *password2; /* When key rotation used, new password may be set before it expires */
108138c8a9a5SSteve French 	char workstation_name[CIFS_MAX_WORKSTATION_LEN];
108238c8a9a5SSteve French 	struct session_key auth_key;
108338c8a9a5SSteve French 	struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
108438c8a9a5SSteve French 	enum securityEnum sectype; /* what security flavor was specified? */
108538c8a9a5SSteve French 	bool sign;		/* is signing required? */
108638c8a9a5SSteve French 	bool domainAuto:1;
10877e8cffa4SSteve French 	bool expired_pwd;  /* track if access denied or expired pwd so can know if need to update */
1088567f1b1dSShyam Prasad N 	unsigned int flags;
108938c8a9a5SSteve French 	__u16 session_flags;
109038c8a9a5SSteve French 	__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
109138c8a9a5SSteve French 	__u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE];
109238c8a9a5SSteve French 	__u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];
109338c8a9a5SSteve French 	__u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
109438c8a9a5SSteve French 
109538c8a9a5SSteve French 	/*
109638c8a9a5SSteve French 	 * Network interfaces available on the server this session is
109738c8a9a5SSteve French 	 * connected to.
109838c8a9a5SSteve French 	 *
109938c8a9a5SSteve French 	 * Other channels can be opened by connecting and binding this
110038c8a9a5SSteve French 	 * session to interfaces from this list.
110138c8a9a5SSteve French 	 *
110238c8a9a5SSteve French 	 * iface_lock should be taken when accessing any of these fields
110338c8a9a5SSteve French 	 */
110438c8a9a5SSteve French 	spinlock_t iface_lock;
110538c8a9a5SSteve French 	/* ========= begin: protected by iface_lock ======== */
110638c8a9a5SSteve French 	struct list_head iface_list;
110738c8a9a5SSteve French 	size_t iface_count;
110838c8a9a5SSteve French 	unsigned long iface_last_update; /* jiffies */
110938c8a9a5SSteve French 	/* ========= end: protected by iface_lock ======== */
111038c8a9a5SSteve French 
111138c8a9a5SSteve French 	spinlock_t chan_lock;
111238c8a9a5SSteve French 	/* ========= begin: protected by chan_lock ======== */
111338c8a9a5SSteve French #define CIFS_MAX_CHANNELS 16
1114c395f798SShyam Prasad N #define CIFS_INVAL_CHAN_INDEX (-1)
111538c8a9a5SSteve French #define CIFS_ALL_CHANNELS_SET(ses)	\
111638c8a9a5SSteve French 	((1UL << (ses)->chan_count) - 1)
111738c8a9a5SSteve French #define CIFS_ALL_CHANS_GOOD(ses)		\
111838c8a9a5SSteve French 	(!(ses)->chans_need_reconnect)
111938c8a9a5SSteve French #define CIFS_ALL_CHANS_NEED_RECONNECT(ses)	\
112038c8a9a5SSteve French 	((ses)->chans_need_reconnect == CIFS_ALL_CHANNELS_SET(ses))
112138c8a9a5SSteve French #define CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses)	\
112238c8a9a5SSteve French 	((ses)->chans_need_reconnect = CIFS_ALL_CHANNELS_SET(ses))
112338c8a9a5SSteve French #define CIFS_CHAN_NEEDS_RECONNECT(ses, index)	\
112438c8a9a5SSteve French 	test_bit((index), &(ses)->chans_need_reconnect)
112538c8a9a5SSteve French #define CIFS_CHAN_IN_RECONNECT(ses, index)	\
112638c8a9a5SSteve French 	((ses)->chans[(index)].in_reconnect)
112738c8a9a5SSteve French 
112838c8a9a5SSteve French 	struct cifs_chan chans[CIFS_MAX_CHANNELS];
112938c8a9a5SSteve French 	size_t chan_count;
113038c8a9a5SSteve French 	size_t chan_max;
113138c8a9a5SSteve French 	atomic_t chan_seq; /* round robin state */
113238c8a9a5SSteve French 
113338c8a9a5SSteve French 	/*
113438c8a9a5SSteve French 	 * chans_need_reconnect is a bitmap indicating which of the channels
113538c8a9a5SSteve French 	 * under this smb session needs to be reconnected.
113638c8a9a5SSteve French 	 * If not multichannel session, only one bit will be used.
113738c8a9a5SSteve French 	 *
113838c8a9a5SSteve French 	 * We will ask for sess and tcon reconnection only if all the
113938c8a9a5SSteve French 	 * channels are marked for needing reconnection. This will
114038c8a9a5SSteve French 	 * enable the sessions on top to continue to live till any
114138c8a9a5SSteve French 	 * of the channels below are active.
114238c8a9a5SSteve French 	 */
114338c8a9a5SSteve French 	unsigned long chans_need_reconnect;
114438c8a9a5SSteve French 	/* ========= end: protected by chan_lock ======== */
114538c8a9a5SSteve French 	struct cifs_ses *dfs_root_ses;
1146a43f95fdSWinston Wen 	struct nls_table *local_nls;
114738c8a9a5SSteve French };
114838c8a9a5SSteve French 
114938c8a9a5SSteve French static inline bool
cap_unix(struct cifs_ses * ses)115038c8a9a5SSteve French cap_unix(struct cifs_ses *ses)
115138c8a9a5SSteve French {
115238c8a9a5SSteve French 	return ses->server->vals->cap_unix & ses->capabilities;
115338c8a9a5SSteve French }
115438c8a9a5SSteve French 
115538c8a9a5SSteve French /*
115638c8a9a5SSteve French  * common struct for holding inode info when searching for or updating an
115738c8a9a5SSteve French  * inode with new info
115838c8a9a5SSteve French  */
115938c8a9a5SSteve French 
1160a18280e7SPaulo Alcantara #define CIFS_FATTR_JUNCTION		0x1
116138c8a9a5SSteve French #define CIFS_FATTR_DELETE_PENDING	0x2
116238c8a9a5SSteve French #define CIFS_FATTR_NEED_REVAL		0x4
116338c8a9a5SSteve French #define CIFS_FATTR_INO_COLLISION	0x8
116438c8a9a5SSteve French #define CIFS_FATTR_UNKNOWN_NLINK	0x10
116538c8a9a5SSteve French #define CIFS_FATTR_FAKE_ROOT_INO	0x20
116638c8a9a5SSteve French 
116738c8a9a5SSteve French struct cifs_fattr {
116838c8a9a5SSteve French 	u32		cf_flags;
116938c8a9a5SSteve French 	u32		cf_cifsattrs;
117038c8a9a5SSteve French 	u64		cf_uniqueid;
117138c8a9a5SSteve French 	u64		cf_eof;
117238c8a9a5SSteve French 	u64		cf_bytes;
117338c8a9a5SSteve French 	u64		cf_createtime;
117438c8a9a5SSteve French 	kuid_t		cf_uid;
117538c8a9a5SSteve French 	kgid_t		cf_gid;
117638c8a9a5SSteve French 	umode_t		cf_mode;
117738c8a9a5SSteve French 	dev_t		cf_rdev;
117838c8a9a5SSteve French 	unsigned int	cf_nlink;
117938c8a9a5SSteve French 	unsigned int	cf_dtype;
118038c8a9a5SSteve French 	struct timespec64 cf_atime;
118138c8a9a5SSteve French 	struct timespec64 cf_mtime;
118238c8a9a5SSteve French 	struct timespec64 cf_ctime;
118338c8a9a5SSteve French 	u32             cf_cifstag;
118438c8a9a5SSteve French 	char            *cf_symlink_target;
118538c8a9a5SSteve French };
118638c8a9a5SSteve French 
118738c8a9a5SSteve French /*
118838c8a9a5SSteve French  * there is one of these for each connection to a resource on a particular
118938c8a9a5SSteve French  * session
119038c8a9a5SSteve French  */
119138c8a9a5SSteve French struct cifs_tcon {
119238c8a9a5SSteve French 	struct list_head tcon_list;
119307e76ea1SDavid Howells 	int debug_id;		/* Debugging for tracing */
119438c8a9a5SSteve French 	int tc_count;
119538c8a9a5SSteve French 	struct list_head rlist; /* reconnect list */
119638c8a9a5SSteve French 	spinlock_t tc_lock;  /* protect anything here that is not protected */
119738c8a9a5SSteve French 	atomic_t num_local_opens;  /* num of all opens including disconnected */
119838c8a9a5SSteve French 	atomic_t num_remote_opens; /* num of all network opens on server */
119938c8a9a5SSteve French 	struct list_head openFileList;
120038c8a9a5SSteve French 	spinlock_t open_file_lock; /* protects list above */
120138c8a9a5SSteve French 	struct cifs_ses *ses;	/* pointer to session associated with */
120238c8a9a5SSteve French 	char tree_name[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
120338c8a9a5SSteve French 	char *nativeFileSystem;
120438c8a9a5SSteve French 	char *password;		/* for share-level security */
120538c8a9a5SSteve French 	__u32 tid;		/* The 4 byte tree id */
120638c8a9a5SSteve French 	__u16 Flags;		/* optional support bits */
120738c8a9a5SSteve French 	enum tid_status_enum status;
120838c8a9a5SSteve French 	atomic_t num_smbs_sent;
120938c8a9a5SSteve French 	union {
121038c8a9a5SSteve French 		struct {
121138c8a9a5SSteve French 			atomic_t num_writes;
121238c8a9a5SSteve French 			atomic_t num_reads;
121338c8a9a5SSteve French 			atomic_t num_flushes;
121438c8a9a5SSteve French 			atomic_t num_oplock_brks;
121538c8a9a5SSteve French 			atomic_t num_opens;
121638c8a9a5SSteve French 			atomic_t num_closes;
121738c8a9a5SSteve French 			atomic_t num_deletes;
121838c8a9a5SSteve French 			atomic_t num_mkdirs;
121938c8a9a5SSteve French 			atomic_t num_posixopens;
122038c8a9a5SSteve French 			atomic_t num_posixmkdirs;
122138c8a9a5SSteve French 			atomic_t num_rmdirs;
122238c8a9a5SSteve French 			atomic_t num_renames;
122338c8a9a5SSteve French 			atomic_t num_t2renames;
122438c8a9a5SSteve French 			atomic_t num_ffirst;
122538c8a9a5SSteve French 			atomic_t num_fnext;
122638c8a9a5SSteve French 			atomic_t num_fclose;
122738c8a9a5SSteve French 			atomic_t num_hardlinks;
122838c8a9a5SSteve French 			atomic_t num_symlinks;
122938c8a9a5SSteve French 			atomic_t num_locks;
123038c8a9a5SSteve French 			atomic_t num_acl_get;
123138c8a9a5SSteve French 			atomic_t num_acl_set;
123238c8a9a5SSteve French 		} cifs_stats;
123338c8a9a5SSteve French 		struct {
123438c8a9a5SSteve French 			atomic_t smb2_com_sent[NUMBER_OF_SMB2_COMMANDS];
123538c8a9a5SSteve French 			atomic_t smb2_com_failed[NUMBER_OF_SMB2_COMMANDS];
123638c8a9a5SSteve French 		} smb2_stats;
123738c8a9a5SSteve French 	} stats;
123838c8a9a5SSteve French 	__u64    bytes_read;
123938c8a9a5SSteve French 	__u64    bytes_written;
124038c8a9a5SSteve French 	spinlock_t stat_lock;  /* protects the two fields above */
1241441786beSSteve French 	time64_t stats_from_time;
124238c8a9a5SSteve French 	FILE_SYSTEM_DEVICE_INFO fsDevInfo;
124338c8a9a5SSteve French 	FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
124438c8a9a5SSteve French 	FILE_SYSTEM_UNIX_INFO fsUnixInfo;
124538c8a9a5SSteve French 	bool ipc:1;   /* set if connection to IPC$ share (always also pipe) */
124638c8a9a5SSteve French 	bool pipe:1;  /* set if connection to pipe share */
124738c8a9a5SSteve French 	bool print:1; /* set if connection to printer share */
124838c8a9a5SSteve French 	bool retry:1;
124938c8a9a5SSteve French 	bool nocase:1;
125038c8a9a5SSteve French 	bool nohandlecache:1; /* if strange server resource prob can turn off */
125138c8a9a5SSteve French 	bool nodelete:1;
125238c8a9a5SSteve French 	bool seal:1;      /* transport encryption for this mounted share */
125338c8a9a5SSteve French 	bool unix_ext:1;  /* if false disable Linux extensions to CIFS protocol
125438c8a9a5SSteve French 				for this mount even if server would support */
125538c8a9a5SSteve French 	bool posix_extensions; /* if true SMB3.11 posix extensions enabled */
125638c8a9a5SSteve French 	bool local_lease:1; /* check leases (only) on local system not remote */
125738c8a9a5SSteve French 	bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
125838c8a9a5SSteve French 	bool broken_sparse_sup; /* if server or share does not support sparse */
125938c8a9a5SSteve French 	bool need_reconnect:1; /* connection reset, tid now invalid */
126038c8a9a5SSteve French 	bool need_reopen_files:1; /* need to reopen tcon file handles */
126138c8a9a5SSteve French 	bool use_resilient:1; /* use resilient instead of durable handles */
126238c8a9a5SSteve French 	bool use_persistent:1; /* use persistent instead of durable handles */
126338c8a9a5SSteve French 	bool no_lease:1;    /* Do not request leases on files or directories */
126438c8a9a5SSteve French 	bool use_witness:1; /* use witness protocol */
126538c8a9a5SSteve French 	__le32 capabilities;
126638c8a9a5SSteve French 	__u32 share_flags;
126738c8a9a5SSteve French 	__u32 maximal_access;
126838c8a9a5SSteve French 	__u32 vol_serial_number;
126938c8a9a5SSteve French 	__le64 vol_create_time;
127038c8a9a5SSteve French 	__u64 snapshot_time; /* for timewarp tokens - timestamp of snapshot */
127138c8a9a5SSteve French 	__u32 handle_timeout; /* persistent and durable handle timeout in ms */
127238c8a9a5SSteve French 	__u32 ss_flags;		/* sector size flags */
127338c8a9a5SSteve French 	__u32 perf_sector_size; /* best sector size for perf */
127438c8a9a5SSteve French 	__u32 max_chunks;
127538c8a9a5SSteve French 	__u32 max_bytes_chunk;
127638c8a9a5SSteve French 	__u32 max_bytes_copy;
12776a50d71dSSteve French 	__u32 max_cached_dirs;
127838c8a9a5SSteve French #ifdef CONFIG_CIFS_FSCACHE
127938c8a9a5SSteve French 	u64 resource_id;		/* server resource id */
12804a5c16d0SDavid Howells 	bool fscache_acquired;		/* T if we've tried acquiring a cookie */
128138c8a9a5SSteve French 	struct fscache_volume *fscache;	/* cookie for share */
12824a5c16d0SDavid Howells 	struct mutex fscache_lock;	/* Prevent regetting a cookie */
128338c8a9a5SSteve French #endif
128438c8a9a5SSteve French 	struct list_head pending_opens;	/* list of incomplete opens */
128538c8a9a5SSteve French 	struct cached_fids *cfids;
128638c8a9a5SSteve French 	/* BB add field for back pointer to sb struct(s)? */
128738c8a9a5SSteve French #ifdef CONFIG_CIFS_DFS_UPCALL
128838c8a9a5SSteve French 	struct delayed_work dfs_cache_work;
128938c8a9a5SSteve French #endif
129038c8a9a5SSteve French 	struct delayed_work	query_interfaces; /* query interfaces workqueue job */
12913ae872deSPaulo Alcantara 	char *origin_fullpath; /* canonical copy of smb3_fs_context::source */
129238c8a9a5SSteve French };
129338c8a9a5SSteve French 
129438c8a9a5SSteve French /*
129538c8a9a5SSteve French  * This is a refcounted and timestamped container for a tcon pointer. The
129638c8a9a5SSteve French  * container holds a tcon reference. It is considered safe to free one of
129738c8a9a5SSteve French  * these when the tl_count goes to 0. The tl_time is the time of the last
129838c8a9a5SSteve French  * "get" on the container.
129938c8a9a5SSteve French  */
130038c8a9a5SSteve French struct tcon_link {
130138c8a9a5SSteve French 	struct rb_node		tl_rbnode;
130238c8a9a5SSteve French 	kuid_t			tl_uid;
130338c8a9a5SSteve French 	unsigned long		tl_flags;
130438c8a9a5SSteve French #define TCON_LINK_MASTER	0
130538c8a9a5SSteve French #define TCON_LINK_PENDING	1
130638c8a9a5SSteve French #define TCON_LINK_IN_TREE	2
130738c8a9a5SSteve French 	unsigned long		tl_time;
130838c8a9a5SSteve French 	atomic_t		tl_count;
130938c8a9a5SSteve French 	struct cifs_tcon	*tl_tcon;
131038c8a9a5SSteve French };
131138c8a9a5SSteve French 
131238c8a9a5SSteve French extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
131338c8a9a5SSteve French extern void smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst);
131438c8a9a5SSteve French 
131538c8a9a5SSteve French static inline struct cifs_tcon *
tlink_tcon(struct tcon_link * tlink)131638c8a9a5SSteve French tlink_tcon(struct tcon_link *tlink)
131738c8a9a5SSteve French {
131838c8a9a5SSteve French 	return tlink->tl_tcon;
131938c8a9a5SSteve French }
132038c8a9a5SSteve French 
132138c8a9a5SSteve French static inline struct tcon_link *
cifs_sb_master_tlink(struct cifs_sb_info * cifs_sb)132238c8a9a5SSteve French cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
132338c8a9a5SSteve French {
132438c8a9a5SSteve French 	return cifs_sb->master_tlink;
132538c8a9a5SSteve French }
132638c8a9a5SSteve French 
132738c8a9a5SSteve French extern void cifs_put_tlink(struct tcon_link *tlink);
132838c8a9a5SSteve French 
132938c8a9a5SSteve French static inline struct tcon_link *
cifs_get_tlink(struct tcon_link * tlink)133038c8a9a5SSteve French cifs_get_tlink(struct tcon_link *tlink)
133138c8a9a5SSteve French {
133238c8a9a5SSteve French 	if (tlink && !IS_ERR(tlink))
133338c8a9a5SSteve French 		atomic_inc(&tlink->tl_count);
133438c8a9a5SSteve French 	return tlink;
133538c8a9a5SSteve French }
133638c8a9a5SSteve French 
133738c8a9a5SSteve French /* This function is always expected to succeed */
133838c8a9a5SSteve French extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
133938c8a9a5SSteve French 
134038c8a9a5SSteve French #define CIFS_OPLOCK_NO_CHANGE 0xfe
134138c8a9a5SSteve French 
134238c8a9a5SSteve French struct cifs_pending_open {
134338c8a9a5SSteve French 	struct list_head olist;
134438c8a9a5SSteve French 	struct tcon_link *tlink;
134538c8a9a5SSteve French 	__u8 lease_key[16];
134638c8a9a5SSteve French 	__u32 oplock;
134738c8a9a5SSteve French };
134838c8a9a5SSteve French 
134938c8a9a5SSteve French struct cifs_deferred_close {
135038c8a9a5SSteve French 	struct list_head dlist;
135138c8a9a5SSteve French 	struct tcon_link *tlink;
135238c8a9a5SSteve French 	__u16  netfid;
135338c8a9a5SSteve French 	__u64  persistent_fid;
135438c8a9a5SSteve French 	__u64  volatile_fid;
135538c8a9a5SSteve French };
135638c8a9a5SSteve French 
135738c8a9a5SSteve French /*
135838c8a9a5SSteve French  * This info hangs off the cifsFileInfo structure, pointed to by llist.
135938c8a9a5SSteve French  * This is used to track byte stream locks on the file
136038c8a9a5SSteve French  */
136138c8a9a5SSteve French struct cifsLockInfo {
136238c8a9a5SSteve French 	struct list_head llist;	/* pointer to next cifsLockInfo */
136338c8a9a5SSteve French 	struct list_head blist; /* pointer to locks blocked on this */
136438c8a9a5SSteve French 	wait_queue_head_t block_q;
136538c8a9a5SSteve French 	__u64 offset;
136638c8a9a5SSteve French 	__u64 length;
136738c8a9a5SSteve French 	__u32 pid;
136838c8a9a5SSteve French 	__u16 type;
136938c8a9a5SSteve French 	__u16 flags;
137038c8a9a5SSteve French };
137138c8a9a5SSteve French 
137238c8a9a5SSteve French /*
137338c8a9a5SSteve French  * One of these for each open instance of a file
137438c8a9a5SSteve French  */
137538c8a9a5SSteve French struct cifs_search_info {
137638c8a9a5SSteve French 	loff_t index_of_last_entry;
137738c8a9a5SSteve French 	__u16 entries_in_buffer;
137838c8a9a5SSteve French 	__u16 info_level;
137938c8a9a5SSteve French 	__u32 resume_key;
138038c8a9a5SSteve French 	char *ntwrk_buf_start;
138138c8a9a5SSteve French 	char *srch_entries_start;
138238c8a9a5SSteve French 	char *last_entry;
138338c8a9a5SSteve French 	const char *presume_name;
138438c8a9a5SSteve French 	unsigned int resume_name_len;
138538c8a9a5SSteve French 	bool endOfSearch:1;
138638c8a9a5SSteve French 	bool emptyDir:1;
138738c8a9a5SSteve French 	bool unicode:1;
138838c8a9a5SSteve French 	bool smallBuf:1; /* so we know which buf_release function to call */
138938c8a9a5SSteve French };
139038c8a9a5SSteve French 
139138c8a9a5SSteve French #define ACL_NO_MODE	((umode_t)(-1))
139238c8a9a5SSteve French struct cifs_open_parms {
139338c8a9a5SSteve French 	struct cifs_tcon *tcon;
139438c8a9a5SSteve French 	struct cifs_sb_info *cifs_sb;
139538c8a9a5SSteve French 	int disposition;
139638c8a9a5SSteve French 	int desired_access;
139738c8a9a5SSteve French 	int create_options;
139838c8a9a5SSteve French 	const char *path;
139938c8a9a5SSteve French 	struct cifs_fid *fid;
140038c8a9a5SSteve French 	umode_t mode;
140138c8a9a5SSteve French 	bool reconnect:1;
14021b5f2928SSteve French 	bool replay:1; /* indicates that this open is for a replay */
1403df0a8a19SPaulo Alcantara 	struct kvec *ea_cctx;
140438c8a9a5SSteve French };
140538c8a9a5SSteve French 
140638c8a9a5SSteve French struct cifs_fid {
140738c8a9a5SSteve French 	__u16 netfid;
140838c8a9a5SSteve French 	__u64 persistent_fid;	/* persist file id for smb2 */
140938c8a9a5SSteve French 	__u64 volatile_fid;	/* volatile file id for smb2 */
141038c8a9a5SSteve French 	__u8 lease_key[SMB2_LEASE_KEY_SIZE];	/* lease key for smb2 */
141138c8a9a5SSteve French 	__u8 create_guid[16];
141238c8a9a5SSteve French 	__u32 access;
141338c8a9a5SSteve French 	struct cifs_pending_open *pending_open;
141438c8a9a5SSteve French 	unsigned int epoch;
141538c8a9a5SSteve French #ifdef CONFIG_CIFS_DEBUG2
141638c8a9a5SSteve French 	__u64 mid;
141738c8a9a5SSteve French #endif /* CIFS_DEBUG2 */
141838c8a9a5SSteve French 	bool purge_cache;
141938c8a9a5SSteve French };
142038c8a9a5SSteve French 
142138c8a9a5SSteve French struct cifs_fid_locks {
142238c8a9a5SSteve French 	struct list_head llist;
142338c8a9a5SSteve French 	struct cifsFileInfo *cfile;	/* fid that owns locks */
142438c8a9a5SSteve French 	struct list_head locks;		/* locks held by fid above */
142538c8a9a5SSteve French };
142638c8a9a5SSteve French 
142738c8a9a5SSteve French struct cifsFileInfo {
142838c8a9a5SSteve French 	/* following two lists are protected by tcon->open_file_lock */
142938c8a9a5SSteve French 	struct list_head tlist;	/* pointer to next fid owned by tcon */
143038c8a9a5SSteve French 	struct list_head flist;	/* next fid (file instance) for this inode */
143138c8a9a5SSteve French 	/* lock list below protected by cifsi->lock_sem */
143238c8a9a5SSteve French 	struct cifs_fid_locks *llist;	/* brlocks held by this fid */
143338c8a9a5SSteve French 	kuid_t uid;		/* allows finding which FileInfo structure */
143438c8a9a5SSteve French 	__u32 pid;		/* process id who opened file */
143538c8a9a5SSteve French 	struct cifs_fid fid;	/* file id from remote */
143638c8a9a5SSteve French 	struct list_head rlist; /* reconnect list */
143738c8a9a5SSteve French 	/* BB add lock scope info here if needed */
143838c8a9a5SSteve French 	/* lock scope id (0 if none) */
143938c8a9a5SSteve French 	struct dentry *dentry;
144038c8a9a5SSteve French 	struct tcon_link *tlink;
144138c8a9a5SSteve French 	unsigned int f_flags;
144238c8a9a5SSteve French 	bool invalidHandle:1;	/* file closed via session abend */
144338c8a9a5SSteve French 	bool swapfile:1;
144438c8a9a5SSteve French 	bool oplock_break_cancelled:1;
1445b6e27f7fSSteve French 	bool status_file_deleted:1; /* file has been deleted */
14466f17163bSRitvik Budhiraja 	bool offload:1; /* offload final part of _put to a wq */
144738c8a9a5SSteve French 	unsigned int oplock_epoch; /* epoch from the lease break */
144838c8a9a5SSteve French 	__u32 oplock_level; /* oplock/lease level from the lease break */
144938c8a9a5SSteve French 	int count;
145038c8a9a5SSteve French 	spinlock_t file_info_lock; /* protects four flag/count fields above */
145138c8a9a5SSteve French 	struct mutex fh_mutex; /* prevents reopen race after dead ses*/
145238c8a9a5SSteve French 	struct cifs_search_info srch_inf;
145338c8a9a5SSteve French 	struct work_struct oplock_break; /* work for oplock breaks */
145438c8a9a5SSteve French 	struct work_struct put; /* work for the final part of _put */
14556f17163bSRitvik Budhiraja 	struct work_struct serverclose; /* work for serverclose */
145638c8a9a5SSteve French 	struct delayed_work deferred;
145738c8a9a5SSteve French 	bool deferred_close_scheduled; /* Flag to indicate close is scheduled */
145838c8a9a5SSteve French 	char *symlink_target;
145938c8a9a5SSteve French };
146038c8a9a5SSteve French 
146138c8a9a5SSteve French struct cifs_io_parms {
146238c8a9a5SSteve French 	__u16 netfid;
146338c8a9a5SSteve French 	__u64 persistent_fid;	/* persist file id for smb2 */
146438c8a9a5SSteve French 	__u64 volatile_fid;	/* volatile file id for smb2 */
146538c8a9a5SSteve French 	__u32 pid;
146638c8a9a5SSteve French 	__u64 offset;
146738c8a9a5SSteve French 	unsigned int length;
146838c8a9a5SSteve French 	struct cifs_tcon *tcon;
146938c8a9a5SSteve French 	struct TCP_Server_Info *server;
147038c8a9a5SSteve French };
147138c8a9a5SSteve French 
147238c8a9a5SSteve French struct cifs_aio_ctx {
147338c8a9a5SSteve French 	struct kref		refcount;
147438c8a9a5SSteve French 	struct list_head	list;
147538c8a9a5SSteve French 	struct mutex		aio_mutex;
147638c8a9a5SSteve French 	struct completion	done;
147738c8a9a5SSteve French 	struct iov_iter		iter;
147838c8a9a5SSteve French 	struct kiocb		*iocb;
147938c8a9a5SSteve French 	struct cifsFileInfo	*cfile;
148038c8a9a5SSteve French 	struct bio_vec		*bv;
148138c8a9a5SSteve French 	loff_t			pos;
148238c8a9a5SSteve French 	unsigned int		nr_pinned_pages;
148338c8a9a5SSteve French 	ssize_t			rc;
148438c8a9a5SSteve French 	unsigned int		len;
148538c8a9a5SSteve French 	unsigned int		total_len;
148638c8a9a5SSteve French 	unsigned int		bv_need_unpin;	/* If ->bv[] needs unpinning */
148738c8a9a5SSteve French 	bool			should_dirty;
148838c8a9a5SSteve French 	/*
148938c8a9a5SSteve French 	 * Indicates if this aio_ctx is for direct_io,
149038c8a9a5SSteve French 	 * If yes, iter is a copy of the user passed iov_iter
149138c8a9a5SSteve French 	 */
149238c8a9a5SSteve French 	bool			direct_io;
149338c8a9a5SSteve French };
149438c8a9a5SSteve French 
149538c8a9a5SSteve French /* asynchronous read support */
149638c8a9a5SSteve French struct cifs_readdata {
149738c8a9a5SSteve French 	struct kref			refcount;
149838c8a9a5SSteve French 	struct list_head		list;
149938c8a9a5SSteve French 	struct completion		done;
150038c8a9a5SSteve French 	struct cifsFileInfo		*cfile;
150138c8a9a5SSteve French 	struct address_space		*mapping;
150238c8a9a5SSteve French 	struct cifs_aio_ctx		*ctx;
150338c8a9a5SSteve French 	__u64				offset;
150438c8a9a5SSteve French 	ssize_t				got_bytes;
150538c8a9a5SSteve French 	unsigned int			bytes;
150638c8a9a5SSteve French 	pid_t				pid;
150738c8a9a5SSteve French 	int				result;
150838c8a9a5SSteve French 	struct work_struct		work;
150938c8a9a5SSteve French 	struct iov_iter			iter;
151038c8a9a5SSteve French 	struct kvec			iov[2];
151138c8a9a5SSteve French 	struct TCP_Server_Info		*server;
151238c8a9a5SSteve French #ifdef CONFIG_CIFS_SMB_DIRECT
151338c8a9a5SSteve French 	struct smbd_mr			*mr;
151438c8a9a5SSteve French #endif
151538c8a9a5SSteve French 	struct cifs_credits		credits;
151638c8a9a5SSteve French };
151738c8a9a5SSteve French 
151838c8a9a5SSteve French /* asynchronous write support */
151938c8a9a5SSteve French struct cifs_writedata {
152038c8a9a5SSteve French 	struct kref			refcount;
152138c8a9a5SSteve French 	struct list_head		list;
152238c8a9a5SSteve French 	struct completion		done;
152338c8a9a5SSteve French 	enum writeback_sync_modes	sync_mode;
152438c8a9a5SSteve French 	struct work_struct		work;
152538c8a9a5SSteve French 	struct cifsFileInfo		*cfile;
152638c8a9a5SSteve French 	struct cifs_aio_ctx		*ctx;
152738c8a9a5SSteve French 	struct iov_iter			iter;
152838c8a9a5SSteve French 	struct bio_vec			*bv;
152938c8a9a5SSteve French 	__u64				offset;
153038c8a9a5SSteve French 	pid_t				pid;
153138c8a9a5SSteve French 	unsigned int			bytes;
153238c8a9a5SSteve French 	int				result;
153338c8a9a5SSteve French 	struct TCP_Server_Info		*server;
153438c8a9a5SSteve French #ifdef CONFIG_CIFS_SMB_DIRECT
153538c8a9a5SSteve French 	struct smbd_mr			*mr;
153638c8a9a5SSteve French #endif
153738c8a9a5SSteve French 	struct cifs_credits		credits;
1538cdd7870aSShyam Prasad N 	bool				replay;
153938c8a9a5SSteve French };
154038c8a9a5SSteve French 
154138c8a9a5SSteve French /*
154238c8a9a5SSteve French  * Take a reference on the file private data. Must be called with
154338c8a9a5SSteve French  * cfile->file_info_lock held.
154438c8a9a5SSteve French  */
154538c8a9a5SSteve French static inline void
cifsFileInfo_get_locked(struct cifsFileInfo * cifs_file)154638c8a9a5SSteve French cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file)
154738c8a9a5SSteve French {
154838c8a9a5SSteve French 	++cifs_file->count;
154938c8a9a5SSteve French }
155038c8a9a5SSteve French 
155138c8a9a5SSteve French struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file);
155238c8a9a5SSteve French void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_hdlr,
155338c8a9a5SSteve French 		       bool offload);
155438c8a9a5SSteve French void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
155538c8a9a5SSteve French 
155638c8a9a5SSteve French #define CIFS_CACHE_READ_FLG	1
155738c8a9a5SSteve French #define CIFS_CACHE_HANDLE_FLG	2
155838c8a9a5SSteve French #define CIFS_CACHE_RH_FLG	(CIFS_CACHE_READ_FLG | CIFS_CACHE_HANDLE_FLG)
155938c8a9a5SSteve French #define CIFS_CACHE_WRITE_FLG	4
156038c8a9a5SSteve French #define CIFS_CACHE_RW_FLG	(CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG)
156138c8a9a5SSteve French #define CIFS_CACHE_RHW_FLG	(CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG)
156238c8a9a5SSteve French 
156338c8a9a5SSteve French #define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE))
156438c8a9a5SSteve French #define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG)
156538c8a9a5SSteve French #define CIFS_CACHE_WRITE(cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE))
156638c8a9a5SSteve French 
156738c8a9a5SSteve French /*
156838c8a9a5SSteve French  * One of these for each file inode
156938c8a9a5SSteve French  */
157038c8a9a5SSteve French 
157138c8a9a5SSteve French struct cifsInodeInfo {
157238c8a9a5SSteve French 	struct netfs_inode netfs; /* Netfslib context and vfs inode */
157338c8a9a5SSteve French 	bool can_cache_brlcks;
157438c8a9a5SSteve French 	struct list_head llist;	/* locks helb by this inode */
157538c8a9a5SSteve French 	/*
157638c8a9a5SSteve French 	 * NOTE: Some code paths call down_read(lock_sem) twice, so
157738c8a9a5SSteve French 	 * we must always use cifs_down_write() instead of down_write()
157838c8a9a5SSteve French 	 * for this semaphore to avoid deadlocks.
157938c8a9a5SSteve French 	 */
158038c8a9a5SSteve French 	struct rw_semaphore lock_sem;	/* protect the fields above */
158138c8a9a5SSteve French 	/* BB add in lists for dirty pages i.e. write caching info for oplock */
158238c8a9a5SSteve French 	struct list_head openFileList;
158338c8a9a5SSteve French 	spinlock_t	open_file_lock;	/* protects openFileList */
158438c8a9a5SSteve French 	__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
158538c8a9a5SSteve French 	unsigned int oplock;		/* oplock/lease level we have */
158638c8a9a5SSteve French 	unsigned int epoch;		/* used to track lease state changes */
158738c8a9a5SSteve French #define CIFS_INODE_PENDING_OPLOCK_BREAK   (0) /* oplock break in progress */
158838c8a9a5SSteve French #define CIFS_INODE_PENDING_WRITERS	  (1) /* Writes in progress */
158938c8a9a5SSteve French #define CIFS_INODE_FLAG_UNUSED		  (2) /* Unused flag */
159038c8a9a5SSteve French #define CIFS_INO_DELETE_PENDING		  (3) /* delete pending on server */
159138c8a9a5SSteve French #define CIFS_INO_INVALID_MAPPING	  (4) /* pagecache is invalid */
159238c8a9a5SSteve French #define CIFS_INO_LOCK			  (5) /* lock bit for synchronization */
159338c8a9a5SSteve French #define CIFS_INO_MODIFIED_ATTR            (6) /* Indicate change in mtime/ctime */
159438c8a9a5SSteve French #define CIFS_INO_CLOSE_ON_LOCK            (7) /* Not to defer the close when lock is set */
159538c8a9a5SSteve French 	unsigned long flags;
159638c8a9a5SSteve French 	spinlock_t writers_lock;
159738c8a9a5SSteve French 	unsigned int writers;		/* Number of writers on this inode */
159838c8a9a5SSteve French 	unsigned long time;		/* jiffies of last update of inode */
159938c8a9a5SSteve French 	u64  server_eof;		/* current file size on server -- protected by i_lock */
160038c8a9a5SSteve French 	u64  uniqueid;			/* server inode number */
160138c8a9a5SSteve French 	u64  createtime;		/* creation time on server */
160238c8a9a5SSteve French 	__u8 lease_key[SMB2_LEASE_KEY_SIZE];	/* lease key for this inode */
160338c8a9a5SSteve French 	struct list_head deferred_closes; /* list of deferred closes */
160438c8a9a5SSteve French 	spinlock_t deferred_lock; /* protection on deferred list */
160538c8a9a5SSteve French 	bool lease_granted; /* Flag to indicate whether lease or oplock is granted. */
160638c8a9a5SSteve French 	char *symlink_target;
1607b9e741acSPaulo Alcantara 	__u32 reparse_tag;
160838c8a9a5SSteve French };
160938c8a9a5SSteve French 
161038c8a9a5SSteve French static inline struct cifsInodeInfo *
CIFS_I(struct inode * inode)161138c8a9a5SSteve French CIFS_I(struct inode *inode)
161238c8a9a5SSteve French {
161338c8a9a5SSteve French 	return container_of(inode, struct cifsInodeInfo, netfs.inode);
161438c8a9a5SSteve French }
161538c8a9a5SSteve French 
161638c8a9a5SSteve French static inline struct cifs_sb_info *
CIFS_SB(struct super_block * sb)161738c8a9a5SSteve French CIFS_SB(struct super_block *sb)
161838c8a9a5SSteve French {
161938c8a9a5SSteve French 	return sb->s_fs_info;
162038c8a9a5SSteve French }
162138c8a9a5SSteve French 
162238c8a9a5SSteve French static inline struct cifs_sb_info *
CIFS_FILE_SB(struct file * file)162338c8a9a5SSteve French CIFS_FILE_SB(struct file *file)
162438c8a9a5SSteve French {
162538c8a9a5SSteve French 	return CIFS_SB(file_inode(file)->i_sb);
162638c8a9a5SSteve French }
162738c8a9a5SSteve French 
CIFS_DIR_SEP(const struct cifs_sb_info * cifs_sb)162838c8a9a5SSteve French static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
162938c8a9a5SSteve French {
163038c8a9a5SSteve French 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
163138c8a9a5SSteve French 		return '/';
163238c8a9a5SSteve French 	else
163338c8a9a5SSteve French 		return '\\';
163438c8a9a5SSteve French }
163538c8a9a5SSteve French 
163638c8a9a5SSteve French static inline void
convert_delimiter(char * path,char delim)163738c8a9a5SSteve French convert_delimiter(char *path, char delim)
163838c8a9a5SSteve French {
163938c8a9a5SSteve French 	char old_delim, *pos;
164038c8a9a5SSteve French 
164138c8a9a5SSteve French 	if (delim == '/')
164238c8a9a5SSteve French 		old_delim = '\\';
164338c8a9a5SSteve French 	else
164438c8a9a5SSteve French 		old_delim = '/';
164538c8a9a5SSteve French 
164638c8a9a5SSteve French 	pos = path;
164738c8a9a5SSteve French 	while ((pos = strchr(pos, old_delim)))
164838c8a9a5SSteve French 		*pos = delim;
164938c8a9a5SSteve French }
165038c8a9a5SSteve French 
165138c8a9a5SSteve French #define cifs_stats_inc atomic_inc
165238c8a9a5SSteve French 
cifs_stats_bytes_written(struct cifs_tcon * tcon,unsigned int bytes)165338c8a9a5SSteve French static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon,
165438c8a9a5SSteve French 					    unsigned int bytes)
165538c8a9a5SSteve French {
165638c8a9a5SSteve French 	if (bytes) {
165738c8a9a5SSteve French 		spin_lock(&tcon->stat_lock);
165838c8a9a5SSteve French 		tcon->bytes_written += bytes;
165938c8a9a5SSteve French 		spin_unlock(&tcon->stat_lock);
166038c8a9a5SSteve French 	}
166138c8a9a5SSteve French }
166238c8a9a5SSteve French 
cifs_stats_bytes_read(struct cifs_tcon * tcon,unsigned int bytes)166338c8a9a5SSteve French static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
166438c8a9a5SSteve French 					 unsigned int bytes)
166538c8a9a5SSteve French {
166638c8a9a5SSteve French 	spin_lock(&tcon->stat_lock);
166738c8a9a5SSteve French 	tcon->bytes_read += bytes;
166838c8a9a5SSteve French 	spin_unlock(&tcon->stat_lock);
166938c8a9a5SSteve French }
167038c8a9a5SSteve French 
167138c8a9a5SSteve French 
167238c8a9a5SSteve French /*
167338c8a9a5SSteve French  * This is the prototype for the mid receive function. This function is for
167438c8a9a5SSteve French  * receiving the rest of the SMB frame, starting with the WordCount (which is
167538c8a9a5SSteve French  * just after the MID in struct smb_hdr). Note:
167638c8a9a5SSteve French  *
167738c8a9a5SSteve French  * - This will be called by cifsd, with no locks held.
167838c8a9a5SSteve French  * - The mid will still be on the pending_mid_q.
167938c8a9a5SSteve French  * - mid->resp_buf will point to the current buffer.
168038c8a9a5SSteve French  *
168138c8a9a5SSteve French  * Returns zero on a successful receive, or an error. The receive state in
168238c8a9a5SSteve French  * the TCP_Server_Info will also be updated.
168338c8a9a5SSteve French  */
168438c8a9a5SSteve French typedef int (mid_receive_t)(struct TCP_Server_Info *server,
168538c8a9a5SSteve French 			    struct mid_q_entry *mid);
168638c8a9a5SSteve French 
168738c8a9a5SSteve French /*
168838c8a9a5SSteve French  * This is the prototype for the mid callback function. This is called once the
168938c8a9a5SSteve French  * mid has been received off of the socket. When creating one, take special
169038c8a9a5SSteve French  * care to avoid deadlocks. Things to bear in mind:
169138c8a9a5SSteve French  *
169238c8a9a5SSteve French  * - it will be called by cifsd, with no locks held
169338c8a9a5SSteve French  * - the mid will be removed from any lists
169438c8a9a5SSteve French  */
169538c8a9a5SSteve French typedef void (mid_callback_t)(struct mid_q_entry *mid);
169638c8a9a5SSteve French 
169738c8a9a5SSteve French /*
169838c8a9a5SSteve French  * This is the protopyte for mid handle function. This is called once the mid
169938c8a9a5SSteve French  * has been recognized after decryption of the message.
170038c8a9a5SSteve French  */
170138c8a9a5SSteve French typedef int (mid_handle_t)(struct TCP_Server_Info *server,
170238c8a9a5SSteve French 			    struct mid_q_entry *mid);
170338c8a9a5SSteve French 
170438c8a9a5SSteve French /* one of these for every pending CIFS request to the server */
170538c8a9a5SSteve French struct mid_q_entry {
170638c8a9a5SSteve French 	struct list_head qhead;	/* mids waiting on reply from this server */
170738c8a9a5SSteve French 	struct kref refcount;
170838c8a9a5SSteve French 	struct TCP_Server_Info *server;	/* server corresponding to this mid */
170938c8a9a5SSteve French 	__u64 mid;		/* multiplex id */
171038c8a9a5SSteve French 	__u16 credits;		/* number of credits consumed by this mid */
171138c8a9a5SSteve French 	__u16 credits_received;	/* number of credits from the response */
171238c8a9a5SSteve French 	__u32 pid;		/* process id */
171338c8a9a5SSteve French 	__u32 sequence_number;  /* for CIFS signing */
171438c8a9a5SSteve French 	unsigned long when_alloc;  /* when mid was created */
171538c8a9a5SSteve French #ifdef CONFIG_CIFS_STATS2
171638c8a9a5SSteve French 	unsigned long when_sent; /* time when smb send finished */
171738c8a9a5SSteve French 	unsigned long when_received; /* when demux complete (taken off wire) */
171838c8a9a5SSteve French #endif
171938c8a9a5SSteve French 	mid_receive_t *receive; /* call receive callback */
172038c8a9a5SSteve French 	mid_callback_t *callback; /* call completion callback */
172138c8a9a5SSteve French 	mid_handle_t *handle; /* call handle mid callback */
172238c8a9a5SSteve French 	void *callback_data;	  /* general purpose pointer for callback */
172338c8a9a5SSteve French 	struct task_struct *creator;
172438c8a9a5SSteve French 	void *resp_buf;		/* pointer to received SMB header */
172538c8a9a5SSteve French 	unsigned int resp_buf_size;
172638c8a9a5SSteve French 	int mid_state;	/* wish this were enum but can not pass to wait_event */
172738c8a9a5SSteve French 	unsigned int mid_flags;
172838c8a9a5SSteve French 	__le16 command;		/* smb command code */
172938c8a9a5SSteve French 	unsigned int optype;	/* operation type */
173038c8a9a5SSteve French 	bool large_buf:1;	/* if valid response, is pointer to large buf */
173138c8a9a5SSteve French 	bool multiRsp:1;	/* multiple trans2 responses for one request  */
173238c8a9a5SSteve French 	bool multiEnd:1;	/* both received */
173338c8a9a5SSteve French 	bool decrypted:1;	/* decrypted entry */
173438c8a9a5SSteve French };
173538c8a9a5SSteve French 
173638c8a9a5SSteve French struct close_cancelled_open {
173738c8a9a5SSteve French 	struct cifs_fid         fid;
173838c8a9a5SSteve French 	struct cifs_tcon        *tcon;
173938c8a9a5SSteve French 	struct work_struct      work;
174038c8a9a5SSteve French 	__u64 mid;
174138c8a9a5SSteve French 	__u16 cmd;
174238c8a9a5SSteve French };
174338c8a9a5SSteve French 
174438c8a9a5SSteve French /*	Make code in transport.c a little cleaner by moving
174538c8a9a5SSteve French 	update of optional stats into function below */
cifs_in_send_inc(struct TCP_Server_Info * server)174638c8a9a5SSteve French static inline void cifs_in_send_inc(struct TCP_Server_Info *server)
174738c8a9a5SSteve French {
174838c8a9a5SSteve French 	atomic_inc(&server->in_send);
174938c8a9a5SSteve French }
175038c8a9a5SSteve French 
cifs_in_send_dec(struct TCP_Server_Info * server)175138c8a9a5SSteve French static inline void cifs_in_send_dec(struct TCP_Server_Info *server)
175238c8a9a5SSteve French {
175338c8a9a5SSteve French 	atomic_dec(&server->in_send);
175438c8a9a5SSteve French }
175538c8a9a5SSteve French 
cifs_num_waiters_inc(struct TCP_Server_Info * server)175638c8a9a5SSteve French static inline void cifs_num_waiters_inc(struct TCP_Server_Info *server)
175738c8a9a5SSteve French {
175838c8a9a5SSteve French 	atomic_inc(&server->num_waiters);
175938c8a9a5SSteve French }
176038c8a9a5SSteve French 
cifs_num_waiters_dec(struct TCP_Server_Info * server)176138c8a9a5SSteve French static inline void cifs_num_waiters_dec(struct TCP_Server_Info *server)
176238c8a9a5SSteve French {
176338c8a9a5SSteve French 	atomic_dec(&server->num_waiters);
176438c8a9a5SSteve French }
176538c8a9a5SSteve French 
176638c8a9a5SSteve French #ifdef CONFIG_CIFS_STATS2
cifs_save_when_sent(struct mid_q_entry * mid)176738c8a9a5SSteve French static inline void cifs_save_when_sent(struct mid_q_entry *mid)
176838c8a9a5SSteve French {
176938c8a9a5SSteve French 	mid->when_sent = jiffies;
177038c8a9a5SSteve French }
177138c8a9a5SSteve French #else
cifs_save_when_sent(struct mid_q_entry * mid)177238c8a9a5SSteve French static inline void cifs_save_when_sent(struct mid_q_entry *mid)
177338c8a9a5SSteve French {
177438c8a9a5SSteve French }
177538c8a9a5SSteve French #endif
177638c8a9a5SSteve French 
177738c8a9a5SSteve French /* for pending dnotify requests */
177838c8a9a5SSteve French struct dir_notify_req {
177938c8a9a5SSteve French 	struct list_head lhead;
178038c8a9a5SSteve French 	__le16 Pid;
178138c8a9a5SSteve French 	__le16 PidHigh;
178238c8a9a5SSteve French 	__u16 Mid;
178338c8a9a5SSteve French 	__u16 Tid;
178438c8a9a5SSteve French 	__u16 Uid;
178538c8a9a5SSteve French 	__u16 netfid;
178638c8a9a5SSteve French 	__u32 filter; /* CompletionFilter (for multishot) */
178738c8a9a5SSteve French 	int multishot;
178838c8a9a5SSteve French 	struct file *pfile;
178938c8a9a5SSteve French };
179038c8a9a5SSteve French 
179138c8a9a5SSteve French struct dfs_info3_param {
179238c8a9a5SSteve French 	int flags; /* DFSREF_REFERRAL_SERVER, DFSREF_STORAGE_SERVER*/
179338c8a9a5SSteve French 	int path_consumed;
179438c8a9a5SSteve French 	int server_type;
179538c8a9a5SSteve French 	int ref_flag;
179638c8a9a5SSteve French 	char *path_name;
179738c8a9a5SSteve French 	char *node_name;
179838c8a9a5SSteve French 	int ttl;
179938c8a9a5SSteve French };
180038c8a9a5SSteve French 
180138c8a9a5SSteve French struct file_list {
180238c8a9a5SSteve French 	struct list_head list;
180338c8a9a5SSteve French 	struct cifsFileInfo *cfile;
180438c8a9a5SSteve French };
180538c8a9a5SSteve French 
180638c8a9a5SSteve French struct cifs_mount_ctx {
180738c8a9a5SSteve French 	struct cifs_sb_info *cifs_sb;
180838c8a9a5SSteve French 	struct smb3_fs_context *fs_ctx;
180938c8a9a5SSteve French 	unsigned int xid;
181038c8a9a5SSteve French 	struct TCP_Server_Info *server;
181138c8a9a5SSteve French 	struct cifs_ses *ses;
181238c8a9a5SSteve French 	struct cifs_tcon *tcon;
181338c8a9a5SSteve French };
181438c8a9a5SSteve French 
__free_dfs_info_param(struct dfs_info3_param * param)1815ce04127cSPaulo Alcantara static inline void __free_dfs_info_param(struct dfs_info3_param *param)
181638c8a9a5SSteve French {
181738c8a9a5SSteve French 	kfree(param->path_name);
181838c8a9a5SSteve French 	kfree(param->node_name);
181938c8a9a5SSteve French }
1820ce04127cSPaulo Alcantara 
free_dfs_info_param(struct dfs_info3_param * param)1821ce04127cSPaulo Alcantara static inline void free_dfs_info_param(struct dfs_info3_param *param)
1822ce04127cSPaulo Alcantara {
1823ce04127cSPaulo Alcantara 	if (param)
1824ce04127cSPaulo Alcantara 		__free_dfs_info_param(param);
1825ce04127cSPaulo Alcantara }
1826ce04127cSPaulo Alcantara 
zfree_dfs_info_param(struct dfs_info3_param * param)1827ce04127cSPaulo Alcantara static inline void zfree_dfs_info_param(struct dfs_info3_param *param)
1828ce04127cSPaulo Alcantara {
1829ce04127cSPaulo Alcantara 	if (param) {
1830ce04127cSPaulo Alcantara 		__free_dfs_info_param(param);
1831ce04127cSPaulo Alcantara 		memset(param, 0, sizeof(*param));
1832ce04127cSPaulo Alcantara 	}
183338c8a9a5SSteve French }
183438c8a9a5SSteve French 
free_dfs_info_array(struct dfs_info3_param * param,int number_of_items)183538c8a9a5SSteve French static inline void free_dfs_info_array(struct dfs_info3_param *param,
183638c8a9a5SSteve French 				       int number_of_items)
183738c8a9a5SSteve French {
183838c8a9a5SSteve French 	int i;
183938c8a9a5SSteve French 
184038c8a9a5SSteve French 	if ((number_of_items == 0) || (param == NULL))
184138c8a9a5SSteve French 		return;
184238c8a9a5SSteve French 	for (i = 0; i < number_of_items; i++) {
184338c8a9a5SSteve French 		kfree(param[i].path_name);
184438c8a9a5SSteve French 		kfree(param[i].node_name);
184538c8a9a5SSteve French 	}
184638c8a9a5SSteve French 	kfree(param);
184738c8a9a5SSteve French }
184838c8a9a5SSteve French 
is_interrupt_error(int error)184938c8a9a5SSteve French static inline bool is_interrupt_error(int error)
185038c8a9a5SSteve French {
185138c8a9a5SSteve French 	switch (error) {
185238c8a9a5SSteve French 	case -EINTR:
185338c8a9a5SSteve French 	case -ERESTARTSYS:
185438c8a9a5SSteve French 	case -ERESTARTNOHAND:
185538c8a9a5SSteve French 	case -ERESTARTNOINTR:
185638c8a9a5SSteve French 		return true;
185738c8a9a5SSteve French 	}
185838c8a9a5SSteve French 	return false;
185938c8a9a5SSteve French }
186038c8a9a5SSteve French 
is_retryable_error(int error)186138c8a9a5SSteve French static inline bool is_retryable_error(int error)
186238c8a9a5SSteve French {
186338c8a9a5SSteve French 	if (is_interrupt_error(error) || error == -EAGAIN)
186438c8a9a5SSteve French 		return true;
186538c8a9a5SSteve French 	return false;
186638c8a9a5SSteve French }
186738c8a9a5SSteve French 
is_replayable_error(int error)1868f642fcf3SShyam Prasad N static inline bool is_replayable_error(int error)
1869f642fcf3SShyam Prasad N {
1870f642fcf3SShyam Prasad N 	if (error == -EAGAIN || error == -ECONNABORTED)
1871f642fcf3SShyam Prasad N 		return true;
1872f642fcf3SShyam Prasad N 	return false;
1873f642fcf3SShyam Prasad N }
1874f642fcf3SShyam Prasad N 
187538c8a9a5SSteve French 
187638c8a9a5SSteve French /* cifs_get_writable_file() flags */
187738c8a9a5SSteve French #define FIND_WR_ANY         0
187838c8a9a5SSteve French #define FIND_WR_FSUID_ONLY  1
187938c8a9a5SSteve French #define FIND_WR_WITH_DELETE 2
188038c8a9a5SSteve French 
188138c8a9a5SSteve French #define   MID_FREE 0
188238c8a9a5SSteve French #define   MID_REQUEST_ALLOCATED 1
188338c8a9a5SSteve French #define   MID_REQUEST_SUBMITTED 2
188438c8a9a5SSteve French #define   MID_RESPONSE_RECEIVED 4
188538c8a9a5SSteve French #define   MID_RETRY_NEEDED      8 /* session closed while this request out */
188638c8a9a5SSteve French #define   MID_RESPONSE_MALFORMED 0x10
188738c8a9a5SSteve French #define   MID_SHUTDOWN		 0x20
1888d527f513SZhang Xiaoxu #define   MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */
188938c8a9a5SSteve French 
189038c8a9a5SSteve French /* Flags */
189138c8a9a5SSteve French #define   MID_WAIT_CANCELLED	 1 /* Cancelled while waiting for response */
189238c8a9a5SSteve French #define   MID_DELETED            2 /* Mid has been dequeued/deleted */
189338c8a9a5SSteve French 
189438c8a9a5SSteve French /* Types of response buffer returned from SendReceive2 */
189538c8a9a5SSteve French #define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
189638c8a9a5SSteve French #define   CIFS_SMALL_BUFFER     1
189738c8a9a5SSteve French #define   CIFS_LARGE_BUFFER     2
189838c8a9a5SSteve French #define   CIFS_IOVEC            4    /* array of response buffers */
189938c8a9a5SSteve French 
190038c8a9a5SSteve French /* Type of Request to SendReceive2 */
190138c8a9a5SSteve French #define   CIFS_BLOCKING_OP      1    /* operation can block */
190238c8a9a5SSteve French #define   CIFS_NON_BLOCKING     2    /* do not block waiting for credits */
190338c8a9a5SSteve French #define   CIFS_TIMEOUT_MASK 0x003    /* only one of above set in req */
190438c8a9a5SSteve French #define   CIFS_LOG_ERROR    0x010    /* log NT STATUS if non-zero */
190538c8a9a5SSteve French #define   CIFS_LARGE_BUF_OP 0x020    /* large request buffer */
190638c8a9a5SSteve French #define   CIFS_NO_RSP_BUF   0x040    /* no response buffer required */
190738c8a9a5SSteve French 
190838c8a9a5SSteve French /* Type of request operation */
190938c8a9a5SSteve French #define   CIFS_ECHO_OP            0x080  /* echo request */
191038c8a9a5SSteve French #define   CIFS_OBREAK_OP          0x0100 /* oplock break request */
191138c8a9a5SSteve French #define   CIFS_NEG_OP             0x0200 /* negotiate request */
191238c8a9a5SSteve French #define   CIFS_CP_CREATE_CLOSE_OP 0x0400 /* compound create+close request */
191338c8a9a5SSteve French /* Lower bitmask values are reserved by others below. */
191438c8a9a5SSteve French #define   CIFS_SESS_OP            0x2000 /* session setup request */
191538c8a9a5SSteve French #define   CIFS_OP_MASK            0x2780 /* mask request type */
191638c8a9a5SSteve French 
191738c8a9a5SSteve French #define   CIFS_HAS_CREDITS        0x0400 /* already has credits */
191838c8a9a5SSteve French #define   CIFS_TRANSFORM_REQ      0x0800 /* transform request before sending */
191938c8a9a5SSteve French #define   CIFS_NO_SRV_RSP         0x1000 /* there is no server response */
192038c8a9a5SSteve French 
192138c8a9a5SSteve French /* Security Flags: indicate type of session setup needed */
192238c8a9a5SSteve French #define   CIFSSEC_MAY_SIGN	0x00001
192338c8a9a5SSteve French #define   CIFSSEC_MAY_NTLMV2	0x00004
192438c8a9a5SSteve French #define   CIFSSEC_MAY_KRB5	0x00008
192538c8a9a5SSteve French #define   CIFSSEC_MAY_SEAL	0x00040 /* not supported yet */
192638c8a9a5SSteve French #define   CIFSSEC_MAY_NTLMSSP	0x00080 /* raw ntlmssp with ntlmv2 */
192738c8a9a5SSteve French 
192838c8a9a5SSteve French #define   CIFSSEC_MUST_SIGN	0x01001
192938c8a9a5SSteve French /* note that only one of the following can be set so the
193038c8a9a5SSteve French result of setting MUST flags more than once will be to
193138c8a9a5SSteve French require use of the stronger protocol */
193238c8a9a5SSteve French #define   CIFSSEC_MUST_NTLMV2	0x04004
193338c8a9a5SSteve French #define   CIFSSEC_MUST_KRB5	0x08008
193438c8a9a5SSteve French #ifdef CONFIG_CIFS_UPCALL
193538c8a9a5SSteve French #define   CIFSSEC_MASK          0x8F08F /* flags supported if no weak allowed */
193638c8a9a5SSteve French #else
193738c8a9a5SSteve French #define	  CIFSSEC_MASK          0x87087 /* flags supported if no weak allowed */
193838c8a9a5SSteve French #endif /* UPCALL */
193938c8a9a5SSteve French #define   CIFSSEC_MUST_SEAL	0x40040 /* not supported yet */
194038c8a9a5SSteve French #define   CIFSSEC_MUST_NTLMSSP	0x80080 /* raw ntlmssp with ntlmv2 */
194138c8a9a5SSteve French 
194238c8a9a5SSteve French #define   CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP)
194338c8a9a5SSteve French #define   CIFSSEC_MAX (CIFSSEC_MUST_NTLMV2)
194438c8a9a5SSteve French #define   CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
194538c8a9a5SSteve French /*
194638c8a9a5SSteve French  *****************************************************************
194738c8a9a5SSteve French  * All constants go here
194838c8a9a5SSteve French  *****************************************************************
194938c8a9a5SSteve French  */
195038c8a9a5SSteve French 
195138c8a9a5SSteve French #define UID_HASH (16)
195238c8a9a5SSteve French 
195338c8a9a5SSteve French /*
195438c8a9a5SSteve French  * Note that ONE module should define _DECLARE_GLOBALS_HERE to cause the
195538c8a9a5SSteve French  * following to be declared.
195638c8a9a5SSteve French  */
195738c8a9a5SSteve French 
195838c8a9a5SSteve French /****************************************************************************
195938c8a9a5SSteve French  * Here are all the locks (spinlock, mutex, semaphore) in cifs.ko, arranged according
196038c8a9a5SSteve French  * to the locking order. i.e. if two locks are to be held together, the lock that
196138c8a9a5SSteve French  * appears higher in this list needs to be taken before the other.
196238c8a9a5SSteve French  *
196338c8a9a5SSteve French  * If you hold a lock that is lower in this list, and you need to take a higher lock
196438c8a9a5SSteve French  * (or if you think that one of the functions that you're calling may need to), first
196538c8a9a5SSteve French  * drop the lock you hold, pick up the higher lock, then the lower one. This will
196638c8a9a5SSteve French  * ensure that locks are picked up only in one direction in the below table
196738c8a9a5SSteve French  * (top to bottom).
196838c8a9a5SSteve French  *
196938c8a9a5SSteve French  * Also, if you expect a function to be called with a lock held, explicitly document
197038c8a9a5SSteve French  * this in the comments on top of your function definition.
197138c8a9a5SSteve French  *
197238c8a9a5SSteve French  * And also, try to keep the critical sections (lock hold time) to be as minimal as
197338c8a9a5SSteve French  * possible. Blocking / calling other functions with a lock held always increase
197438c8a9a5SSteve French  * the risk of a possible deadlock.
197538c8a9a5SSteve French  *
197638c8a9a5SSteve French  * Following this rule will avoid unnecessary deadlocks, which can get really hard to
197738c8a9a5SSteve French  * debug. Also, any new lock that you introduce, please add to this list in the correct
197838c8a9a5SSteve French  * order.
197938c8a9a5SSteve French  *
198038c8a9a5SSteve French  * Please populate this list whenever you introduce new locks in your changes. Or in
198138c8a9a5SSteve French  * case I've missed some existing locks. Please ensure that it's added in the list
198238c8a9a5SSteve French  * based on the locking order expected.
198338c8a9a5SSteve French  *
198438c8a9a5SSteve French  * =====================================================================================
198538c8a9a5SSteve French  * Lock				Protects			Initialization fn
198638c8a9a5SSteve French  * =====================================================================================
198738c8a9a5SSteve French  * vol_list_lock
198838c8a9a5SSteve French  * vol_info->ctx_lock		vol_info->ctx
198938c8a9a5SSteve French  * cifs_sb_info->tlink_tree_lock	cifs_sb_info->tlink_tree	cifs_setup_cifs_sb
199038c8a9a5SSteve French  * TCP_Server_Info->		TCP_Server_Info			cifs_get_tcp_session
199138c8a9a5SSteve French  * reconnect_mutex
199238c8a9a5SSteve French  * TCP_Server_Info->srv_mutex	TCP_Server_Info			cifs_get_tcp_session
199338c8a9a5SSteve French  * cifs_ses->session_mutex		cifs_ses		sesInfoAlloc
199438c8a9a5SSteve French  *				cifs_tcon
199538c8a9a5SSteve French  * cifs_tcon->open_file_lock	cifs_tcon->openFileList		tconInfoAlloc
199638c8a9a5SSteve French  *				cifs_tcon->pending_opens
199738c8a9a5SSteve French  * cifs_tcon->stat_lock		cifs_tcon->bytes_read		tconInfoAlloc
199838c8a9a5SSteve French  *				cifs_tcon->bytes_written
199938c8a9a5SSteve French  * cifs_tcp_ses_lock		cifs_tcp_ses_list		sesInfoAlloc
200038c8a9a5SSteve French  * GlobalMid_Lock		GlobalMaxActiveXid		init_cifs
200138c8a9a5SSteve French  *				GlobalCurrentXid
200238c8a9a5SSteve French  *				GlobalTotalActiveXid
200338c8a9a5SSteve French  * TCP_Server_Info->srv_lock	(anything in struct not protected by another lock and can change)
200438c8a9a5SSteve French  * TCP_Server_Info->mid_lock	TCP_Server_Info->pending_mid_q	cifs_get_tcp_session
200538c8a9a5SSteve French  *				->CurrentMid
200638c8a9a5SSteve French  *				(any changes in mid_q_entry fields)
200738c8a9a5SSteve French  * TCP_Server_Info->req_lock	TCP_Server_Info->in_flight	cifs_get_tcp_session
200838c8a9a5SSteve French  *				->credits
200938c8a9a5SSteve French  *				->echo_credits
201038c8a9a5SSteve French  *				->oplock_credits
201138c8a9a5SSteve French  *				->reconnect_instance
201238c8a9a5SSteve French  * cifs_ses->ses_lock		(anything that is not protected by another lock and can change)
201338c8a9a5SSteve French  * cifs_ses->iface_lock		cifs_ses->iface_list		sesInfoAlloc
201438c8a9a5SSteve French  *				->iface_count
201538c8a9a5SSteve French  *				->iface_last_update
201638c8a9a5SSteve French  * cifs_ses->chan_lock		cifs_ses->chans
201738c8a9a5SSteve French  *				->chans_need_reconnect
201838c8a9a5SSteve French  *				->chans_in_reconnect
201938c8a9a5SSteve French  * cifs_tcon->tc_lock		(anything that is not protected by another lock and can change)
202038c8a9a5SSteve French  * cifsInodeInfo->open_file_lock	cifsInodeInfo->openFileList	cifs_alloc_inode
202138c8a9a5SSteve French  * cifsInodeInfo->writers_lock	cifsInodeInfo->writers		cifsInodeInfo_alloc
202238c8a9a5SSteve French  * cifsInodeInfo->lock_sem	cifsInodeInfo->llist		cifs_init_once
202338c8a9a5SSteve French  *				->can_cache_brlcks
202438c8a9a5SSteve French  * cifsInodeInfo->deferred_lock	cifsInodeInfo->deferred_closes	cifsInodeInfo_alloc
20252da338ffSSteve French  * cached_fid->fid_mutex		cifs_tcon->crfid		tcon_info_alloc
202638c8a9a5SSteve French  * cifsFileInfo->fh_mutex		cifsFileInfo			cifs_new_fileinfo
202738c8a9a5SSteve French  * cifsFileInfo->file_info_lock	cifsFileInfo->count		cifs_new_fileinfo
202838c8a9a5SSteve French  *				->invalidHandle			initiate_cifs_search
202938c8a9a5SSteve French  *				->oplock_break_cancelled
203038c8a9a5SSteve French  * cifs_aio_ctx->aio_mutex		cifs_aio_ctx			cifs_aio_ctx_alloc
203138c8a9a5SSteve French  ****************************************************************************/
203238c8a9a5SSteve French 
203338c8a9a5SSteve French #ifdef DECLARE_GLOBALS_HERE
203438c8a9a5SSteve French #define GLOBAL_EXTERN
203538c8a9a5SSteve French #else
203638c8a9a5SSteve French #define GLOBAL_EXTERN extern
203738c8a9a5SSteve French #endif
203838c8a9a5SSteve French 
203938c8a9a5SSteve French /*
204038c8a9a5SSteve French  * the list of TCP_Server_Info structures, ie each of the sockets
204138c8a9a5SSteve French  * connecting our client to a distinct server (ip address), is
204238c8a9a5SSteve French  * chained together by cifs_tcp_ses_list. The list of all our SMB
204338c8a9a5SSteve French  * sessions (and from that the tree connections) can be found
204438c8a9a5SSteve French  * by iterating over cifs_tcp_ses_list
204538c8a9a5SSteve French  */
204638c8a9a5SSteve French extern struct list_head		cifs_tcp_ses_list;
204738c8a9a5SSteve French 
204838c8a9a5SSteve French /*
204938c8a9a5SSteve French  * This lock protects the cifs_tcp_ses_list, the list of smb sessions per
205038c8a9a5SSteve French  * tcp session, and the list of tcon's per smb session. It also protects
205138c8a9a5SSteve French  * the reference counters for the server, smb session, and tcon.
205238c8a9a5SSteve French  * generally the locks should be taken in order tcp_ses_lock before
205338c8a9a5SSteve French  * tcon->open_file_lock and that before file->file_info_lock since the
205438c8a9a5SSteve French  * structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file
205538c8a9a5SSteve French  */
205638c8a9a5SSteve French extern spinlock_t		cifs_tcp_ses_lock;
205738c8a9a5SSteve French 
205838c8a9a5SSteve French /*
205938c8a9a5SSteve French  * Global transaction id (XID) information
206038c8a9a5SSteve French  */
206138c8a9a5SSteve French extern unsigned int GlobalCurrentXid;	/* protected by GlobalMid_Sem */
206238c8a9a5SSteve French extern unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
206338c8a9a5SSteve French extern unsigned int GlobalMaxActiveXid;	/* prot by GlobalMid_Sem */
206438c8a9a5SSteve French extern spinlock_t GlobalMid_Lock; /* protects above & list operations on midQ entries */
206538c8a9a5SSteve French 
206638c8a9a5SSteve French /*
206738c8a9a5SSteve French  *  Global counters, updated atomically
206838c8a9a5SSteve French  */
206938c8a9a5SSteve French extern atomic_t sesInfoAllocCount;
207038c8a9a5SSteve French extern atomic_t tconInfoAllocCount;
207138c8a9a5SSteve French extern atomic_t tcpSesNextId;
207238c8a9a5SSteve French extern atomic_t tcpSesAllocCount;
207338c8a9a5SSteve French extern atomic_t tcpSesReconnectCount;
207438c8a9a5SSteve French extern atomic_t tconInfoReconnectCount;
207538c8a9a5SSteve French 
207638c8a9a5SSteve French /* Various Debug counters */
207738c8a9a5SSteve French extern atomic_t buf_alloc_count;	/* current number allocated  */
207838c8a9a5SSteve French extern atomic_t small_buf_alloc_count;
207938c8a9a5SSteve French #ifdef CONFIG_CIFS_STATS2
208038c8a9a5SSteve French extern atomic_t total_buf_alloc_count; /* total allocated over all time */
208138c8a9a5SSteve French extern atomic_t total_small_buf_alloc_count;
208238c8a9a5SSteve French extern unsigned int slow_rsp_threshold; /* number of secs before logging */
208338c8a9a5SSteve French #endif
208438c8a9a5SSteve French 
208538c8a9a5SSteve French /* Misc globals */
208638c8a9a5SSteve French extern bool enable_oplocks; /* enable or disable oplocks */
208738c8a9a5SSteve French extern bool lookupCacheEnabled;
208838c8a9a5SSteve French extern unsigned int global_secflags;	/* if on, session setup sent
208938c8a9a5SSteve French 				with more secure ntlmssp2 challenge/resp */
209038c8a9a5SSteve French extern unsigned int sign_CIFS_PDUs;  /* enable smb packet signing */
209138c8a9a5SSteve French extern bool enable_gcm_256; /* allow optional negotiate of strongest signing (aes-gcm-256) */
209238c8a9a5SSteve French extern bool require_gcm_256; /* require use of strongest signing (aes-gcm-256) */
209338c8a9a5SSteve French extern bool enable_negotiate_signing; /* request use of faster (GMAC) signing if available */
209438c8a9a5SSteve French extern bool linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
209538c8a9a5SSteve French extern unsigned int CIFSMaxBufSize;  /* max size not including hdr */
209638c8a9a5SSteve French extern unsigned int cifs_min_rcv;    /* min size of big ntwrk buf pool */
209738c8a9a5SSteve French extern unsigned int cifs_min_small;  /* min size of small buf pool */
209838c8a9a5SSteve French extern unsigned int cifs_max_pending; /* MAX requests at once to server*/
2099238b351dSSteve French extern unsigned int dir_cache_timeout; /* max time for directory lease caching of dir */
210038c8a9a5SSteve French extern bool disable_legacy_dialects;  /* forbid vers=1.0 and vers=2.0 mounts */
210138c8a9a5SSteve French extern atomic_t mid_count;
210238c8a9a5SSteve French 
210338c8a9a5SSteve French void cifs_oplock_break(struct work_struct *work);
210438c8a9a5SSteve French void cifs_queue_oplock_break(struct cifsFileInfo *cfile);
210538c8a9a5SSteve French void smb2_deferred_work_close(struct work_struct *work);
210638c8a9a5SSteve French 
210738c8a9a5SSteve French extern const struct slow_work_ops cifs_oplock_break_ops;
210838c8a9a5SSteve French extern struct workqueue_struct *cifsiod_wq;
210938c8a9a5SSteve French extern struct workqueue_struct *decrypt_wq;
211038c8a9a5SSteve French extern struct workqueue_struct *fileinfo_put_wq;
211138c8a9a5SSteve French extern struct workqueue_struct *cifsoplockd_wq;
211238c8a9a5SSteve French extern struct workqueue_struct *deferredclose_wq;
21136f17163bSRitvik Budhiraja extern struct workqueue_struct *serverclose_wq;
211438c8a9a5SSteve French extern __u32 cifs_lock_secret;
211538c8a9a5SSteve French 
2116c1f3c820SSteve French extern mempool_t *cifs_sm_req_poolp;
2117c1f3c820SSteve French extern mempool_t *cifs_req_poolp;
211838c8a9a5SSteve French extern mempool_t *cifs_mid_poolp;
211938c8a9a5SSteve French 
212038c8a9a5SSteve French /* Operations for different SMB versions */
212138c8a9a5SSteve French #define SMB1_VERSION_STRING	"1.0"
212238c8a9a5SSteve French #define SMB20_VERSION_STRING    "2.0"
212338c8a9a5SSteve French #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
212438c8a9a5SSteve French extern struct smb_version_operations smb1_operations;
212538c8a9a5SSteve French extern struct smb_version_values smb1_values;
212638c8a9a5SSteve French extern struct smb_version_operations smb20_operations;
212738c8a9a5SSteve French extern struct smb_version_values smb20_values;
212838c8a9a5SSteve French #endif /* CIFS_ALLOW_INSECURE_LEGACY */
212938c8a9a5SSteve French #define SMB21_VERSION_STRING	"2.1"
213038c8a9a5SSteve French extern struct smb_version_operations smb21_operations;
213138c8a9a5SSteve French extern struct smb_version_values smb21_values;
213238c8a9a5SSteve French #define SMBDEFAULT_VERSION_STRING "default"
213338c8a9a5SSteve French extern struct smb_version_values smbdefault_values;
213438c8a9a5SSteve French #define SMB3ANY_VERSION_STRING "3"
213538c8a9a5SSteve French extern struct smb_version_values smb3any_values;
213638c8a9a5SSteve French #define SMB30_VERSION_STRING	"3.0"
213738c8a9a5SSteve French extern struct smb_version_operations smb30_operations;
213838c8a9a5SSteve French extern struct smb_version_values smb30_values;
213938c8a9a5SSteve French #define SMB302_VERSION_STRING	"3.02"
214038c8a9a5SSteve French #define ALT_SMB302_VERSION_STRING "3.0.2"
214138c8a9a5SSteve French /*extern struct smb_version_operations smb302_operations;*/ /* not needed yet */
214238c8a9a5SSteve French extern struct smb_version_values smb302_values;
214338c8a9a5SSteve French #define SMB311_VERSION_STRING	"3.1.1"
214438c8a9a5SSteve French #define ALT_SMB311_VERSION_STRING "3.11"
214538c8a9a5SSteve French extern struct smb_version_operations smb311_operations;
214638c8a9a5SSteve French extern struct smb_version_values smb311_values;
214738c8a9a5SSteve French 
get_security_type_str(enum securityEnum sectype)214838c8a9a5SSteve French static inline char *get_security_type_str(enum securityEnum sectype)
214938c8a9a5SSteve French {
215038c8a9a5SSteve French 	switch (sectype) {
215138c8a9a5SSteve French 	case RawNTLMSSP:
215238c8a9a5SSteve French 		return "RawNTLMSSP";
215338c8a9a5SSteve French 	case Kerberos:
215438c8a9a5SSteve French 		return "Kerberos";
215538c8a9a5SSteve French 	case NTLMv2:
215638c8a9a5SSteve French 		return "NTLMv2";
215738c8a9a5SSteve French 	default:
215838c8a9a5SSteve French 		return "Unknown";
215938c8a9a5SSteve French 	}
216038c8a9a5SSteve French }
216138c8a9a5SSteve French 
is_smb1_server(struct TCP_Server_Info * server)216238c8a9a5SSteve French static inline bool is_smb1_server(struct TCP_Server_Info *server)
216338c8a9a5SSteve French {
216438c8a9a5SSteve French 	return strcmp(server->vals->version_string, SMB1_VERSION_STRING) == 0;
216538c8a9a5SSteve French }
216638c8a9a5SSteve French 
is_tcon_dfs(struct cifs_tcon * tcon)216738c8a9a5SSteve French static inline bool is_tcon_dfs(struct cifs_tcon *tcon)
216838c8a9a5SSteve French {
216938c8a9a5SSteve French 	/*
217038c8a9a5SSteve French 	 * For SMB1, see MS-CIFS 2.4.55 SMB_COM_TREE_CONNECT_ANDX (0x75) and MS-CIFS 3.3.4.4 DFS
217138c8a9a5SSteve French 	 * Subsystem Notifies That a Share Is a DFS Share.
217238c8a9a5SSteve French 	 *
217338c8a9a5SSteve French 	 * For SMB2+, see MS-SMB2 2.2.10 SMB2 TREE_CONNECT Response and MS-SMB2 3.3.4.14 Server
217438c8a9a5SSteve French 	 * Application Updates a Share.
217538c8a9a5SSteve French 	 */
217638c8a9a5SSteve French 	if (!tcon || !tcon->ses || !tcon->ses->server)
217738c8a9a5SSteve French 		return false;
217838c8a9a5SSteve French 	return is_smb1_server(tcon->ses->server) ? tcon->Flags & SMB_SHARE_IS_IN_DFS :
217938c8a9a5SSteve French 		tcon->share_flags & (SHI1005_FLAGS_DFS | SHI1005_FLAGS_DFS_ROOT);
218038c8a9a5SSteve French }
218138c8a9a5SSteve French 
cifs_is_referral_server(struct cifs_tcon * tcon,const struct dfs_info3_param * ref)218238c8a9a5SSteve French static inline bool cifs_is_referral_server(struct cifs_tcon *tcon,
218338c8a9a5SSteve French 					   const struct dfs_info3_param *ref)
218438c8a9a5SSteve French {
218538c8a9a5SSteve French 	/*
218638c8a9a5SSteve French 	 * Check if all targets are capable of handling DFS referrals as per
218738c8a9a5SSteve French 	 * MS-DFSC 2.2.4 RESP_GET_DFS_REFERRAL.
218838c8a9a5SSteve French 	 */
218938c8a9a5SSteve French 	return is_tcon_dfs(tcon) || (ref && (ref->flags & DFSREF_REFERRAL_SERVER));
219038c8a9a5SSteve French }
219138c8a9a5SSteve French 
cifs_flock_len(const struct file_lock * fl)219238c8a9a5SSteve French static inline u64 cifs_flock_len(const struct file_lock *fl)
219338c8a9a5SSteve French {
219438c8a9a5SSteve French 	return (u64)fl->fl_end - fl->fl_start + 1;
219538c8a9a5SSteve French }
219638c8a9a5SSteve French 
ntlmssp_workstation_name_size(const struct cifs_ses * ses)219738c8a9a5SSteve French static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses)
219838c8a9a5SSteve French {
219938c8a9a5SSteve French 	if (WARN_ON_ONCE(!ses || !ses->server))
220038c8a9a5SSteve French 		return 0;
220138c8a9a5SSteve French 	/*
220238c8a9a5SSteve French 	 * Make workstation name no more than 15 chars when using insecure dialects as some legacy
220338c8a9a5SSteve French 	 * servers do require it during NTLMSSP.
220438c8a9a5SSteve French 	 */
220538c8a9a5SSteve French 	if (ses->server->dialect <= SMB20_PROT_ID)
220638c8a9a5SSteve French 		return min_t(size_t, sizeof(ses->workstation_name), RFC1001_NAME_LEN_WITH_NULL);
220738c8a9a5SSteve French 	return sizeof(ses->workstation_name);
220838c8a9a5SSteve French }
220938c8a9a5SSteve French 
move_cifs_info_to_smb2(struct smb2_file_all_info * dst,const FILE_ALL_INFO * src)221038c8a9a5SSteve French static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const FILE_ALL_INFO *src)
221138c8a9a5SSteve French {
221238c8a9a5SSteve French 	memcpy(dst, src, (size_t)((u8 *)&src->AccessFlags - (u8 *)src));
221338c8a9a5SSteve French 	dst->AccessFlags = src->AccessFlags;
221438c8a9a5SSteve French 	dst->CurrentByteOffset = src->CurrentByteOffset;
221538c8a9a5SSteve French 	dst->Mode = src->Mode;
221638c8a9a5SSteve French 	dst->AlignmentRequirement = src->AlignmentRequirement;
221738c8a9a5SSteve French 	dst->FileNameLength = src->FileNameLength;
221838c8a9a5SSteve French }
221938c8a9a5SSteve French 
cifs_get_num_sgs(const struct smb_rqst * rqst,int num_rqst,const u8 * sig)222038c8a9a5SSteve French static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
222138c8a9a5SSteve French 				   int num_rqst,
222238c8a9a5SSteve French 				   const u8 *sig)
222338c8a9a5SSteve French {
222438c8a9a5SSteve French 	unsigned int len, skip;
222538c8a9a5SSteve French 	unsigned int nents = 0;
222638c8a9a5SSteve French 	unsigned long addr;
22270c00e422SDavid Howells 	size_t data_size;
222838c8a9a5SSteve French 	int i, j;
222938c8a9a5SSteve French 
223038c8a9a5SSteve French 	/*
223138c8a9a5SSteve French 	 * The first rqst has a transform header where the first 20 bytes are
223238c8a9a5SSteve French 	 * not part of the encrypted blob.
223338c8a9a5SSteve French 	 */
223438c8a9a5SSteve French 	skip = 20;
223538c8a9a5SSteve French 
223638c8a9a5SSteve French 	/* Assumes the first rqst has a transform header as the first iov.
223738c8a9a5SSteve French 	 * I.e.
223838c8a9a5SSteve French 	 * rqst[0].rq_iov[0]  is transform header
223938c8a9a5SSteve French 	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
224038c8a9a5SSteve French 	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
224138c8a9a5SSteve French 	 */
224238c8a9a5SSteve French 	for (i = 0; i < num_rqst; i++) {
22430c00e422SDavid Howells 		data_size = iov_iter_count(&rqst[i].rq_iter);
22440c00e422SDavid Howells 
224538c8a9a5SSteve French 		/* We really don't want a mixture of pinned and unpinned pages
224638c8a9a5SSteve French 		 * in the sglist.  It's hard to keep track of which is what.
224738c8a9a5SSteve French 		 * Instead, we convert to a BVEC-type iterator higher up.
224838c8a9a5SSteve French 		 */
22490c00e422SDavid Howells 		if (data_size &&
22500c00e422SDavid Howells 		    WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
225138c8a9a5SSteve French 			return -EIO;
225238c8a9a5SSteve French 
225338c8a9a5SSteve French 		/* We also don't want to have any extra refs or pins to clean
225438c8a9a5SSteve French 		 * up in the sglist.
225538c8a9a5SSteve French 		 */
22560c00e422SDavid Howells 		if (data_size &&
22570c00e422SDavid Howells 		    WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
225838c8a9a5SSteve French 			return -EIO;
225938c8a9a5SSteve French 
226038c8a9a5SSteve French 		for (j = 0; j < rqst[i].rq_nvec; j++) {
226138c8a9a5SSteve French 			struct kvec *iov = &rqst[i].rq_iov[j];
226238c8a9a5SSteve French 
226338c8a9a5SSteve French 			addr = (unsigned long)iov->iov_base + skip;
226438c8a9a5SSteve French 			if (unlikely(is_vmalloc_addr((void *)addr))) {
226538c8a9a5SSteve French 				len = iov->iov_len - skip;
226638c8a9a5SSteve French 				nents += DIV_ROUND_UP(offset_in_page(addr) + len,
226738c8a9a5SSteve French 						      PAGE_SIZE);
226838c8a9a5SSteve French 			} else {
226938c8a9a5SSteve French 				nents++;
227038c8a9a5SSteve French 			}
227138c8a9a5SSteve French 			skip = 0;
227238c8a9a5SSteve French 		}
22730c00e422SDavid Howells 		if (data_size)
227438c8a9a5SSteve French 			nents += iov_iter_npages(&rqst[i].rq_iter, INT_MAX);
227538c8a9a5SSteve French 	}
227638c8a9a5SSteve French 	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
227738c8a9a5SSteve French 	return nents;
227838c8a9a5SSteve French }
227938c8a9a5SSteve French 
228038c8a9a5SSteve French /* We can not use the normal sg_set_buf() as we will sometimes pass a
228138c8a9a5SSteve French  * stack object as buf.
228238c8a9a5SSteve French  */
cifs_sg_set_buf(struct sg_table * sgtable,const void * buf,unsigned int buflen)228338c8a9a5SSteve French static inline void cifs_sg_set_buf(struct sg_table *sgtable,
228438c8a9a5SSteve French 				   const void *buf,
228538c8a9a5SSteve French 				   unsigned int buflen)
228638c8a9a5SSteve French {
228738c8a9a5SSteve French 	unsigned long addr = (unsigned long)buf;
228838c8a9a5SSteve French 	unsigned int off = offset_in_page(addr);
228938c8a9a5SSteve French 
229038c8a9a5SSteve French 	addr &= PAGE_MASK;
229138c8a9a5SSteve French 	if (unlikely(is_vmalloc_addr((void *)addr))) {
229238c8a9a5SSteve French 		do {
229338c8a9a5SSteve French 			unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
229438c8a9a5SSteve French 
229538c8a9a5SSteve French 			sg_set_page(&sgtable->sgl[sgtable->nents++],
229638c8a9a5SSteve French 				    vmalloc_to_page((void *)addr), len, off);
229738c8a9a5SSteve French 
229838c8a9a5SSteve French 			off = 0;
229938c8a9a5SSteve French 			addr += PAGE_SIZE;
230038c8a9a5SSteve French 			buflen -= len;
230138c8a9a5SSteve French 		} while (buflen);
230238c8a9a5SSteve French 	} else {
230338c8a9a5SSteve French 		sg_set_page(&sgtable->sgl[sgtable->nents++],
23043b1ddbb6SArnd Bergmann 			    virt_to_page((void *)addr), buflen, off);
230538c8a9a5SSteve French 	}
230638c8a9a5SSteve French }
230738c8a9a5SSteve French 
2308831ffbd1SPaulo Alcantara #define CIFS_OPARMS(_cifs_sb, _tcon, _path, _da, _cd, _co, _mode) \
2309831ffbd1SPaulo Alcantara 	((struct cifs_open_parms) { \
2310831ffbd1SPaulo Alcantara 		.tcon = _tcon, \
2311831ffbd1SPaulo Alcantara 		.path = _path, \
2312831ffbd1SPaulo Alcantara 		.desired_access = (_da), \
2313831ffbd1SPaulo Alcantara 		.disposition = (_cd), \
2314831ffbd1SPaulo Alcantara 		.create_options = cifs_create_options(_cifs_sb, (_co)), \
2315831ffbd1SPaulo Alcantara 		.mode = (_mode), \
2316831ffbd1SPaulo Alcantara 		.cifs_sb = _cifs_sb, \
2317831ffbd1SPaulo Alcantara 	})
2318831ffbd1SPaulo Alcantara 
2319f4e5ceb6SPaulo Alcantara struct smb2_compound_vars {
2320f4e5ceb6SPaulo Alcantara 	struct cifs_open_parms oparms;
2321886b7fb4SSteve French 	struct kvec rsp_iov[MAX_COMPOUND];
2322886b7fb4SSteve French 	struct smb_rqst rqst[MAX_COMPOUND];
2323f4e5ceb6SPaulo Alcantara 	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
2324f4e5ceb6SPaulo Alcantara 	struct kvec qi_iov;
2325f4e5ceb6SPaulo Alcantara 	struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
2326f4e5ceb6SPaulo Alcantara 	struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
2327f4e5ceb6SPaulo Alcantara 	struct kvec close_iov;
2328f4e5ceb6SPaulo Alcantara 	struct smb2_file_rename_info rename_info;
2329f4e5ceb6SPaulo Alcantara 	struct smb2_file_link_info link_info;
23307449d736SSteve French 	struct kvec ea_iov;
2331f4e5ceb6SPaulo Alcantara };
2332f4e5ceb6SPaulo Alcantara 
cifs_ses_exiting(struct cifs_ses * ses)2333a65f2b56SPaulo Alcantara static inline bool cifs_ses_exiting(struct cifs_ses *ses)
2334a65f2b56SPaulo Alcantara {
2335a65f2b56SPaulo Alcantara 	bool ret;
2336a65f2b56SPaulo Alcantara 
2337a65f2b56SPaulo Alcantara 	spin_lock(&ses->ses_lock);
2338a65f2b56SPaulo Alcantara 	ret = ses->ses_status == SES_EXITING;
2339a65f2b56SPaulo Alcantara 	spin_unlock(&ses->ses_lock);
2340a65f2b56SPaulo Alcantara 	return ret;
2341a65f2b56SPaulo Alcantara }
2342a65f2b56SPaulo Alcantara 
234338c8a9a5SSteve French #endif	/* _CIFS_GLOB_H */
2344