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>
struct hlist_node *node, *last = NULL;
int ret = 0;
struct hlist_node *node, *last = NULL;
int ret = 0;
- mark->flags = FSNOTIFY_MARK_FLAG_INODE;
+ mark->flags |= FSNOTIFY_MARK_FLAG_INODE;
assert_spin_locked(&mark->lock);
assert_spin_locked(&group->mark_lock);
assert_spin_locked(&mark->lock);
assert_spin_locked(&group->mark_lock);
- /* if !group something else already marked this to die */
- if (!group) {
+ /* something else already called this function on this mark */
+ if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) {
spin_unlock(&mark->lock);
return;
}
spin_unlock(&mark->lock);
return;
}
+ mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
+
/* 1 from caller and 1 for being on i_list/g_list */
BUG_ON(atomic_read(&mark->refcnt) < 2);
/* 1 from caller and 1 for being on i_list/g_list */
BUG_ON(atomic_read(&mark->refcnt) < 2);
BUG();
list_del_init(&mark->g_list);
BUG();
list_del_init(&mark->g_list);
fsnotify_put_mark(mark); /* for i_list and g_list */
fsnotify_put_mark(mark); /* for i_list and g_list */
spin_lock(&mark->lock);
spin_lock(&group->mark_lock);
spin_lock(&mark->lock);
spin_lock(&group->mark_lock);
+ mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE;
+
mark->group = group;
list_add(&mark->g_list, &group->marks_list);
atomic_inc(&group->num_marks);
mark->group = group;
list_add(&mark->g_list, &group->marks_list);
atomic_inc(&group->num_marks);
+ mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
list_del_init(&mark->g_list);
atomic_dec(&group->num_marks);
fsnotify_put_mark(mark);
list_del_init(&mark->g_list);
atomic_dec(&group->num_marks);
fsnotify_put_mark(mark);
struct hlist_node *node, *last = NULL;
int ret = 0;
struct hlist_node *node, *last = NULL;
int ret = 0;
- mark->flags = FSNOTIFY_MARK_FLAG_VFSMOUNT;
+ mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT;
assert_spin_locked(&mark->lock);
assert_spin_locked(&group->mark_lock);
assert_spin_locked(&mark->lock);
assert_spin_locked(&group->mark_lock);
#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02
#define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04
#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08
#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02
#define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04
#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08
+#define FSNOTIFY_MARK_FLAG_ALIVE 0x10
unsigned int flags; /* vfsmount or inode mark? */
void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
};
unsigned int flags; /* vfsmount or inode mark? */
void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
};