From: Eric Paris Date: Wed, 28 Jul 2010 14:18:38 +0000 (-0400) Subject: fsnotify: use an explicit flag to indicate fsnotify_destroy_mark has been called X-Git-Tag: v2.6.36-rc1~303^2~15 X-Git-Url: https://bbs.cooldavid.org/git/?p=net-next-2.6.git;a=commitdiff_plain;h=700307a29ad61090dcf1d45f8f4a135f5e9211ae 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 --- diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index 455cb41c729..37b460f302b 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c @@ -187,7 +187,7 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark, 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); diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 8f3b0e7a543..69c5a166930 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -121,12 +121,14 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark) group = mark->group; - /* 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; } + 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); @@ -141,7 +143,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark) BUG(); list_del_init(&mark->g_list); - mark->group = NULL; 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(&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); @@ -258,7 +261,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, return ret; err: - mark->group = NULL; + mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; list_del_init(&mark->g_list); atomic_dec(&group->num_marks); fsnotify_put_mark(mark); diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c index b7ae6403002..56772b578fb 100644 --- a/fs/notify/vfsmount_mark.c +++ b/fs/notify/vfsmount_mark.c @@ -145,7 +145,7 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark, 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); diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 3410d388163..8e24cdf7292 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -300,6 +300,7 @@ struct fsnotify_mark { #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 */ };