[Devel] [PATCH RHEL8 COMMIT] Revert "ms/proc/mounts: add cursor"

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jul 15 16:28:00 MSK 2021


The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.55
------>
commit 1cd24b362444b0fae9afedaeefa6202395c98845
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date:   Fri Jul 9 14:54:22 2021 +0300

    Revert "ms/proc/mounts: add cursor"
    
    This reverts commit 2e01d45a2a2dbfa302b387584474645172b7c5bd.
    
    There is another version of this patch in vz7 3.10.0-1160.15.2.vz7.173.8
    kernel, so we revert the current (old and wrong) one, will cherry-pick
    v2 in following patch.
    
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 fs/mount.h            | 14 ++------
 fs/namespace.c        | 92 ++++++++++-----------------------------------------
 fs/proc_namespace.c   |  4 +--
 fs/sync.c             |  5 ---
 include/linux/mount.h |  4 +--
 5 files changed, 22 insertions(+), 97 deletions(-)

diff --git a/fs/mount.h b/fs/mount.h
index 66b863fa3db0..9225fc7bce30 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -9,13 +9,7 @@ struct mnt_namespace {
 	atomic_t		count;
 	struct ns_common	ns;
 	struct mount *	root;
-	/*
-	 * Traversal and modification of .list is protected by either
-	 * - taking namespace_sem for write, OR
-	 * - taking namespace_sem for read AND taking .ns_lock.
-	 */
 	struct list_head	list;
-	spinlock_t              ns_lock;
 	struct user_namespace	*user_ns;
 	struct ucounts		*ucounts;
 	u64			seq;	/* Sequence number to prevent loops */
@@ -143,13 +137,12 @@ struct proc_mounts {
 	struct mnt_namespace *ns;
 	struct path root;
 	int (*show)(struct seq_file *, struct vfsmount *);
-	struct mount cursor;
+	void *cached_mount;
+	u64 cached_event;
+	loff_t cached_index;
 };
 
 extern const struct seq_operations mounts_op;
-extern inline void lock_ns_list(struct mnt_namespace *ns);
-extern inline void unlock_ns_list(struct mnt_namespace *ns);
-extern inline bool mnt_is_cursor(struct mount *mnt);
 
 extern bool __is_local_mountpoint(struct dentry *dentry);
 static inline bool is_local_mountpoint(struct dentry *dentry)
@@ -164,4 +157,3 @@ static inline bool is_anon_ns(struct mnt_namespace *ns)
 {
 	return ns->seq == 0;
 }
-extern void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor);
diff --git a/fs/namespace.c b/fs/namespace.c
index 321a79198aac..cdeb83740de5 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -671,21 +671,6 @@ struct vfsmount *lookup_mnt(const struct path *path)
 	return m;
 }
 
