fsnotify: document mark locking

Signed-off-by: Jan Kara <jack@suse.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Jan Kara 2015-09-04 15:43:06 -07:00 committed by Linus Torvalds
parent 3c53e51421
commit 1e39fc0183

View File

@ -195,40 +195,50 @@ struct fsnotify_group {
#define FSNOTIFY_EVENT_INODE 2 #define FSNOTIFY_EVENT_INODE 2
/* /*
* a mark is simply an object attached to an in core inode which allows an * A mark is simply an object attached to an in core inode which allows an
* fsnotify listener to indicate they are either no longer interested in events * fsnotify listener to indicate they are either no longer interested in events
* of a type matching mask or only interested in those events. * of a type matching mask or only interested in those events.
* *
* these are flushed when an inode is evicted from core and may be flushed * These are flushed when an inode is evicted from core and may be flushed
* when the inode is modified (as seen by fsnotify_access). Some fsnotify users * when the inode is modified (as seen by fsnotify_access). Some fsnotify
* (such as dnotify) will flush these when the open fd is closed and not at * users (such as dnotify) will flush these when the open fd is closed and not
* inode eviction or modification. * at inode eviction or modification.
*
* Text in brackets is showing the lock(s) protecting modifications of a
* particular entry. obj_lock means either inode->i_lock or
* mnt->mnt_root->d_lock depending on the mark type.
*/ */
struct fsnotify_mark { struct fsnotify_mark {
__u32 mask; /* mask this mark is for */ /* Mask this mark is for [mark->lock, group->mark_mutex] */
/* we hold ref for each i_list and g_list. also one ref for each 'thing' __u32 mask;
/* We hold one for presence in g_list. Also one ref for each 'thing'
* in kernel that found and may be using this mark. */ * in kernel that found and may be using this mark. */
atomic_t refcnt; /* active things looking at this mark */ atomic_t refcnt;
struct fsnotify_group *group; /* group this mark is for */ /* Group this mark is for. Set on mark creation, stable until last ref
struct list_head g_list; /* list of marks by group->i_fsnotify_marks * is dropped */
* Also reused for queueing mark into struct fsnotify_group *group;
* destroy_list when it's waiting for /* List of marks by group->i_fsnotify_marks. Also reused for queueing
* the end of SRCU period before it can * mark into destroy_list when it's waiting for the end of SRCU period
* be freed */ * before it can be freed. [group->mark_mutex] */
spinlock_t lock; /* protect group and inode */ struct list_head g_list;
struct hlist_node obj_list; /* list of marks for inode / vfsmount */ /* Protects inode / mnt pointers, flags, masks */
struct list_head free_list; /* tmp list used when freeing this mark */ spinlock_t lock;
union { /* List of marks for inode / vfsmount [obj_lock] */
struct hlist_node obj_list;
/* tmp list used when freeing this mark */
struct list_head free_list;
union { /* Object pointer [mark->lock, group->mark_mutex] */
struct inode *inode; /* inode this mark is associated with */ struct inode *inode; /* inode this mark is associated with */
struct vfsmount *mnt; /* vfsmount this mark is associated with */ struct vfsmount *mnt; /* vfsmount this mark is associated with */
}; };
__u32 ignored_mask; /* events types to ignore */ /* Events types to ignore [mark->lock, group->mark_mutex] */
__u32 ignored_mask;
#define FSNOTIFY_MARK_FLAG_INODE 0x01 #define FSNOTIFY_MARK_FLAG_INODE 0x01
#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02 #define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02
#define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04 #define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04
#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08 #define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08
#define FSNOTIFY_MARK_FLAG_ALIVE 0x10 #define FSNOTIFY_MARK_FLAG_ALIVE 0x10
unsigned int flags; /* vfsmount or inode mark? */ unsigned int flags; /* flags [mark->lock] */
void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */ void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
}; };