diff options
Diffstat (limited to 'fs/cifs/cifsglob.h')
-rw-r--r-- | fs/cifs/cifsglob.h | 176 |
1 files changed, 117 insertions, 59 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 48f7c197cd2d..38ab0fca49e1 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -33,6 +33,10 @@ #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ +#define SMB_PATH_MAX 260 +#define CIFS_PORT 445 +#define RFC1001_PORT 139 + /* * The sizes of various internal tables and strings */ @@ -73,6 +77,9 @@ #define SMB_ECHO_INTERVAL_MAX 600 #define SMB_ECHO_INTERVAL_DEFAULT 60 +/* maximum number of PDUs in one compound */ +#define MAX_COMPOUND 5 + /* * Default number of credits to keep available for SMB3. * This value is chosen somewhat arbitrarily. The Windows client @@ -130,10 +137,12 @@ struct cifs_secmech { struct crypto_shash *md5; /* md5 hash function */ struct crypto_shash *hmacsha256; /* hmac-sha256 hash function */ struct crypto_shash *cmacaes; /* block-cipher based MAC function */ + struct crypto_shash *sha512; /* sha512 hash function */ struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */ struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */ struct sdesc *sdeschmacsha256; /* ctxt to generate smb2 signature */ struct sdesc *sdesccmacaes; /* ctxt to generate smb3 signature */ + struct sdesc *sdescsha512; /* ctxt to generate smb3.11 signing key */ struct crypto_aead *ccmaesencrypt; /* smb3 encryption aead */ struct crypto_aead *ccmaesdecrypt; /* smb3 decryption aead */ }; @@ -174,6 +183,7 @@ struct smb_rqst { struct kvec *rq_iov; /* array of kvecs */ unsigned int rq_nvec; /* number of kvecs in array */ struct page **rq_pages; /* pointer to array of page ptrs */ + unsigned int rq_offset; /* the offset to the 1st page */ unsigned int rq_npages; /* number pages in array */ unsigned int rq_pagesz; /* page size to use */ unsigned int rq_tailsz; /* length of last page */ @@ -185,9 +195,7 @@ enum smb_version { Smb_21, Smb_30, Smb_302, -#ifdef CONFIG_CIFS_SMB311 Smb_311, -#endif /* SMB311 */ Smb_3any, Smb_default, Smb_version_err @@ -242,7 +250,7 @@ struct smb_version_operations { int (*map_error)(char *, bool); /* find mid corresponding to the response message */ struct mid_q_entry * (*find_mid)(struct TCP_Server_Info *, char *); - void (*dump_detail)(void *); + void (*dump_detail)(void *buf, struct TCP_Server_Info *ptcp_info); void (*clear_stats)(struct cifs_tcon *); void (*print_stats)(struct seq_file *m, struct cifs_tcon *); void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *); @@ -309,6 +317,10 @@ struct smb_version_operations { /* send echo request */ int (*echo)(struct TCP_Server_Info *); /* create directory */ + int (*posix_mkdir)(const unsigned int xid, struct inode *inode, + umode_t mode, struct cifs_tcon *tcon, + const char *full_path, + struct cifs_sb_info *cifs_sb); int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *, struct cifs_sb_info *); /* set info on created directory */ @@ -370,7 +382,7 @@ struct smb_version_operations { int (*close_dir)(const unsigned int, struct cifs_tcon *, struct cifs_fid *); /* calculate a size of SMB message */ - unsigned int (*calc_smb_size)(void *); + unsigned int (*calc_smb_size)(void *buf, struct TCP_Server_Info *ptcpi); /* check for STATUS_PENDING and process it in a positive case */ bool (*is_status_pending)(char *, struct TCP_Server_Info *, int); /* check for STATUS_NETWORK_SESSION_EXPIRED */ @@ -413,9 +425,9 @@ struct smb_version_operations { void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int, bool *); /* create lease context buffer for CREATE request */ - char * (*create_lease_buf)(u8 *, u8); + char * (*create_lease_buf)(u8 *lease_key, u8 oplock); /* parse lease context buffer and return oplock/epoch info */ - __u8 (*parse_lease_buf)(void *, unsigned int *); + __u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey); ssize_t (*copychunk_range)(const unsigned int, struct cifsFileInfo *src_file, struct cifsFileInfo *target_file, @@ -446,16 +458,19 @@ struct smb_version_operations { long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, loff_t); /* init transform request - used for encryption for now */ - int (*init_transform_rq)(struct TCP_Server_Info *, struct smb_rqst *, - struct smb_rqst *); - /* free transform request */ - void (*free_transform_rq)(struct smb_rqst *); + int (*init_transform_rq)(struct TCP_Server_Info *, int num_rqst, + struct smb_rqst *, struct smb_rqst *); int (*is_transform_hdr)(void *buf); int (*receive_transform)(struct TCP_Server_Info *, - struct mid_q_entry **); + struct mid_q_entry **, char **, int *); enum securityEnum (*select_sectype)(struct TCP_Server_Info *, enum securityEnum); - + int (*next_header)(char *); + /* ioctl passthrough for query_info */ + int (*ioctl_query_info)(const unsigned int xid, + struct cifs_tcon *tcon, + __le16 *path, int is_dir, + unsigned long p); }; struct smb_version_values { @@ -466,6 +481,7 @@ struct smb_version_values { __u32 exclusive_lock_type; __u32 shared_lock_type; __u32 unlock_lock_type; + size_t header_preamble_size; size_t header_size; size_t max_header_size; size_t read_rsp_size; @@ -518,10 +534,12 @@ struct smb_vol { bool sfu_remap:1; /* remap seven reserved chars ala SFU */ bool posix_paths:1; /* unset to not ask for posix pathnames. */ bool no_linux_ext:1; + bool linux_ext:1; bool sfu_emul:1; bool nullauth:1; /* attempt to authenticate with null user */ bool nocase:1; /* request case insensitive filenames */ bool nobrl:1; /* disable sending byte range locks to srv */ + bool nohandlecache:1; /* disable caching dir handles if srvr probs */ bool mand_lock:1; /* send mandatory not posix byte range lock reqs */ bool seal:1; /* request transport encryption on share */ bool nodfs:1; /* Do not request DFS, even if available */ @@ -627,7 +645,7 @@ struct TCP_Server_Info { bool oplocks:1; /* enable oplocks */ unsigned int maxReq; /* Clients should submit no more */ /* than maxReq distinct unanswered SMBs to the server when using */ - /* multiplexed reads or writes */ + /* multiplexed reads or writes (for SMB1/CIFS only, not SMB2/SMB3) */ unsigned int maxBuf; /* maxBuf specifies the maximum */ /* message size the server can send or receive for non-raw SMBs */ /* maxBuf is returned by SMB NegotiateProtocol so maxBuf is only 0 */ @@ -642,6 +660,7 @@ struct TCP_Server_Info { /* 16th byte of RFC1001 workstation name is always null */ char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; __u32 sequence_number; /* for signing, protected by srv_mutex */ + __u32 reconnect_instance; /* incremented on each reconnect */ struct session_key session_key; unsigned long lstrp; /* when we got last response from this server */ struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */ @@ -662,6 +681,8 @@ struct TCP_Server_Info { struct delayed_work echo; /* echo ping workqueue job */ char *smallbuf; /* pointer to current "small" buffer */ char *bigbuf; /* pointer to current "big" buffer */ + /* Total size of this PDU. Only valid from cifs_demultiplex_thread */ + unsigned int pdu_size; unsigned int total_read; /* total amount of data read in this pass */ #ifdef CONFIG_CIFS_FSCACHE struct fscache_cookie *fscache; /* client index cache cookie */ @@ -669,12 +690,14 @@ struct TCP_Server_Info { #ifdef CONFIG_CIFS_STATS2 atomic_t in_send; /* requests trying to send */ atomic_t num_waiters; /* blocked waiting to get in sendrecv */ -#endif + atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */ +#endif /* STATS2 */ unsigned int max_read; unsigned int max_write; -#ifdef CONFIG_CIFS_SMB311 - __u8 preauth_sha_hash[64]; /* save initital negprot hash */ -#endif /* 3.1.1 */ + __le16 cipher_type; + /* save initital negprot hash */ + __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; + bool posix_ext_supported; struct delayed_work reconnect; /* reconnect workqueue job */ struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ unsigned long echo_interval; @@ -782,6 +805,7 @@ compare_mid(__u16 mid, const struct smb_hdr *smb) * a single wsize request with a single call. */ #define CIFS_DEFAULT_IOSIZE (1024 * 1024) +#define SMB3_DEFAULT_IOSIZE (4 * 1024 * 1024) /* * Windows only supports a max of 60kb reads and 65535 byte writes. Default to @@ -827,6 +851,13 @@ static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net) #endif +struct cifs_server_iface { + size_t speed; + unsigned int rdma_capable : 1; + unsigned int rss_capable : 1; + struct sockaddr_storage sockaddr; +}; + /* * Session structure. One of these for each uid session with a particular host */ @@ -861,9 +892,21 @@ struct cifs_ses { __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; -#ifdef CONFIG_CIFS_SMB311 - __u8 preauth_sha_hash[64]; -#endif /* 3.1.1 */ + __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; + + /* + * Network interfaces available on the server this session is + * connected to. + * + * Other channels can be opened by connecting and binding this + * session to interfaces from this list. + * + * iface_lock should be taken when accessing any of these fields + */ + spinlock_t iface_lock; + struct cifs_server_iface *iface_list; + size_t iface_count; + unsigned long iface_last_update; /* jiffies */ }; static inline bool @@ -872,6 +915,15 @@ cap_unix(struct cifs_ses *ses) return ses->server->vals->cap_unix & ses->capabilities; } +struct cached_fid { + bool is_valid:1; /* Do we have a useable root fid */ + struct kref refcount; + struct cifs_fid *fid; + struct mutex fid_mutex; + struct cifs_tcon *tcon; + struct work_struct lease_break; +}; + /* * there is one of these for each connection to a resource on a particular * session @@ -880,6 +932,8 @@ struct cifs_tcon { struct list_head tcon_list; int tc_count; struct list_head rlist; /* reconnect list */ + atomic_t num_local_opens; /* num of all opens including disconnected */ + atomic_t num_remote_opens; /* num of all network opens on server */ struct list_head openFileList; spinlock_t open_file_lock; /* protects list above */ struct cifs_ses *ses; /* pointer to session associated with */ @@ -889,7 +943,6 @@ struct cifs_tcon { __u32 tid; /* The 4 byte tree id */ __u16 Flags; /* optional support bits */ enum statusEnum tidStatus; -#ifdef CONFIG_CIFS_STATS atomic_t num_smbs_sent; union { struct { @@ -920,24 +973,9 @@ struct cifs_tcon { atomic_t smb2_com_failed[NUMBER_OF_SMB2_COMMANDS]; } smb2_stats; } stats; -#ifdef CONFIG_CIFS_STATS2 - unsigned long long time_writes; - unsigned long long time_reads; - unsigned long long time_opens; - unsigned long long time_deletes; - unsigned long long time_closes; - unsigned long long time_mkdirs; - unsigned long long time_rmdirs; - unsigned long long time_renames; - unsigned long long time_t2renames; - unsigned long long time_ffirst; - unsigned long long time_fnext; - unsigned long long time_fclose; -#endif /* CONFIG_CIFS_STATS2 */ __u64 bytes_read; __u64 bytes_written; spinlock_t stat_lock; /* protects the two fields above */ -#endif /* CONFIG_CIFS_STATS */ FILE_SYSTEM_DEVICE_INFO fsDevInfo; FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ FILE_SYSTEM_UNIX_INFO fsUnixInfo; @@ -946,9 +984,11 @@ struct cifs_tcon { bool print:1; /* set if connection to printer share */ bool retry:1; bool nocase:1; + bool nohandlecache:1; /* if strange server resource prob can turn off */ bool seal:1; /* transport encryption for this mounted share */ bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol for this mount even if server would support */ + bool posix_extensions; /* if true SMB3.11 posix extensions enabled */ bool local_lease:1; /* check leases (only) on local system not remote */ bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */ bool broken_sparse_sup; /* if server or share does not support sparse */ @@ -972,6 +1012,7 @@ struct cifs_tcon { struct fscache_cookie *fscache; /* cookie for share */ #endif struct list_head pending_opens; /* list of incomplete opens */ + struct cached_fid crfid; /* Cached root fid */ /* BB add field for back pointer to sb struct(s)? */ }; @@ -994,6 +1035,7 @@ struct tcon_link { }; extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb); +extern void smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst); static inline struct cifs_tcon * tlink_tcon(struct tcon_link *tlink) @@ -1001,6 +1043,12 @@ tlink_tcon(struct tcon_link *tlink) return tlink->tl_tcon; } +static inline struct tcon_link * +cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) +{ + return cifs_sb->master_tlink; +} + extern void cifs_put_tlink(struct tcon_link *tlink); static inline struct tcon_link * @@ -1034,7 +1082,8 @@ struct cifsLockInfo { __u64 offset; __u64 length; __u32 pid; - __u32 type; + __u16 type; + __u16 flags; }; /* @@ -1064,6 +1113,7 @@ struct cifs_open_parms { int create_options; const char *path; struct cifs_fid *fid; + umode_t mode; bool reconnect:1; }; @@ -1075,6 +1125,9 @@ struct cifs_fid { __u8 create_guid[16]; struct cifs_pending_open *pending_open; unsigned int epoch; +#ifdef CONFIG_CIFS_DEBUG2 + __u64 mid; +#endif /* CIFS_DEBUG2 */ bool purge_cache; }; @@ -1133,6 +1186,11 @@ struct cifs_aio_ctx { unsigned int len; unsigned int total_len; bool should_dirty; + /* + * Indicates if this aio_ctx is for direct_io, + * If yes, iter is a copy of the user passed iov_iter + */ + bool direct_io; }; struct cifs_readdata; @@ -1162,10 +1220,11 @@ struct cifs_readdata { struct smbd_mr *mr; #endif unsigned int pagesz; + unsigned int page_offset; unsigned int tailsz; unsigned int credits; unsigned int nr_pages; - struct page *pages[]; + struct page **pages; }; struct cifs_writedata; @@ -1187,10 +1246,11 @@ struct cifs_writedata { struct smbd_mr *mr; #endif unsigned int pagesz; + unsigned int page_offset; unsigned int tailsz; unsigned int credits; unsigned int nr_pages; - struct page *pages[]; + struct page **pages; }; /* @@ -1291,7 +1351,6 @@ convert_delimiter(char *path, char delim) *pos = delim; } -#ifdef CONFIG_CIFS_STATS #define cifs_stats_inc atomic_inc static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon, @@ -1311,13 +1370,6 @@ static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon, tcon->bytes_read += bytes; spin_unlock(&tcon->stat_lock); } -#else - -#define cifs_stats_inc(field) do {} while (0) -#define cifs_stats_bytes_written(tcon, bytes) do {} while (0) -#define cifs_stats_bytes_read(tcon, bytes) do {} while (0) - -#endif /* @@ -1355,6 +1407,7 @@ typedef int (mid_handle_t)(struct TCP_Server_Info *server, /* one of these for every pending CIFS request to the server */ struct mid_q_entry { struct list_head qhead; /* mids waiting on reply from this server */ + struct kref refcount; struct TCP_Server_Info *server; /* server corresponding to this mid */ __u64 mid; /* multiplex id */ __u32 pid; /* process id */ @@ -1369,6 +1422,7 @@ struct mid_q_entry { mid_handle_t *handle; /* call handle mid callback */ void *callback_data; /* general purpose pointer for callback */ void *resp_buf; /* pointer to received SMB header */ + unsigned int resp_buf_size; int mid_state; /* wish this were enum but can not pass to wait_event */ unsigned int mid_flags; __le16 command; /* smb command code */ @@ -1466,6 +1520,7 @@ struct dfs_info3_param { #define CIFS_FATTR_NEED_REVAL 0x4 #define CIFS_FATTR_INO_COLLISION 0x8 #define CIFS_FATTR_UNKNOWN_NLINK 0x10 +#define CIFS_FATTR_FAKE_ROOT_INO 0x20 struct cifs_fattr { u32 cf_flags; @@ -1480,9 +1535,9 @@ struct cifs_fattr { dev_t cf_rdev; unsigned int cf_nlink; unsigned int cf_dtype; - struct timespec cf_atime; - struct timespec cf_mtime; - struct timespec cf_ctime; + struct timespec64 cf_atime; + struct timespec64 cf_mtime; + struct timespec64 cf_ctime; }; static inline void free_dfs_info_param(struct dfs_info3_param *param) @@ -1517,6 +1572,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, /* Flags */ #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ +#define MID_DELETED 2 /* Mid has been dequeued/deleted */ /* Types of response buffer returned from SendReceive2 */ #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ @@ -1678,21 +1734,23 @@ GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */ #ifdef CONFIG_CIFS_STATS2 GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */ GLOBAL_EXTERN atomic_t totSmBufAllocCount; +extern unsigned int slow_rsp_threshold; /* number of secs before logging */ #endif GLOBAL_EXTERN atomic_t smBufAllocCount; GLOBAL_EXTERN atomic_t midCount; /* Misc globals */ -GLOBAL_EXTERN bool enable_oplocks; /* enable or disable oplocks */ -GLOBAL_EXTERN bool lookupCacheEnabled; -GLOBAL_EXTERN unsigned int global_secflags; /* if on, session setup sent +extern bool enable_oplocks; /* enable or disable oplocks */ +extern bool lookupCacheEnabled; +extern unsigned int global_secflags; /* if on, session setup sent with more secure ntlmssp2 challenge/resp */ -GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ -GLOBAL_EXTERN bool linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ -GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ -GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ -GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */ -GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/ +extern unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ +extern bool linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ +extern unsigned int CIFSMaxBufSize; /* max size not including hdr */ +extern unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ +extern unsigned int cifs_min_small; /* min size of small buf pool */ +extern unsigned int cifs_max_pending; /* MAX requests at once to server*/ +extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */ #ifdef CONFIG_CIFS_ACL GLOBAL_EXTERN struct rb_root uidtree; |