[Devel] [PATCH rh7] ve/fs/sync: fix CT's mountpoints traversal

Andrey Ryabinin aryabinin at virtuozzo.com
Wed Feb 24 07:36:22 PST 2016


Currently sync reads 've->root_path.mnt' mount and iterate over it childs.
This doesn't work, as not all in-container mounts could be reached that way.

This patch slightly rework's mounts traversal. Now sync just iterates over all
mounts of current mount namespace (actually we iterate over all mounts that
seen in container's /proc/mounts). This approach seems much more correct and
also simpler.

I think we could get rid of 've->root_path' now.

https://jira.sw.ru/browse/PSBM-44125

Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 fs/mount.h     |  1 -
 fs/namespace.c |  2 +-
 fs/sync.c      | 18 +++++++-----------
 3 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/fs/mount.h b/fs/mount.h
index b496064..013152b 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -71,7 +71,6 @@ static inline int is_mounted(struct vfsmount *mnt)
 }
 
 extern struct rw_semaphore namespace_sem;
-extern struct mount *next_mnt(struct mount *p, struct mount *root);
 
 extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
 
diff --git a/fs/namespace.c b/fs/namespace.c
index fa9ee9e..787619b 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -756,7 +756,7 @@ static void commit_tree(struct mount *mnt)
 	touch_mnt_namespace(n);
 }
 
-struct mount *next_mnt(struct mount *p, struct mount *root)
+static struct mount *next_mnt(struct mount *p, struct mount *root)
 {
 	struct list_head *next = p->mnt_mounts.next;
 	if (next == &p->mnt_mounts) {
diff --git a/fs/sync.c b/fs/sync.c
index 8119ab4..9242a60 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -127,17 +127,17 @@ static int sync_filesystem_collected(struct list_head *sync_list, struct super_b
 	return 0;
 }
 
-static int sync_collect_filesystems(struct ve_struct *ve, struct list_head *sync_list)
+static int sync_collect_filesystems(struct list_head *sync_list)
 {
-	struct mount *root = real_mount(ve->root_path.mnt);
 	struct mount *mnt;
+	struct mnt_namespace *mnt_ns = current->nsproxy->mnt_ns;
 	struct sync_sb *ss;
 	int ret = 0;
 
 	BUG_ON(!list_empty(sync_list));
 
 	down_read(&namespace_sem);
-	for (mnt = root; mnt; mnt = next_mnt(mnt, root)) {
+	list_for_each_entry(mnt, &mnt_ns->list, mnt_list) {
 		if (sync_filesystem_collected(sync_list, mnt->mnt.mnt_sb))
 			continue;
 
@@ -161,20 +161,18 @@ static int sync_collect_filesystems(struct ve_struct *ve, struct list_head *sync
 	return ret;
 }
 
-static void sync_filesystems_ve(struct ve_struct *ve, struct user_beancounter *ub, int wait)
+static void sync_filesystems_ub(struct user_beancounter *ub, int wait)
 {
 	struct super_block *sb;
 	LIST_HEAD(sync_list);
 	struct sync_sb *ss;
 
-	mutex_lock(&ve->sync_mutex);		/* Could be down_interruptible */
-
 	/*
 	 * We don't need to care about allocating failure here. At least we
 	 * don't need to skip sync on such error.
 	 * Let's sync what we collected already instead.
 	 */
-	sync_collect_filesystems(ve, &sync_list);
+	sync_collect_filesystems(&sync_list);
 
 	list_for_each_entry(ss, &sync_list, list) {
 		sb = ss->sb;
@@ -185,8 +183,6 @@ static void sync_filesystems_ve(struct ve_struct *ve, struct user_beancounter *u
 	}
 
 	sync_release_filesystems(&sync_list);
-
-	mutex_unlock(&ve->sync_mutex);
 }
 
 static int __ve_fsync_behavior(struct ve_struct *ve)
@@ -250,8 +246,8 @@ SYSCALL_DEFINE0(sync)
 
 		if (sync_ub && (sync_ub != get_ub0())) {
 			wakeup_flusher_threads_ub(0, sync_ub, WB_REASON_SYNC);
-			sync_filesystems_ve(get_exec_env(), sync_ub, nowait);
-			sync_filesystems_ve(get_exec_env(), sync_ub, wait);
+			sync_filesystems_ub(sync_ub, nowait);
+			sync_filesystems_ub(sync_ub, wait);
 			goto skip;
 		}
 	}
-- 
2.4.10



More information about the Devel mailing list