diff options
Diffstat (limited to 'fs/notify/mark.c')
-rw-r--r-- | fs/notify/mark.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index f32ca924c44e..08ab7b252322 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -141,6 +141,30 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) } } +static struct inode *fsnotify_detach_from_object(struct fsnotify_mark *mark) +{ + struct fsnotify_mark_connector *conn; + struct inode *inode = NULL; + spinlock_t *lock; + + conn = mark->connector; + if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) + lock = &conn->inode->i_lock; + else + lock = &conn->mnt->mnt_root->d_lock; + spin_lock(lock); + hlist_del_init_rcu(&mark->obj_list); + if (hlist_empty(&conn->list)) { + if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) + inode = conn->inode; + } + mark->connector = NULL; + spin_unlock(lock); + fsnotify_recalc_mask(conn); + + return inode; +} + /* * Remove mark from inode / vfsmount list, group list, drop inode reference * if we got one. @@ -164,12 +188,8 @@ void fsnotify_detach_mark(struct fsnotify_mark *mark) mark->flags &= ~FSNOTIFY_MARK_FLAG_ATTACHED; - if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_INODE) - inode = fsnotify_destroy_inode_mark(mark); - else if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) - fsnotify_destroy_vfsmount_mark(mark); - else - BUG(); + inode = fsnotify_detach_from_object(mark); + /* * Note that we didn't update flags telling whether inode cares about * what's happening with children. We update these flags from |