summary refs log tree commit diff
path: root/fs/notify/mark.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2017-03-15 09:48:11 +0100
committerJan Kara <jack@suse.cz>2017-04-10 17:37:35 +0200
commit8212a6097a720896b4cdbe516487ad47f4296599 (patch)
treec598677214226244c7db2b90be6f2715cfbf38eb /fs/notify/mark.c
parenta03e2e4f078365428bb4317989cb5d1d6563cfe9 (diff)
downloadlinux-8212a6097a720896b4cdbe516487ad47f4296599.tar.gz
fsnotify: Remove indirection from fsnotify_detach_mark()
fsnotify_detach_mark() calls fsnotify_destroy_inode_mark() or
fsnotify_destroy_vfsmount_mark() to remove mark from object list. These
two functions are however very similar and differ only in the lock they
use to protect the object list of marks. Simplify the code by removing
the indirection and removing mark from the object list in a common
function.

Reviewed-by: Miklos Szeredi <mszeredi@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify/mark.c')
-rw-r--r--fs/notify/mark.c32
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