Skip to content

Commit d6f7b98

Browse files
amir73iljankara
authored andcommitted
fsnotify: use type id to identify connector object type
An fsnotify_mark_connector is referencing a single type of object (either inode or vfsmount). Instead of storing a type mask in connector->flags, store a single type id in connector->type to identify the type of object. When a connector object is detached from the object, its type is set to FSNOTIFY_OBJ_TYPE_DETACHED and this object is not going to be reused. The function fsnotify_clear_marks_by_group() is the only place where type mask was used, so use type flags instead of type id to this function. This change is going to be more convenient when adding a new object type (super block). Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent 3acf4e3 commit d6f7b98

File tree

4 files changed

+32
-26
lines changed

4 files changed

+32
-26
lines changed

fs/notify/fdinfo.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
7777
struct inotify_inode_mark *inode_mark;
7878
struct inode *inode;
7979

80-
if (!(mark->connector->flags & FSNOTIFY_OBJ_TYPE_INODE))
80+
if (mark->connector->type != FSNOTIFY_OBJ_TYPE_INODE)
8181
return;
8282

8383
inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
@@ -116,7 +116,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
116116
if (mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)
117117
mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
118118

119-
if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_INODE) {
119+
if (mark->connector->type == FSNOTIFY_OBJ_TYPE_INODE) {
120120
inode = igrab(mark->connector->inode);
121121
if (!inode)
122122
return;
@@ -126,7 +126,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
126126
show_mark_fhandle(m, inode);
127127
seq_putc(m, '\n');
128128
iput(inode);
129-
} else if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
129+
} else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
130130
struct mount *mnt = real_mount(mark->connector->mnt);
131131

132132
seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",

fs/notify/group.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void fsnotify_destroy_group(struct fsnotify_group *group)
6767
fsnotify_group_stop_queueing(group);
6868

6969
/* Clear all marks for this group and queue them for destruction */
70-
fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES);
70+
fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES_MASK);
7171

