[Devel] [PATCH RHEL8 COMMIT] ve/sync/mounts: skip cursor mounts when iterating over mnt_ns->list
Konstantin Khorenko
khorenko at virtuozzo.com
Fri Jul 16 20:46:22 MSK 2021
The commit is pushed to "branch-rh8-4.18.0-305.3.1.vz8.7.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-305.3.1.el8
------>
commit ad666a87ebe9b78bee0fb808b0650e6020329653
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date: Fri Jul 16 20:46:21 2021 +0300
ve/sync/mounts: skip cursor mounts when iterating over mnt_ns->list
After RHEL ported "proc/mounts: add cursor" we need to iterate over
mounts list in mntns more carefully:
- Export mnt_list_next and move it out from CONFIG_PROC_FS;
- Use mnt_list_next in sync_collect_filesystems to skip cursors.
Otherwise kernel would break at dereferencing something from
uninitialized cursor mount.
https://jira.sw.ru/browse/PSBM-131158
Fixes: e92dd8564eab ("ve/fs/sync: Per containter sync and syncfs and
fs.fsync-enable sysctl")
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
fs/namespace.c | 6 +++---
fs/sync.c | 7 +++++--
include/linux/fs.h | 4 ++++
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index f38b5d70c4d7..9128029f5a78 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1320,9 +1320,8 @@ struct vfsmount *mnt_clone_internal(const struct path *path)
return &p->mnt;
}
-#ifdef CONFIG_PROC_FS
-static struct mount *mnt_list_next(struct mnt_namespace *ns,
- struct list_head *p)
+struct mount *mnt_list_next(struct mnt_namespace *ns,
+ struct list_head *p)
{
struct mount *mnt, *ret = NULL;
@@ -1339,6 +1338,7 @@ static struct mount *mnt_list_next(struct mnt_namespace *ns,
return ret;
}
+#ifdef CONFIG_PROC_FS
/* iterator; we want it to have access to namespace_sem, thus here... */
static void *m_start(struct seq_file *m, loff_t *pos)
{
diff --git a/fs/sync.c b/fs/sync.c
index 5a4fab629931..dc38126dbdd5 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -146,9 +146,10 @@ static int sync_collect_filesystems(struct ve_struct *ve, struct list_head *sync
mnt_ns = ve_ns->mnt_ns;
rcu_read_unlock();
- list_for_each_entry(mnt, &mnt_ns->list, mnt_list) {
+ mnt = mnt_list_next(mnt_ns, &mnt_ns->list);
+ while (mnt) {
if (sync_filesystem_collected(sync_list, mnt->mnt.mnt_sb))
- continue;
+ goto next;
ss = kmalloc(sizeof(*ss), GFP_KERNEL);
if (ss == NULL) {
@@ -165,6 +166,8 @@ static int sync_collect_filesystems(struct ve_struct *ve, struct list_head *sync
ss->sb->s_count++;
spin_unlock(&sb_lock);
list_add_tail(&ss->list, sync_list);
+next:
+ mnt = mnt_list_next(mnt_ns, &mnt->mnt_list);
}
up_read(&namespace_sem);
return ret;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 11e014939b74..f9ce9d3d8b2b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -67,6 +67,7 @@ struct fscrypt_info;
struct fscrypt_operations;
struct fs_context;
struct fs_parameter_spec;
+struct mnt_namespace;
extern void __init inode_init(void);
extern void __init inode_init_early(void);
@@ -3392,6 +3393,9 @@ extern void setattr_copy(struct inode *inode, const struct iattr *attr);
extern int file_update_time(struct file *file);
+extern struct mount *mnt_list_next(struct mnt_namespace *ns,
+ struct list_head *p);
+
static inline bool vma_is_dax(const struct vm_area_struct *vma)
{
return vma->vm_file && IS_DAX(vma->vm_file->f_mapping->host);
More information about the Devel
mailing list