• Eric W. Biederman's avatar
    proc: Use a list of inodes to flush from proc · 7bc3e6e5
    Eric W. Biederman authored
    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: default avatarEric W. Biederman <ebiederm@xmission.com>
    7bc3e6e5
inode.c 13.1 KB