• Linus Torvalds's avatar
    Merge tag 'vfs-6.9.pidfd' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs · b5683a37
    Linus Torvalds authored
    Pull pdfd updates from Christian Brauner:
    
     - Until now pidfds could only be created for thread-group leaders but
       not for threads. There was no technical reason for this. We simply
       had no users that needed support for this. Now we do have users that
       need support for this.
    
       This introduces a new PIDFD_THREAD flag for pidfd_open(). If that
       flag is set pidfd_open() creates a pidfd that refers to a specific
       thread.
    
       In addition, we now allow clone() and clone3() to be called with
       CLONE_PIDFD | CLONE_THREAD which wasn't possible before.
    
       A pidfd that refers to an individual thread differs from a pidfd that
       refers to a thread-group leader:
    
        (1) Pidfds are pollable. A task may poll a pidfd and get notified
            when the task has exited.
    
            For thread-group leader pidfds the polling task is woken if the
            thread-group is empty. In other words, if the thread-group
            leader task exits when there are still threads alive in its
            thread-group the polling task will not be woken when the
            thread-group leader exits but rather when the last thread in the
            thread-group exits.
    
            For thread-specific pidfds the polling task is woken if the
            thread exits.
    
        (2) Passing a thread-group leader pidfd to pidfd_send_signal() will
            generate thread-group directed signals like kill(2) does.
    
            Passing a thread-specific pidfd to pidfd_send_signal() will
            generate thread-specific signals like tgkill(2) does.
    
            The default scope of the signal is thus determined by the type
            of the pidfd.
    
            Since use-cases exist where the default scope of the provided
            pidfd needs to be overriden the following flags are added to
            pidfd_send_signal():
    
             - PIDFD_SIGNAL_THREAD
               Send a thread-specific signal.
    
             - PIDFD_SIGNAL_THREAD_GROUP
               Send a thread-group directed signal.
    
             - PIDFD_SIGNAL_PROCESS_GROUP
               Send a process-group directed signal.
    
            The scope change will only work if the struct pid is actually
            used for this scope.
    
            For example, in order to send a thread-group directed signal the
            provided pidfd must be used as a thread-group leader and
            similarly for PIDFD_SIGNAL_PROCESS_GROUP the struct pid must be
            used as a process group leader.
    
     - Move pidfds from the anonymous inode infrastructure to a tiny pseudo
       filesystem. This will unblock further work that we weren't able to do
       simply because of the very justified limitations of anonymous inodes.
       Moving pidfds to a tiny pseudo filesystem allows for statx on pidfds
       to become useful for the first time. They can now be compared by
       inode number which are unique for the system lifetime.
    
       Instead of stashing struct pid in file->private_data we can now stash
       it in inode->i_private. This makes it possible to introduce concepts
       that operate on a process once all file descriptors have been closed.
       A concrete example is kill-on-last-close. Another side-effect is that
       file->private_data is now freed up for per-file options for pidfds.
    
       Now, each struct pid will refer to a different inode but the same
       struct pid will refer to the same inode if it's opened multiple
       times. In contrast to now where each struct pid refers to the same
       inode.
    
       The tiny pseudo filesystem is not visible anywhere in userspace
       exactly like e.g., pipefs and sockfs. There's no lookup, there's no
       complex inode operations, nothing. Dentries and inodes are always
       deleted when the last pidfd is closed.
    
       We allocate a new inode and dentry for each struct pid and we reuse
       that inode and dentry for all pidfds that refer to the same struct
       pid. The code is entirely optional and fairly small. If it's not
       selected we fallback to anonymous inodes. Heavily inspired by nsfs.
    
       The dentry and inode allocation mechanism is moved into generic
       infrastructure that is now shared between nsfs and pidfs. The
       path_from_stashed() helper must be provided with a stashing location,
       an inode number, a mount, and the private data that is supposed to be
       used and it will provide a path that can be passed to dentry_open().
    
       The helper will try retrieve an existing dentry from the provided
       stashing location. If a valid dentry is found it is reused. If not a
       new one is allocated and we try to stash it in the provided location.
       If this fails we retry until we either find an existing dentry or the
       newly allocated dentry could be stashed. Subsequent openers of the
       same namespace or task are then able to reuse it.
    
     - Currently it is only possible to get notified when a task has exited,
       i.e., become a zombie and userspace gets notified with EPOLLIN. We
       now also support waiting until the task has been reaped, notifying
       userspace with EPOLLHUP.
    
     - Ensure that ESRCH is reported for getfd if a task is exiting instead
       of the confusing EBADF.
    
     - Various smaller cleanups to pidfd functions.
    
    * tag 'vfs-6.9.pidfd' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (23 commits)
      libfs: improve path_from_stashed()
      libfs: add stashed_dentry_prune()
      libfs: improve path_from_stashed() helper
      pidfs: convert to path_from_stashed() helper
      nsfs: convert to path_from_stashed() helper
      libfs: add path_from_stashed()
      pidfd: add pidfs
      pidfd: move struct pidfd_fops
      pidfd: allow to override signal scope in pidfd_send_signal()
      pidfd: change pidfd_send_signal() to respect PIDFD_THREAD
      signal: fill in si_code in prepare_kill_siginfo()
      selftests: add ESRCH tests for pidfd_getfd()
      pidfd: getfd should always report ESRCH if a task is exiting
      pidfd: clone: allow CLONE_THREAD | CLONE_PIDFD together
      pidfd: exit: kill the no longer used thread_group_exited()
      pidfd: change do_notify_pidfd() to use __wake_up(poll_to_key(EPOLLIN))
      pid: kill the obsolete PIDTYPE_PID code in transfer_pid()
      pidfd: kill the no longer needed do_notify_pidfd() in de_thread()
      pidfd_poll: report POLLHUP when pid_task() == NULL
      pidfd: implement PIDFD_THREAD flag for pidfd_open()
      ...
    b5683a37
libfs.c 55.6 KB