aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/notify/inode_mark.c2
-rw-r--r--fs/notify/mark.c11
-rw-r--r--fs/notify/vfsmount_mark.c2
-rw-r--r--include/linux/fsnotify_backend.h1
4 files changed, 10 insertions, 6 deletions
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 455cb41c729b..37b460f302b7 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,
187 struct hlist_node *node, *last = NULL; 187 struct hlist_node *node, *last = NULL;
188 int ret = 0; 188 int ret = 0;
189 189
190 mark->flags = FSNOTIFY_MARK_FLAG_INODE; 190 mark->flags |= FSNOTIFY_MARK_FLAG_INODE;
191 191
192 assert_spin_locked(&mark->lock); 192 assert_spin_locked(&mark->lock);
193 assert_spin_locked(&group->mark_lock); 193 assert_spin_locked(&group->mark_lock);
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 8f3b0e7a543d..69c5a166930c 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -121,12 +121,14 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
121 121
122 group = mark->group; 122 group = mark->group;
123 123
124 /* if !group something else already marked this to die */ 124 /* something else already called this function on this mark */
125 if (!group) { 125 if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) {
126 spin_unlock(&mark->lock); 126 spin_unlock(&mark->lock);
127 return; 127 return;
128 } 128 }
129 129
130 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
131
130 /* 1 from caller and 1 for being on i_list/g_list */ 132 /* 1 from caller and 1 for being on i_list/g_list */
131 BUG_ON(atomic_read(&mark->refcnt) < 2); 133 BUG_ON(atomic_read(&mark->refcnt) < 2);
132 134
@@ -141,7 +143,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
141 BUG(); 143 BUG();
142 144
143 list_del_init(&mark->g_list); 145 list_del_init(&mark->g_list);
144 mark->group = NULL;
145 146
146 fsnotify_put_mark(mark); /* for i_list and g_list */ 147 fsnotify_put_mark(mark); /* for i_list and g_list */
147 148
@@ -229,6 +230,8 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
229 spin_lock(&mark->lock); 230 spin_lock(&mark->lock);
230 spin_lock(&group->mark_lock); 231 spin_lock(&group->mark_lock);
231 232
233 mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE;
234
232 mark->group = group; 235 mark->group = group;
233 list_add(&mark->g_list, &group->marks_list); 236 list_add(&mark->g_list, &group->marks_list);
234 atomic_inc(&group->num_marks); 237 atomic_inc(&group->num_marks);
@@ -258,7 +261,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
258 261
259 return ret; 262 return ret;
260err: 263err:
261 mark->group = NULL; 264 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
262 list_del_init(&mark->g_list); 265 list_del_init(&mark->g_list);
263 atomic_dec(&group->num_marks); 266 atomic_dec(&group->num_marks);
264 fsnotify_put_mark(mark); 267 fsnotify_put_mark(mark);
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c
index b7ae64030021..56772b578fbd 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,
145 struct hlist_node *node, *last = NULL; 145 struct hlist_node *node, *last = NULL;
146 int ret = 0; 146 int ret = 0;
147 147
148 mark->flags = FSNOTIFY_MARK_FLAG_VFSMOUNT; 148 mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT;
149 149
150 assert_spin_locked(&mark->lock); 150 assert_spin_locked(&mark->lock);
151 assert_spin_locked(&group->mark_lock); 151 assert_spin_locked(&group->mark_lock);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 3410d388163e..8e24cdf72928 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -300,6 +300,7 @@ struct fsnotify_mark {
300#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02 300#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02
301#define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04 301#define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04
302#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08 302#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08
303#define FSNOTIFY_MARK_FLAG_ALIVE 0x10
303 unsigned int flags; /* vfsmount or inode mark? */ 304 unsigned int flags; /* vfsmount or inode mark? */
304 void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */ 305 void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
305}; 306};