[Devel] [PATCH RHEL8 COMMIT] proc/mounts: fix skipping mount after cursor
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Jul 15 16:27:34 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 5f1bf5638973a9a0c82cc1703d35e173fc1786ff
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date: Fri Mar 26 17:46:28 2021 +0300
proc/mounts: fix skipping mount after cursor
When reading mounts with:
mount -t tmpfs $(printf 'T%.0s' {1..76}) /tmp/testmount
tail -n1 /proc/self/mountinfo | wc
# 1 10 128
# len should be 128
while read -r line; do echo $line; done < /proc/<pid>/mountinfo
We can see that after TTT mount we stuck on it and show it infinitely.
- Let's fix the case where we do m_start() and *pos == 0, in this case
we need to reset cursor caches (last_pos and last_mntpos) as user asks
us to start iterating from the beginning and we don't need to skip
any mount based on these caches.
- Let's set last_mntpos in m_stop and only in m_stop to actually make it
cache the mount after cursor. There is no point to set it in m_next as
cursor is inserted only in m_stop. Also let's reset last_mntpos to zero
if cursor is removed for consistency.
- Let's fix last_mntpos != mnt check in m_start, in case last_mntpos is
unset we does not want to skip any mount.
- Let's update last_pos in the end of m_start like in m_next. Where is a
posibility that in seq_read we print one entry without calling m_next at
all and go directly to m_stop and increment pos. If previously we had
pos == last_poss, after first m_start pos would be == last_pos + 1, and
after second m_start pos would be == last_pos + 2 and we would forget to
skip mount and will be printing it forever infinitely.
https://jira.sw.ru/browse/PSBM-127476
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Reviewed-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
(cherry picked from vz7 commit 0aee0dc817d1 ("proc/mounts: fix skipping
mount after cursor")
Fixes: ("proc/mounts: add cursor")
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
fs/namespace.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 6e5911e6ce92..99657de8bfb7 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1328,6 +1328,8 @@ static void *m_start(struct seq_file *m, loff_t *pos)
down_read(&namespace_sem);
if (!*pos) {
prev = &p->ns->list;
+ p->last_pos = 0;
+ p->last_mntpos = NULL;
} else {
prev = &p->cursor.mnt_list;
@@ -1380,10 +1382,10 @@ static void *m_start(struct seq_file *m, loff_t *pos)
* here and just remove following lines and p->last_pos field.
*/
if (mnt && (*pos == p->last_pos + 1) &&
- !(p->last_mntpos && (p->last_mntpos != mnt)))
+ (p->last_mntpos == mnt))
mnt = mnt_list_next(p->ns, &mnt->mnt_list);
- p->last_mntpos = mnt;
+ p->last_pos = *pos;
return mnt;
}
@@ -1395,8 +1397,7 @@ static void *m_next(struct seq_file *m, void *v, loff_t *pos)
++*pos;
p->last_pos = *pos;
- p->last_mntpos = mnt_list_next(p->ns, &mnt->mnt_list);
- return p->last_mntpos;
+ return mnt_list_next(p->ns, &mnt->mnt_list);
}
static void m_stop(struct seq_file *m, void *v)
@@ -1405,10 +1406,13 @@ static void m_stop(struct seq_file *m, void *v)
struct mount *mnt = v;
lock_ns_list(p->ns);
- if (mnt)
+ if (mnt) {
list_move_tail(&p->cursor.mnt_list, &mnt->mnt_list);
- else
+ p->last_mntpos = mnt;
+ } else {
list_del_init(&p->cursor.mnt_list);
+ p->last_mntpos = NULL;
+ }
unlock_ns_list(p->ns);
up_read(&namespace_sem);
}
More information about the Devel
mailing list