]> git.baikalelectronics.ru Git - kernel.git/commit
proc: Use a list of inodes to flush from proc
authorEric W. Biederman <ebiederm@xmission.com>
Thu, 20 Feb 2020 00:22:26 +0000 (18:22 -0600)
committerEric W. Biederman <ebiederm@xmission.com>
Mon, 24 Feb 2020 16:14:44 +0000 (10:14 -0600)
commit85dc3bc2736b8762963543a96c5d861fd12b2ecc
tree97ea4c6eec0838079455dd56565226863c157ad2
parent7c60b7ec06cd2acb04f491efc7200b5e5330270f
proc: Use a list of inodes to flush from proc

Rework the flushing of proc to use a list of directory inodes that
need to be flushed.

The list is kept on struct pid not on struct task_struct, as there is
a fixed connection between proc inodes and pids but at least for the
case of de_thread the pid of a task_struct changes.

This removes the dependency on proc_mnt which allows for different
mounts of proc having different mount options even in the same pid
namespace and this allows for the removal of proc_mnt which will
trivially the first mount of proc to honor it's mount options.

This flushing remains an optimization.  The functions
pid_delete_dentry and pid_revalidate ensure that ordinary dcache
management will not attempt to use dentries past the point their
respective task has died.  When unused the shrinker will
eventually be able to remove these dentries.

There is a case in de_thread where proc_flush_pid can be
called early for a given pid.  Which winds up being
safe (if suboptimal) as this is just an optiimization.

Only pid directories are put on the list as the other
per pid files are children of those directories and
d_invalidate on the directory will get them as well.

So that the pid can be used during flushing it's reference count is
taken in release_task and dropped in proc_flush_pid.  Further the call
of proc_flush_pid is moved after the tasklist_lock is released in
release_task so that it is certain that the pid has already been
unhashed when flushing it taking place.  This removes a small race
where a dentry could recreated.

As struct pid is supposed to be small and I need a per pid lock
I reuse the only lock that currently exists in struct pid the
the wait_pidfd.lock.

The net result is that this adds all of this functionality
with just a little extra list management overhead and
a single extra pointer in struct pid.

v2: Initialize pid->inodes.  I somehow failed to get that
    initialization into the initial version of the patch.  A boot
    failure was reported by "kernel test robot <lkp@intel.com>", and
    failure to initialize that pid->inodes matches all of the reported
    symptoms.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
fs/proc/base.c
fs/proc/inode.c
fs/proc/internal.h
include/linux/pid.h
include/linux/proc_fs.h
kernel/exit.c
kernel/pid.c