[Devel] [PATCH RH7] proc/mounts: fix skipping mount after cursor
Alexander Mikhalitsyn
alexander.mikhalitsyn at virtuozzo.com
Fri Mar 26 17:05:20 MSK 2021
On Fri, 26 Mar 2021 15:15:47 +0300
Pavel Tikhomirov <ptikhomirov at virtuozzo.com> wrote:
> 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>
> ---
> fs/namespace.c | 16 ++++++++++------
> 1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/fs/namespace.c b/fs/namespace.c
> index 042ede7abc3b6..a1c5afb446f05 100644
> --- a/fs/namespace.c
> +++ b/fs/namespace.c
> @@ -1457,6 +1457,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;
>
> @@ -1509,10 +1511,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;
> }
> @@ -1524,8 +1526,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)
> @@ -1534,10 +1535,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);
> }
> --
> 2.30.2
>
More information about the Devel
mailing list