aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/mount.h5
-rw-r--r--fs/namespace.c21
-rw-r--r--fs/proc_namespace.c1
3 files changed, 23 insertions, 4 deletions
diff --git a/fs/mount.h b/fs/mount.h
index b29e42f05f34..d55297f2fa05 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -10,7 +10,7 @@ struct mnt_namespace {
10 struct user_namespace *user_ns; 10 struct user_namespace *user_ns;
11 u64 seq; /* Sequence number to prevent loops */ 11 u64 seq; /* Sequence number to prevent loops */
12 wait_queue_head_t poll; 12 wait_queue_head_t poll;
13 int event; 13 u64 event;
14}; 14};
15 15
16struct mnt_pcp { 16struct mnt_pcp {
@@ -104,6 +104,9 @@ struct proc_mounts {
104 struct mnt_namespace *ns; 104 struct mnt_namespace *ns;
105 struct path root; 105 struct path root;
106 int (*show)(struct seq_file *, struct vfsmount *); 106 int (*show)(struct seq_file *, struct vfsmount *);
107 void *cached_mount;
108 u64 cached_event;
109 loff_t cached_index;
107}; 110};
108 111
109#define proc_mounts(p) (container_of((p), struct proc_mounts, m)) 112#define proc_mounts(p) (container_of((p), struct proc_mounts, m))
diff --git a/fs/namespace.c b/fs/namespace.c
index 65233a5f390a..a66aff5bd3fe 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -52,7 +52,7 @@ static int __init set_mphash_entries(char *str)
52} 52}
53__setup("mphash_entries=", set_mphash_entries); 53__setup("mphash_entries=", set_mphash_entries);
54 54
55static int event; 55static u64 event;
56static DEFINE_IDA(mnt_id_ida); 56static DEFINE_IDA(mnt_id_ida);
57static DEFINE_IDA(mnt_group_ida); 57static DEFINE_IDA(mnt_group_ida);
58static DEFINE_SPINLOCK(mnt_id_lock); 58static DEFINE_SPINLOCK(mnt_id_lock);
@@ -1100,14 +1100,29 @@ static void *m_start(struct seq_file *m, loff_t *pos)
1100 struct proc_mounts *p = proc_mounts(m); 1100 struct proc_mounts *p = proc_mounts(m);
1101 1101
1102 down_read(&namespace_sem); 1102 down_read(&namespace_sem);
1103 return seq_list_start(&p->ns->list, *pos); 1103 if (p->cached_event == p->ns->event) {
1104 void *v = p->cached_mount;
1105 if (*pos == p->cached_index)
1106 return v;
1107 if (*pos == p->cached_index + 1) {
1108 v = seq_list_next(v, &p->ns->list, &p->cached_index);
1109 return p->cached_mount = v;
1110 }
1111 }
1112
1113 p->cached_event = p->ns->event;
1114 p->cached_mount = seq_list_start(&p->ns->list, *pos);
1115 p->cached_index = *pos;
1116 return p->cached_mount;
1104} 1117}
1105 1118
1106static void *m_next(struct seq_file *m, void *v, loff_t *pos) 1119static void *m_next(struct seq_file *m, void *v, loff_t *pos)
1107{ 1120{
1108 struct proc_mounts *p = proc_mounts(m); 1121 struct proc_mounts *p = proc_mounts(m);
1109 1122
1110 return seq_list_next(v, &p->ns->list, pos); 1123 p->cached_mount = seq_list_next(v, &p->ns->list, pos);
1124 p->cached_index = *pos;
1125 return p->cached_mount;
1111} 1126}
1112 1127
1113static void m_stop(struct seq_file *m, void *v) 1128static void m_stop(struct seq_file *m, void *v)
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c
index 7be26f03a3f5..1a81373947f3 100644
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -267,6 +267,7 @@ static int mounts_open_common(struct inode *inode, struct file *file,
267 p->root = root; 267 p->root = root;
268 p->m.poll_event = ns->event; 268 p->m.poll_event = ns->event;
269 p->show = show; 269 p->show = show;
270 p->cached_event = ~0ULL;
270 271
271 return 0; 272 return 0;
272 273