fsnotify: use an explicit flag to indicate fsnotify_destroy_mark has been called
Currently fsnotify check is mark->group is NULL to decide if fsnotify_destroy_mark() has already been called or not. With the upcoming rcu work it is a heck of a lot easier to use an explicit flag than worry about group being set to NULL. Signed-off-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
@@ -187,7 +187,7 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
|
|||||||
struct hlist_node *node, *last = NULL;
|
struct hlist_node *node, *last = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mark->flags = FSNOTIFY_MARK_FLAG_INODE;
|
mark->flags |= FSNOTIFY_MARK_FLAG_INODE;
|
||||||
|
|
||||||
assert_spin_locked(&mark->lock);
|
assert_spin_locked(&mark->lock);
|
||||||
assert_spin_locked(&group->mark_lock);
|
assert_spin_locked(&group->mark_lock);
|
||||||
|
@@ -121,12 +121,14 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
|
|||||||
|
|
||||||
group = mark->group;
|
group = mark->group;
|
||||||
|
|
||||||
/* if !group something else already marked this to die */
|
/* something else already called this function on this mark */
|
||||||
if (!group) {
|
if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) {
|
||||||
spin_unlock(&mark->lock);
|
spin_unlock(&mark->lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
|
||||||
|
|
||||||
/* 1 from caller and 1 for being on i_list/g_list */
|
/* 1 from caller and 1 for being on i_list/g_list */
|
||||||
BUG_ON(atomic_read(&mark->refcnt) < 2);
|
BUG_ON(atomic_read(&mark->refcnt) < 2);
|
||||||
|
|
||||||
@@ -141,7 +143,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
|
|||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
list_del_init(&mark->g_list);
|
list_del_init(&mark->g_list);
|
||||||
mark->group = NULL;
|
|
||||||
|
|
||||||
fsnotify_put_mark(mark); /* for i_list and g_list */
|
fsnotify_put_mark(mark); /* for i_list and g_list */
|
||||||
|
|
||||||
@@ -229,6 +230,8 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
|
|||||||
spin_lock(&mark->lock);
|
spin_lock(&mark->lock);
|
||||||
spin_lock(&group->mark_lock);
|
spin_lock(&group->mark_lock);
|
||||||
|
|
||||||
|
mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE;
|
||||||
|
|
||||||
mark->group = group;
|
mark->group = group;
|
||||||
list_add(&mark->g_list, &group->marks_list);
|
list_add(&mark->g_list, &group->marks_list);
|
||||||
atomic_inc(&group->num_marks);
|
atomic_inc(&group->num_marks);
|
||||||
@@ -258,7 +261,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
err:
|
err:
|
||||||
mark->group = NULL;
|
mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
|
||||||
list_del_init(&mark->g_list);
|
list_del_init(&mark->g_list);
|
||||||
atomic_dec(&group->num_marks);
|
atomic_dec(&group->num_marks);
|
||||||
fsnotify_put_mark(mark);
|
fsnotify_put_mark(mark);
|
||||||
|
@@ -145,7 +145,7 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
|
|||||||
struct hlist_node *node, *last = NULL;
|
struct hlist_node *node, *last = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mark->flags = FSNOTIFY_MARK_FLAG_VFSMOUNT;
|
mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT;
|
||||||
|
|
||||||
assert_spin_locked(&mark->lock);
|
assert_spin_locked(&mark->lock);
|
||||||
assert_spin_locked(&group->mark_lock);
|
assert_spin_locked(&group->mark_lock);
|
||||||
|
@@ -300,6 +300,7 @@ struct fsnotify_mark {
|
|||||||
#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
|
||||||
unsigned int flags; /* vfsmount or inode mark? */
|
unsigned int flags; /* vfsmount or inode mark? */
|
||||||
void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
|
void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user