Skip to content

Commit d2f277e

Browse files
amir73iljankara
authored andcommitted
fsnotify: rename fsnotify_{get,put}_sb_connectors()
Instead of counting the number of connectors in an sb, we would like to count the number of watched objects per priority group. As a start, create an accessor fsnotify_sb_watched_objects() to s_fsnotify_connectors and rename the fsnotify_{get,put}_sb_connectors() helpers to fsnotify_{get,put}_sb_watchers() to better describes the counter. Increment the counter at the end of fsnotify_attach_connector_to_object() if connector was attached instead of decrementing it on race to connect. This is fine, because fsnotify_delete_sb() cannot be running in parallel to fsnotify_attach_connector_to_object() which requires a reference to a filesystem object. Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]> Message-Id: <[email protected]>
1 parent 4d69c58 commit d2f277e

File tree

4 files changed

+45
-33
lines changed

4 files changed

+45
-33
lines changed

fs/notify/fsnotify.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ void fsnotify_sb_delete(struct super_block *sb)
9292
fsnotify_unmount_inodes(sb);
9393
fsnotify_clear_marks_by_sb(sb);
9494
/* Wait for outstanding object references from connectors */
95-
wait_var_event(&sb->s_fsnotify_connectors,
96-
!atomic_long_read(&sb->s_fsnotify_connectors));
95+
wait_var_event(fsnotify_sb_watched_objects(sb),
96+
!atomic_long_read(fsnotify_sb_watched_objects(sb)));
9797
}
9898

9999
/*

fs/notify/mark.c

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,43 @@ __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn)
116116
return *fsnotify_conn_mask_p(conn);
117117
}
118118

119+
static void fsnotify_get_sb_watched_objects(struct super_block *sb)
120+
{
121+
atomic_long_inc(fsnotify_sb_watched_objects(sb));
122+
}
123+
124+
static void fsnotify_put_sb_watched_objects(struct super_block *sb)
125+
{
126+
if (atomic_long_dec_and_test(fsnotify_sb_watched_objects(sb)))
127+
wake_up_var(fsnotify_sb_watched_objects(sb));
128+
}
129+
119130
static void fsnotify_get_inode_ref(struct inode *inode)
120131
{
121132
ihold(inode);
122-
atomic_long_inc(&inode->i_sb->s_fsnotify_connectors);
133+
fsnotify_get_sb_watched_objects(inode->i_sb);
134+
}
135+
136+
static void fsnotify_put_inode_ref(struct inode *inode)
137+
{
138+
fsnotify_put_sb_watched_objects(inode->i_sb);
139+
iput(inode);
140+
}
141+
142+
static void fsnotify_get_sb_watchers(struct fsnotify_mark_connector *conn)
143+
{
144+
struct super_block *sb = fsnotify_connector_sb(conn);
145+
146+
if (sb)
147+
fsnotify_get_sb_watched_objects(sb);
148+
}
149+
150+
static void fsnotify_put_sb_watchers(struct fsnotify_mark_connector *conn)
151+
{
152+
struct super_block *sb = fsnotify_connector_sb(conn);
153+
154+
if (sb)
155+
fsnotify_put_sb_watched_objects(sb);
123156
}
124157

125158
/*
@@ -213,31 +246,6 @@ static void fsnotify_connector_destroy_workfn(struct work_struct *work)
213246
}
214247
}
215248

216-
static void fsnotify_put_inode_ref(struct inode *inode)
217-
{
218-
struct super_block *sb = inode->i_sb;
219-
220-
iput(inode);
221-
if (atomic_long_dec_and_test(&sb->s_fsnotify_connectors))
222-
wake_up_var(&sb->s_fsnotify_connectors);
223-
}
224-
225-
static void fsnotify_get_sb_connectors(struct fsnotify_mark_connector *conn)
226-
{
227-
struct super_block *sb = fsnotify_connector_sb(conn);
228-
229-
if (sb)
230-
atomic_long_inc(&sb->s_fsnotify_connectors);
231-
}
232-
233-
static void fsnotify_put_sb_connectors(struct fsnotify_mark_connector *conn)
234-
{
235-
struct super_block *sb = fsnotify_connector_sb(conn);
236-
237-
if (sb && atomic_long_dec_and_test(&sb->s_fsnotify_connectors))
238-
wake_up_var(&sb->s_fsnotify_connectors);
239-
}
240-
241249
static void *fsnotify_detach_connector_from_object(
242250
struct fsnotify_mark_connector *conn,
243251
unsigned int *type)
@@ -261,7 +269,7 @@ static void *fsnotify_detach_connector_from_object(
261269
fsnotify_conn_sb(conn)->s_fsnotify_mask = 0;
262270
}
263271

264-
fsnotify_put_sb_connectors(conn);
272+
fsnotify_put_sb_watchers(conn);
265273
rcu_assign_pointer(*(conn->obj), NULL);
266274
conn->obj = NULL;
267275
conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
@@ -549,19 +557,18 @@ static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp,
549557
conn->flags = 0;
550558
conn->type = obj_type;
551559
conn->obj = connp;
552-
conn->flags = 0;
553-
fsnotify_get_sb_connectors(conn);
554560

555561
/*
556562
* cmpxchg() provides the barrier so that readers of *connp can see
557563
* only initialized structure
558564
*/
559565
if (cmpxchg(connp, NULL, conn)) {
560566
/* Someone else created list structure for us */
561-
fsnotify_put_sb_connectors(conn);
562567
kmem_cache_free(fsnotify_mark_connector_cachep, conn);
568+
return 0;
563569
}
564570

571+
fsnotify_get_sb_watchers(conn);
565572
return 0;
566573
}
567574

include/linux/fsnotify.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
/* Are there any inode/mount/sb objects that are being watched at all? */
2121
static inline bool fsnotify_sb_has_watchers(struct super_block *sb)
2222
{
23-
return atomic_long_read(&sb->s_fsnotify_connectors);
23+
return atomic_long_read(fsnotify_sb_watched_objects(sb));
2424
}
2525

2626
/*

include/linux/fsnotify_backend.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,11 @@ struct fsnotify_mark_connector {
483483
struct hlist_head list;
484484
};
485485

486+
static inline atomic_long_t *fsnotify_sb_watched_objects(struct super_block *sb)
487+
{
488+
return &sb->s_fsnotify_connectors;
489+
}
490+
486491
/*
487492
* A mark is simply an object attached to an in core inode which allows an
488493
* fsnotify listener to indicate they are either no longer interested in events

0 commit comments

Comments
 (0)