Re: [PATCH 2/3] vfs: Use the mounts_to_id array to do /proc/mounts and co.

From: Matthew Wilcox
Date: Mon Mar 15 2021 - 08:55:51 EST


On Mon, Mar 15, 2021 at 12:07:56PM +0000, David Howells wrote:
> Use the mounts_to_id xarray added to the mount namespace to perform

You called it mounts_by_id in the last patch ...

> Since it doesn't trawl a standard list_head, but rather uses xarray, this
> could be done under the RCU read lock only. To do this, we would need to
> hide mounts that are in the process of being inserted into the tree by
> marking them in the xarray itself or using a mount flag.

> /* 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;
> + struct proc_mounts *state = m->private;
> + void *entry;
>
> down_read(&namespace_sem);
> - if (!*pos) {
> - prev = &p->ns->list;
> - } else {
> - prev = &p->cursor.mnt_list;
> + state->xas = (struct xa_state) __XA_STATE(&state->ns->mounts_by_id, *pos, 0, 0);
>
> - /* Read after we'd reached the end? */
> - if (list_empty(prev))
> - return NULL;
> - }
> + entry = xas_find(&state->xas, ULONG_MAX);

I know you haven't enabled enough debugging because this will assert
that either the RCU read lock or the xa_lock is held to prevent xa_nodes
from disappearing underneath us.

Why do you want to use an xa_state for this? This is /proc, so efficiency
isn't the highest priority. I'd just use xa_find(), and then you don't
need to care about an xa_state or locking -- it handles taking the rcu
read lock for you.

> + while (entry && xas_invalid(entry))

I've never seen anybody make that mistake before. Good one. Not sure
if there's anything I can do to prevent it in future.

> + entry = xas_next_entry(&state->xas, ULONG_MAX);