Skip to content

Commit c9d4603

Browse files
amir73iljankara
authored andcommitted
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 <[email protected]> Signed-off-by: Jan Kara <[email protected]> Message-Id: <[email protected]>
1 parent 687c217 commit c9d4603

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

fs/notify/mark.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -154,20 +154,23 @@ static void fsnotify_put_inode_ref(struct inode *inode)
154154
iput(inode);
155155
}
156156

157-
static void fsnotify_get_sb_watchers(struct fsnotify_mark_connector *conn)
157+
/*
158+
* Grab or drop watched objects reference depending on whether the connector
159+
* is attached and has any marks attached.
160+
*/
161+
static void fsnotify_update_sb_watchers(struct super_block *sb,
162+
struct fsnotify_mark_connector *conn)
158163
{
159-
struct super_block *sb = fsnotify_connector_sb(conn);
164+
bool is_watched = conn->flags & FSNOTIFY_CONN_FLAG_IS_WATCHED;
165+
bool has_marks = conn->obj && !hlist_empty(&conn->list);
160166

161-
if (sb)
167+
if (has_marks && !is_watched) {
168+
conn->flags |= FSNOTIFY_CONN_FLAG_IS_WATCHED;
162169
fsnotify_get_sb_watched_objects(sb);
163-
}
164-
165-
static void fsnotify_put_sb_watchers(struct fsnotify_mark_connector *conn)
166-
{
167-
struct super_block *sb = fsnotify_connector_sb(conn);
168-
169-
if (sb)
170+
} else if (!has_marks && is_watched) {
171+
conn->flags &= ~FSNOTIFY_CONN_FLAG_IS_WATCHED;
170172
fsnotify_put_sb_watched_objects(sb);
173+
}
171174
}
172175

173176
/*
@@ -266,6 +269,7 @@ static void *fsnotify_detach_connector_from_object(
266269
unsigned int *type)
267270
{
268271
fsnotify_connp_t *connp = fsnotify_object_connp(conn->obj, conn->type);
272+
struct super_block *sb = fsnotify_connector_sb(conn);
269273
struct inode *inode = NULL;
270274

271275
*type = conn->type;
@@ -285,10 +289,10 @@ static void *fsnotify_detach_connector_from_object(
285289
fsnotify_conn_sb(conn)->s_fsnotify_mask = 0;
286290
}
287291

288-
fsnotify_put_sb_watchers(conn);
289292
rcu_assign_pointer(*connp, NULL);
290293
conn->obj = NULL;
291294
conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
295+
fsnotify_update_sb_watchers(sb, conn);
292296

293297
return inode;
294298
}
@@ -340,6 +344,11 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
340344
objp = fsnotify_detach_connector_from_object(conn, &type);
341345
free_conn = true;
342346
} else {
347+
struct super_block *sb = fsnotify_connector_sb(conn);
348+
349+
/* Update watched objects after detaching mark */
350+
if (sb)
351+
fsnotify_update_sb_watchers(sb, conn);
343352
objp = __fsnotify_recalc_mask(conn);
344353
type = conn->type;
345354
}
@@ -581,10 +590,7 @@ static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp,
581590
if (cmpxchg(connp, NULL, conn)) {
582591
/* Someone else created list structure for us */
583592
kmem_cache_free(fsnotify_mark_connector_cachep, conn);
584-
return 0;
585593
}
586-
587-
fsnotify_get_sb_watchers(conn);
588594
return 0;
589595
}
590596

@@ -624,6 +630,7 @@ static struct fsnotify_mark_connector *fsnotify_grab_connector(
624630
static int fsnotify_add_mark_list(struct fsnotify_mark *mark, void *obj,
625631
unsigned int obj_type, int add_flags)
626632
{
633+
struct super_block *sb = fsnotify_object_sb(obj, obj_type);
627634
struct fsnotify_mark *lmark, *last = NULL;
628635
struct fsnotify_mark_connector *conn;
629636
fsnotify_connp_t *connp;
@@ -673,6 +680,7 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark, void *obj,
673680
/* mark should be the last entry. last is the current last entry */
674681
hlist_add_behind_rcu(&mark->obj_list, &last->obj_list);
675682
added:
683+
fsnotify_update_sb_watchers(sb, conn);
676684
/*
677685
* Since connector is attached to object using cmpxchg() we are
678686
* guaranteed that connector initialization is fully visible by anyone

include/linux/fsnotify_backend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ FSNOTIFY_ITER_FUNCS(sb, SB)
465465
struct fsnotify_mark_connector {
466466
spinlock_t lock;
467467
unsigned short type; /* Type of object [lock] */
468+
#define FSNOTIFY_CONN_FLAG_IS_WATCHED 0x01
468469
#define FSNOTIFY_CONN_FLAG_HAS_IREF 0x02
469470
unsigned short flags; /* flags [lock] */
470471
union {

0 commit comments

Comments
 (0)