7272
/*
7373
* Some marks can still be pinned when waiting for response from

fs/notify/mark.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
119119
if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
120120
new_mask |= mark->mask;
121121
}
122-
if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE)
122+
if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
123123
conn->inode->i_fsnotify_mask = new_mask;
124-
else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT)
124+
else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
125125
real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask;
126126
}
127127

@@ -139,7 +139,7 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
139139
spin_lock(&conn->lock);
140140
__fsnotify_recalc_mask(conn);
141141
spin_unlock(&conn->lock);
142-
if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE)
142+
if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
143143
__fsnotify_update_child_dentry_flags(conn->inode);
144144
}
145145

@@ -166,18 +166,18 @@ static struct inode *fsnotify_detach_connector_from_object(
166166
{
167167
struct inode *inode = NULL;
168168

169-
if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) {
169+
if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
170170
inode = conn->inode;
171171
rcu_assign_pointer(inode->i_fsnotify_marks, NULL);
172172
inode->i_fsnotify_mask = 0;
173173
conn->inode = NULL;
174-
conn->flags &= ~FSNOTIFY_OBJ_TYPE_INODE;
175-
} else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
174+
conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
175+
} else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
176176
rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify_marks,
177177
NULL);
178178
real_mount(conn->mnt)->mnt_fsnotify_mask = 0;
179179
conn->mnt = NULL;
180-
conn->flags &= ~FSNOTIFY_OBJ_TYPE_VFSMOUNT;
180+
conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
181181
}
182182

183183
return inode;
@@ -442,10 +442,10 @@ static int fsnotify_attach_connector_to_object(
442442
spin_lock_init(&conn->lock);
443443
INIT_HLIST_HEAD(&conn->list);
444444
if (inode) {
445-
conn->flags = FSNOTIFY_OBJ_TYPE_INODE;
445+
conn->type = FSNOTIFY_OBJ_TYPE_INODE;
446446
conn->inode = igrab(inode);
447447
} else {
448-
conn->flags = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
448+
conn->type = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
449449
conn->mnt = mnt;
450450
}
451451
/*
@@ -479,8 +479,7 @@ static struct fsnotify_mark_connector *fsnotify_grab_connector(
479479
if (!conn)
480480
goto out;
481481
spin_lock(&conn->lock);
482-
if (!(conn->flags & (FSNOTIFY_OBJ_TYPE_INODE |
483-
FSNOTIFY_OBJ_TYPE_VFSMOUNT))) {
482+
if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED) {
484483
spin_unlock(&conn->lock);
485484
srcu_read_unlock(&fsnotify_mark_srcu, idx);
486485
return NULL;
@@ -646,16 +645,16 @@ struct fsnotify_mark *fsnotify_find_mark(
646645
return NULL;
647646
}
648647

649-
/* Clear any marks in a group with given type */
648+
/* Clear any marks in a group with given type mask */
650649
void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
651-
unsigned int type)
650+
unsigned int type_mask)
652651
{
653652
struct fsnotify_mark *lmark, *mark;
654653
LIST_HEAD(to_free);
655654
struct list_head *head = &to_free;
656655

657656
/* Skip selection step if we want to clear all marks. */
658-
if (type == FSNOTIFY_OBJ_ALL_TYPES) {
657+
if (type_mask == FSNOTIFY_OBJ_ALL_TYPES_MASK) {
659658
head = &group->marks_list;
660659
goto clear;
661660
}
@@ -670,7 +669,7 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
670669
*/
671670
mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
672671
list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {
673-
if (mark->connector->flags & type)
672+
if ((1U << mark->connector->type) & type_mask)
674673
list_move(&mark->g_list, &to_free);
675674
}
676675
mutex_unlock(&group->mark_mutex);

include/linux/fsnotify_backend.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ struct fsnotify_group {
201201
#define FSNOTIFY_EVENT_PATH 1
202202
#define FSNOTIFY_EVENT_INODE 2
203203

204+
enum fsnotify_obj_type {
205+
FSNOTIFY_OBJ_TYPE_INODE,
206+
FSNOTIFY_OBJ_TYPE_VFSMOUNT,
207+
FSNOTIFY_OBJ_TYPE_COUNT,
208+
FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT
209+
};
210+
211+
#define FSNOTIFY_OBJ_TYPE_INODE_FL (1U << FSNOTIFY_OBJ_TYPE_INODE)
212+
#define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
213+
#define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
214+
204215
/*
205216
* Inode / vfsmount point to this structure which tracks all marks attached to
206217
* the inode / vfsmount. The reference to inode / vfsmount is held by this
@@ -209,11 +220,7 @@ struct fsnotify_group {
209220
*/
210221
struct fsnotify_mark_connector {
211222
spinlock_t lock;
212-
#define FSNOTIFY_OBJ_TYPE_INODE 0x01
213-
#define FSNOTIFY_OBJ_TYPE_VFSMOUNT 0x02
214-
#define FSNOTIFY_OBJ_ALL_TYPES (FSNOTIFY_OBJ_TYPE_INODE | \
215-
FSNOTIFY_OBJ_TYPE_VFSMOUNT)
216-
unsigned int flags; /* Type of object [lock] */
223+
unsigned int type; /* Type of object [lock] */
217224
union { /* Object pointer [lock] */
218225
struct inode *inode;
219226
struct vfsmount *mnt;
@@ -369,12 +376,12 @@ extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group, unsigned
369376
/* run all the marks in a group, and clear all of the vfsmount marks */
370377
static inline void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group)
371378
{
372-
fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT);
379+
fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL);
373380
}
374381
/* run all the marks in a group, and clear all of the inode marks */
375382
static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group)
376383
{
377-
fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE);
384+
fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL);
378385
}
379386
extern void fsnotify_get_mark(struct fsnotify_mark *mark);
380387
extern void fsnotify_put_mark(struct fsnotify_mark *mark);

0 commit comments

Comments
 (0)