mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
fsnotify: create helper fsnotify_update_sb_watchers()
We would like to count watched objects by priority group, so we will need to update the watched object counter after adding/removing marks. Create a helper fsnotify_update_sb_watchers() and call it after attaching/detaching a mark, instead of fsnotify_{get,put}_sb_watchers() only after attaching/detaching a connector. Soon, we will use this helper to count watched objects by the highest watching priority group. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz> Message-Id: <20240317184154.1200192-7-amir73il@gmail.com>
This commit is contained in:
parent
687c217c6a
commit
c9d4603b05
@ -154,20 +154,23 @@ static void fsnotify_put_inode_ref(struct inode *inode)
|
||||
iput(inode);
|
||||
}
|
||||
|
||||
static void fsnotify_get_sb_watchers(struct fsnotify_mark_connector *conn)
|
||||
/*
|
||||
* Grab or drop watched objects reference depending on whether the connector
|
||||
* is attached and has any marks attached.
|
||||
*/
|
||||
static void fsnotify_update_sb_watchers(struct super_block *sb,
|
||||
struct fsnotify_mark_connector *conn)
|
||||
{
|
||||
struct super_block *sb = fsnotify_connector_sb(conn);
|
||||
bool is_watched = conn->flags & FSNOTIFY_CONN_FLAG_IS_WATCHED;
|
||||
bool has_marks = conn->obj && !hlist_empty(&conn->list);
|
||||
|
||||
if (sb)
|
||||
if (has_marks && !is_watched) {
|
||||
conn->flags |= FSNOTIFY_CONN_FLAG_IS_WATCHED;
|
||||
fsnotify_get_sb_watched_objects(sb);
|
||||
}
|
||||
|
||||
static void fsnotify_put_sb_watchers(struct fsnotify_mark_connector *conn)
|
||||
{
|
||||
struct super_block *sb = fsnotify_connector_sb(conn);
|
||||
|
||||
if (sb)
|
||||
} else if (!has_marks && is_watched) {
|
||||
conn->flags &= ~FSNOTIFY_CONN_FLAG_IS_WATCHED;
|
||||
fsnotify_put_sb_watched_objects(sb);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -266,6 +269,7 @@ static void *fsnotify_detach_connector_from_object(
|
||||
unsigned int *type)
|
||||
{
|
||||
fsnotify_connp_t *connp = fsnotify_object_connp(conn->obj, conn->type);
|
||||
struct super_block *sb = fsnotify_connector_sb(conn);
|
||||
struct inode *inode = NULL;
|
||||
|
||||
*type = conn->type;
|
||||
@ -285,10 +289,10 @@ static void *fsnotify_detach_connector_from_object(
|
||||
fsnotify_conn_sb(conn)->s_fsnotify_mask = 0;
|
||||
}
|
||||
|
||||
fsnotify_put_sb_watchers(conn);
|
||||
rcu_assign_pointer(*connp, NULL);
|
||||
conn->obj = NULL;
|
||||
conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
|
||||
fsnotify_update_sb_watchers(sb, conn);
|
||||
|
||||
return inode;
|
||||
}
|
||||
@ -340,6 +344,11 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
|
||||
objp = fsnotify_detach_connector_from_object(conn, &type);
|
||||
free_conn = true;
|
||||
} else {
|
||||
struct super_block *sb = fsnotify_connector_sb(conn);
|
||||
|
||||
/* Update watched objects after detaching mark */
|
||||
if (sb)
|
||||
fsnotify_update_sb_watchers(sb, conn);
|
||||
objp = __fsnotify_recalc_mask(conn);
|
||||
type = conn->type;
|
||||
}
|
||||
@ -581,10 +590,7 @@ static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp,
|
||||
if (cmpxchg(connp, NULL, conn)) {
|
||||
/* Someone else created list structure for us */
|
||||
kmem_cache_free(fsnotify_mark_connector_cachep, conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fsnotify_get_sb_watchers(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -624,6 +630,7 @@ out:
|
||||
static int fsnotify_add_mark_list(struct fsnotify_mark *mark, void *obj,
|
||||
unsigned int obj_type, int add_flags)
|
||||
{
|
||||
struct super_block *sb = fsnotify_object_sb(obj, obj_type);
|
||||
struct fsnotify_mark *lmark, *last = NULL;
|
||||
struct fsnotify_mark_connector *conn;
|
||||
fsnotify_connp_t *connp;
|
||||
@ -673,6 +680,7 @@ restart:
|
||||
/* mark should be the last entry. last is the current last entry */
|
||||
hlist_add_behind_rcu(&mark->obj_list, &last->obj_list);
|
||||
added:
|
||||
fsnotify_update_sb_watchers(sb, conn);
|
||||
/*
|
||||
* Since connector is attached to object using cmpxchg() we are
|
||||
* guaranteed that connector initialization is fully visible by anyone
|
||||
|
@ -465,6 +465,7 @@ FSNOTIFY_ITER_FUNCS(sb, SB)
|
||||
struct fsnotify_mark_connector {
|
||||
spinlock_t lock;
|
||||
unsigned short type; /* Type of object [lock] */
|
||||
#define FSNOTIFY_CONN_FLAG_IS_WATCHED 0x01
|
||||
#define FSNOTIFY_CONN_FLAG_HAS_IREF 0x02
|
||||
unsigned short flags; /* flags [lock] */
|
||||
union {
|
||||
|
Loading…
Reference in New Issue
Block a user