summaryrefslogtreecommitdiff
path: root/fs/cifs/cifsglob.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-08-07 20:50:59 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2022-08-07 20:50:59 +0300
commit3bc1bc0b59d04e997db25b84babf459ca1cd80b7 (patch)
tree262e57fefa353b7646a1d03b2796fb2c6e4c1a70 /fs/cifs/cifsglob.h
parenteb5699ba31558bdb2cee6ebde3d0a68091e47dce (diff)
parent0d168a58fca34806b575c7cba87afb11208acb54 (diff)
downloadlinux-3bc1bc0b59d04e997db25b84babf459ca1cd80b7.tar.xz
Merge tag '5.20-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs updates from Steve French: "Mostly cleanup, including smb1 refactoring: - multichannel perf improvement - move additional SMB1 code to not be compiled in when legacy support is disabled. - bug fixes, including one important one for memory leak - various cleanup patches We are still working on and testing some deferred close improvements including an important lease break fix for case when multiple deferred closes are still open, and also some additional perf improvements - those are not included here" * tag '5.20-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6: cifs: update internal module number cifs: alloc_mid function should be marked as static cifs: remove "cifs_" prefix from init/destroy mids functions cifs: remove useless DeleteMidQEntry() cifs: when insecure legacy is disabled shrink amount of SMB1 code cifs: trivial style fixup cifs: fix wrong unlock before return from cifs_tree_connect() cifs: avoid use of global locks for high contention data cifs: remove remaining build warnings cifs: list_for_each() -> list_for_each_entry() cifs: update MAINTAINERS file with reviewers smb2: small refactor in smb2_check_message() cifs: Fix memory leak when using fscache cifs: remove minor build warning cifs: remove some camelCase and also some static build warnings cifs: remove unnecessary (void*) conversions. cifs: remove unnecessary type castings cifs: remove redundant initialization to variable mnt_sign_enabled smb3: check xattr value length earlier
Diffstat (limited to 'fs/cifs/cifsglob.h')
-rw-r--r--fs/cifs/cifsglob.h135
1 files changed, 91 insertions, 44 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index a643c84ff1e9..3070407cafa7 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -605,6 +605,7 @@ inc_rfc1001_len(void *buf, int count)
struct TCP_Server_Info {
struct list_head tcp_ses_list;
struct list_head smb_ses_list;
+ spinlock_t srv_lock; /* protect anything here that is not protected */
__u64 conn_id; /* connection identifier (useful for debugging) */
int srv_count; /* reference counter */
/* 15 character server name + 0x20 16th byte indicating type = srv */
@@ -622,6 +623,7 @@ struct TCP_Server_Info {
#endif
wait_queue_head_t response_q;
wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
+ spinlock_t mid_lock; /* protect mid queue and it's entries */
struct list_head pending_mid_q;
bool noblocksnd; /* use blocking sendmsg */
bool noautotune; /* do not autotune send buf sizes */
@@ -1008,6 +1010,7 @@ struct cifs_ses {
struct list_head rlist; /* reconnect list */
struct list_head tcon_list;
struct cifs_tcon *tcon_ipc;
+ spinlock_t ses_lock; /* protect anything here that is not protected */
struct mutex session_mutex;
struct TCP_Server_Info *server; /* pointer to server info */
int ses_count; /* reference counter */
@@ -1169,6 +1172,7 @@ struct cifs_tcon {
struct list_head tcon_list;
int tc_count;
struct list_head rlist; /* reconnect list */
+ spinlock_t tc_lock; /* protect anything here that is not protected */
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;
@@ -1899,33 +1903,78 @@ require use of the stronger protocol */
*/
/****************************************************************************
- * Locking notes. All updates to global variables and lists should be
- * protected by spinlocks or semaphores.
+ * Here are all the locks (spinlock, mutex, semaphore) in cifs.ko, arranged according
+ * to the locking order. i.e. if two locks are to be held together, the lock that
+ * appears higher in this list needs to be taken before the other.
*
- * Spinlocks
- * ---------
- * GlobalMid_Lock protects:
- * list operations on pending_mid_q and oplockQ
- * updates to XID counters, multiplex id and SMB sequence numbers
- * list operations on global DnotifyReqList
- * updates to ses->status and TCP_Server_Info->tcpStatus
- * updates to server->CurrentMid
- * tcp_ses_lock protects:
- * list operations on tcp and SMB session lists
- * tcon->open_file_lock protects the list of open files hanging off the tcon
- * inode->open_file_lock protects the openFileList hanging off the inode
- * cfile->file_info_lock protects counters and fields in cifs file struct
- * f_owner.lock protects certain per file struct operations
- * mapping->page_lock protects certain per page operations
+ * If you hold a lock that is lower in this list, and you need to take a higher lock
+ * (or if you think that one of the functions that you're calling may need to), first
+ * drop the lock you hold, pick up the higher lock, then the lower one. This will
+ * ensure that locks are picked up only in one direction in the below table
+ * (top to bottom).
*
- * Note that the cifs_tcon.open_file_lock should be taken before
- * not after the cifsInodeInfo.open_file_lock
+ * Also, if you expect a function to be called with a lock held, explicitly document
+ * this in the comments on top of your function definition.
*
- * Semaphores
- * ----------
- * cifsInodeInfo->lock_sem protects:
- * the list of locks held by the inode
+ * And also, try to keep the critical sections (lock hold time) to be as minimal as
+ * possible. Blocking / calling other functions with a lock held always increase
+ * the risk of a possible deadlock.
*
+ * Following this rule will avoid unnecessary deadlocks, which can get really hard to
+ * debug. Also, any new lock that you introduce, please add to this list in the correct
+ * order.
+ *
+ * Please populate this list whenever you introduce new locks in your changes. Or in
+ * case I've missed some existing locks. Please ensure that it's added in the list
+ * based on the locking order expected.
+ *
+ * =====================================================================================
+ * Lock Protects Initialization fn
+ * =====================================================================================
+ * vol_list_lock
+ * vol_info->ctx_lock vol_info->ctx
+ * cifs_sb_info->tlink_tree_lock cifs_sb_info->tlink_tree cifs_setup_cifs_sb
+ * TCP_Server_Info-> TCP_Server_Info cifs_get_tcp_session
+ * reconnect_mutex
+ * TCP_Server_Info->srv_mutex TCP_Server_Info cifs_get_tcp_session
+ * cifs_ses->session_mutex cifs_ses sesInfoAlloc
+ * cifs_tcon
+ * cifs_tcon->open_file_lock cifs_tcon->openFileList tconInfoAlloc
+ * cifs_tcon->pending_opens
+ * cifs_tcon->stat_lock cifs_tcon->bytes_read tconInfoAlloc
+ * cifs_tcon->bytes_written
+ * cifs_tcp_ses_lock cifs_tcp_ses_list sesInfoAlloc
+ * GlobalMid_Lock GlobalMaxActiveXid init_cifs
+ * GlobalCurrentXid
+ * GlobalTotalActiveXid
+ * TCP_Server_Info->srv_lock (anything in struct not protected by another lock and can change)
+ * TCP_Server_Info->mid_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session
+ * ->CurrentMid
+ * (any changes in mid_q_entry fields)
+ * TCP_Server_Info->req_lock TCP_Server_Info->in_flight cifs_get_tcp_session
+ * ->credits
+ * ->echo_credits
+ * ->oplock_credits
+ * ->reconnect_instance
+ * cifs_ses->ses_lock (anything that is not protected by another lock and can change)
+ * cifs_ses->iface_lock cifs_ses->iface_list sesInfoAlloc
+ * ->iface_count
+ * ->iface_last_update
+ * cifs_ses->chan_lock cifs_ses->chans
+ * ->chans_need_reconnect
+ * ->chans_in_reconnect
+ * cifs_tcon->tc_lock (anything that is not protected by another lock and can change)
+ * cifsInodeInfo->open_file_lock cifsInodeInfo->openFileList cifs_alloc_inode
+ * cifsInodeInfo->writers_lock cifsInodeInfo->writers cifsInodeInfo_alloc
+ * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once
+ * ->can_cache_brlcks
+ * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc
+ * cached_fid->fid_mutex cifs_tcon->crfid tconInfoAlloc
+ * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo
+ * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo
+ * ->invalidHandle initiate_cifs_search
+ * ->oplock_break_cancelled
+ * cifs_aio_ctx->aio_mutex cifs_aio_ctx cifs_aio_ctx_alloc
****************************************************************************/
#ifdef DECLARE_GLOBALS_HERE
@@ -1941,47 +1990,44 @@ require use of the stronger protocol */
* sessions (and from that the tree connections) can be found
* by iterating over cifs_tcp_ses_list
*/
-GLOBAL_EXTERN struct list_head cifs_tcp_ses_list;
+extern struct list_head cifs_tcp_ses_list;
/*
* This lock protects the cifs_tcp_ses_list, the list of smb sessions per
* tcp session, and the list of tcon's per smb session. It also protects
- * the reference counters for the server, smb session, and tcon. It also
- * protects some fields in the TCP_Server_Info struct such as dstaddr. Finally,
- * changes to the tcon->tidStatus should be done while holding this lock.
+ * the reference counters for the server, smb session, and tcon.
* generally the locks should be taken in order tcp_ses_lock before
* tcon->open_file_lock and that before file->file_info_lock since the
* structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file
*/
-GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;
+extern spinlock_t cifs_tcp_ses_lock;
/*
* Global transaction id (XID) information
*/
-GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */
-GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
-GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
-GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */
- /* on midQ entries */
+extern unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */
+extern unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
+extern unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
+extern spinlock_t GlobalMid_Lock; /* protects above & list operations on midQ entries */
+
/*
* Global counters, updated atomically
*/
-GLOBAL_EXTERN atomic_t sesInfoAllocCount;
-GLOBAL_EXTERN atomic_t tconInfoAllocCount;
-GLOBAL_EXTERN atomic_t tcpSesNextId;
-GLOBAL_EXTERN atomic_t tcpSesAllocCount;
-GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
-GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
+extern atomic_t sesInfoAllocCount;
+extern atomic_t tconInfoAllocCount;
+extern atomic_t tcpSesNextId;
+extern atomic_t tcpSesAllocCount;
+extern atomic_t tcpSesReconnectCount;
+extern atomic_t tconInfoReconnectCount;
/* Various Debug counters */
-GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */
+extern atomic_t buf_alloc_count; /* current number allocated */
+extern atomic_t small_buf_alloc_count;
#ifdef CONFIG_CIFS_STATS2
-GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */
-GLOBAL_EXTERN atomic_t totSmBufAllocCount;
+extern atomic_t total_buf_alloc_count; /* total allocated over all time */
+extern atomic_t total_small_buf_alloc_count;
extern unsigned int slow_rsp_threshold; /* number of secs before logging */
#endif
-GLOBAL_EXTERN atomic_t smBufAllocCount;
-GLOBAL_EXTERN atomic_t midCount;
/* Misc globals */
extern bool enable_oplocks; /* enable or disable oplocks */
@@ -1998,6 +2044,7 @@ 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 */
+extern atomic_t mid_count;
void cifs_oplock_break(struct work_struct *work);
void cifs_queue_oplock_break(struct cifsFileInfo *cfile);