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 <[email protected]> --- 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 */ -- 2.28.0 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