-inline void lock_ns_list(struct mnt_namespace *ns)
-{
-	spin_lock(&ns->ns_lock);
-}
-
-inline void unlock_ns_list(struct mnt_namespace *ns)
-{
-	spin_unlock(&ns->ns_lock);
-}
-
-inline bool mnt_is_cursor(struct mount *mnt)
-{
-	return mnt->mnt.mnt_flags & MNT_CURSOR;
-}
-
 /*
  * __is_local_mountpoint - Test to see if dentry is a mountpoint in the
  *                         current mount namespace.
@@ -711,15 +696,11 @@ bool __is_local_mountpoint(struct dentry *dentry)
 		goto out;
 
 	down_read(&namespace_sem);
-	lock_ns_list(ns);
 	list_for_each_entry(mnt, &ns->list, mnt_list) {
-		if (mnt_is_cursor(mnt))
-			continue;
 		is_covered = (mnt->mnt_mountpoint == dentry);
 		if (is_covered)
 			break;
 	}
-	unlock_ns_list(ns);
 	up_read(&namespace_sem);
 out:
 	return is_covered;
@@ -1299,70 +1280,46 @@ struct vfsmount *mnt_clone_internal(const struct path *path)
 }
 
 #ifdef CONFIG_PROC_FS
-static struct mount *mnt_list_next(struct mnt_namespace *ns,
-				   struct list_head *p)
-{
-	struct mount *mnt, *ret = NULL;
-
-	lock_ns_list(ns);
-	list_for_each_continue(p, &ns->list) {
-		mnt = list_entry(p, typeof(*mnt), mnt_list);
-		if (!mnt_is_cursor(mnt)) {
-			ret = mnt;
-			break;
-		}
-	}
-	unlock_ns_list(ns);
-
-	return ret;
-}
-
 /* iterator; we want it to have access to namespace_sem, thus here... */
 static void *m_start(struct seq_file *m, loff_t *pos)
 {
 	struct proc_mounts *p = m->private;
-	struct list_head *prev;
 
 	down_read(&namespace_sem);
-	if (!*pos) {
-		prev = &p->ns->list;
-	} else {
-		prev = &p->cursor.mnt_list;
-
-		/* Read after we'd reached the end? */
-		if (list_empty(prev))
-			return NULL;
+	if (p->cached_event == p->ns->event) {
+		void *v = p->cached_mount;
+		if (*pos == p->cached_index)
+			return v;
+		if (*pos == p->cached_index + 1) {
+			v = seq_list_next(v, &p->ns->list, &p->cached_index);
+			return p->cached_mount = v;
+		}
 	}
-	return mnt_list_next(p->ns, prev);
+
+	p->cached_event = p->ns->event;
+	p->cached_mount = seq_list_start(&p->ns->list, *pos);
+	p->cached_index = *pos;
+	return p->cached_mount;
 }
 
 static void *m_next(struct seq_file *m, void *v, loff_t *pos)
 {
 	struct proc_mounts *p = m->private;
-	struct mount *mnt = v;
 
-	++*pos;
-	return mnt_list_next(p->ns, &mnt->mnt_list);
+	p->cached_mount = seq_list_next(v, &p->ns->list, pos);
+	p->cached_index = *pos;
+	return p->cached_mount;
 }
 
 static void m_stop(struct seq_file *m, void *v)
 {
-	struct proc_mounts *p = m->private;
-	struct mount *mnt = v;
-
-	lock_ns_list(p->ns);
-	if (mnt)
-		list_move_tail(&p->cursor.mnt_list, &mnt->mnt_list);
-	else
-		list_del_init(&p->cursor.mnt_list);
-	unlock_ns_list(p->ns);
 	up_read(&namespace_sem);
 }
 
 static int m_show(struct seq_file *m, void *v)
 {
 	struct proc_mounts *p = m->private;
-	struct mount *r = v;
+	struct mount *r = list_entry(v, struct mount, mnt_list);
 	return p->show(m, &r->mnt);
 }
 
@@ -1372,15 +1329,6 @@ const struct seq_operations mounts_op = {
 	.stop	= m_stop,
 	.show	= m_show,
 };
-
-void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor)
-{
-	down_read(&namespace_sem);
-	lock_ns_list(ns);
-	list_del(&cursor->mnt_list);
-	unlock_ns_list(ns);
-	up_read(&namespace_sem);
-}
 #endif  /* CONFIG_PROC_FS */
 
 /**
@@ -3363,7 +3311,6 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, bool a
 	INIT_LIST_HEAD(&new_ns->list);
 	INIT_LIST_HEAD(&new_ns->mntns_list);
 	init_waitqueue_head(&new_ns->poll);
-	spin_lock_init(&new_ns->ns_lock);
 	new_ns->user_ns = get_user_ns(user_ns);
 	new_ns->ucounts = ucounts;
 	return new_ns;
@@ -3876,14 +3823,10 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new,
 	bool visible = false;
 
 	down_read(&namespace_sem);
-	lock_ns_list(ns);
 	list_for_each_entry(mnt, &ns->list, mnt_list) {
 		struct mount *child;
 		int mnt_flags;
 
-		if (mnt_is_cursor(mnt))
-			continue;
-
 		if (mnt->mnt.mnt_sb->s_type != new->mnt_sb->s_type)
 			continue;
 
@@ -3931,7 +3874,6 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new,
 	next:	;
 	}
 found:
-	unlock_ns_list(ns);
 	up_read(&namespace_sem);
 	return visible;
 }
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c
index 969f9c8fbdc0..e16fb8f2049e 100644
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -279,8 +279,7 @@ static int mounts_open_common(struct inode *inode, struct file *file,
 	p->ns = ns;
 	p->root = root;
 	p->show = show;
-	INIT_LIST_HEAD(&p->cursor.mnt_list);
-	p->cursor.mnt.mnt_flags = MNT_CURSOR;
+	p->cached_event = ~0ULL;
 
 	return 0;
 
@@ -297,7 +296,6 @@ static int mounts_release(struct inode *inode, struct file *file)
 	struct seq_file *m = file->private_data;
 	struct proc_mounts *p = m->private;
 	path_put(&p->root);
-	mnt_cursor_del(p->ns, &p->cursor);
 	put_mnt_ns(p->ns);
 	return seq_release_private(inode, file);
 }
diff --git a/fs/sync.c b/fs/sync.c
index 75a1e019ee7c..ef4b1d17fe5a 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -134,11 +134,7 @@ static int sync_collect_filesystems(struct ve_struct *ve, struct list_head *sync
 	BUG_ON(!list_empty(sync_list));
 
 	down_read(&namespace_sem);
-	lock_ns_list(mnt_ns);
 	list_for_each_entry(mnt, &mnt_ns->list, mnt_list) {
-		if (mnt_is_cursor(mnt))
-			continue;
-
 		if (sync_filesystem_collected(sync_list, mnt->mnt.mnt_sb))
 			continue;
 
@@ -158,7 +154,6 @@ static int sync_collect_filesystems(struct ve_struct *ve, struct list_head *sync
 		spin_unlock(&sb_lock);
 		list_add_tail(&ss->list, sync_list);
 	}
-	unlock_ns_list(mnt_ns);
 	up_read(&namespace_sem);
 	return ret;
 }
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 5316b60e9028..45b1f56c6c2f 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -49,8 +49,7 @@ struct mnt_namespace;
 #define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME )
 
 #define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \
-			    MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED | \
-			    MNT_CURSOR)
+			    MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED)
 
 #define MNT_INTERNAL	0x4000
 
@@ -64,7 +63,6 @@ struct mnt_namespace;
 #define MNT_SYNC_UMOUNT		0x2000000
 #define MNT_MARKED		0x4000000
 #define MNT_UMOUNT		0x8000000
-#define MNT_CURSOR		0x10000000
 
 struct vfsmount {
 	struct dentry *mnt_root;	/* root of the mounted tree */


More information about the Devel mailing list