linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/47] file: FD_{ADD,PREPARE}()
@ 2025-11-23 16:33 Christian Brauner
  2025-11-23 16:33 ` [PATCH v4 01/47] file: add FD_{ADD,PREPARE}() Christian Brauner
                   ` (47 more replies)
  0 siblings, 48 replies; 74+ messages in thread
From: Christian Brauner @ 2025-11-23 16:33 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Alexander Viro, Jan Kara, linux-fsdevel, Jeff Layton,
	Amir Goldstein, Jens Axboe, Christian Brauner

Hey,

This now removes roughly double the code that it adds.

I've been playing with this to allow for moderately flexible usage of
the get_unused_fd_flags() + create file + fd_install() pattern that's
used quite extensively and requires cumbersome cleanup paths.

How callers allocate files is really heterogenous so it's not really
convenient to fold them into a single class. It's possibe to split them
into subclasses like for anon inodes. I think that's not necessarily
nice as well. This adds two primitives:

(1) FD_ADD() the simple cases a file is installed:

    fd = FD_ADD(O_CLOEXEC, vfio_device_open_file(device));
    if (fd < 0)
            vfio_device_put_registration(device);
    return fd;

(2) FD_PREPARE() that captures all the cases where access to fd or file
    or additional work before publishing the fd is needed:

    FD_PREPARE(fdf, O_CLOEXEC, sync_file->file);
    if (fdf.err) {
            fput(sync_file->file);
            return fdf.err;
    }

    data.fence = fd_prepare_fd(fdf);
    if (copy_to_user((void __user *)arg, &data, sizeof(data)))
            return -EFAULT;

    return fd_publish(fdf);

I've converted all of the easy cases over to it and it gets rid of an
aweful lot of convoluted cleanup logic. There are a bunch of other cases
that can also be converted after a bit of massaging.

It's centered around a simple struct. FD_PREPARE() encapsulates all of
allocation and cleanup logic and must be followed by a call to
fd_publish() which associates the fd with the file and installs it into
the callers fdtable. If fd_publish() isn't called both are deallocated.
FD_ADD() is a shorthand that does the fd_publish() and never exposes the
struct to the caller. That's often the case when they don't need access
to anything after installing the fd.

It mandates a specific order namely that first we allocate the fd and
then instantiate the file. But that shouldn't be a problem. Nearly
everyone I've converted used this order anyway.

There's a bunch of additional cases where it would be easy to convert
them to this pattern. For example, the whole sync file stuff in dma
currently returns the containing structure of the file instead of the
file itself even though it's only used to allocate files. Changing that
would make it fall into the FD_PREPARE() pattern easily. I've not done
that work yet.

There's room for extending this in a way that wed'd have subclasses for
some particularly often use patterns but as I said I'm not even sure
that's worth it.

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
Changes in v4:
- Integrated error checking into FD_PREPARE() as per Linus suggestion.
- Added FD_ADD() as it's such an obvious win for a bunch of cases.
- Link to v3: https://patch.msgid.link/20251121-work-fd-prepare-v3-0-2c6444d13e0e@kernel.org

Changes in v3:
- Remove scope-based variant.
- Link to v2: https://patch.msgid.link/20251120-work-fd-prepare-v2-0-fef6ebda05d3@kernel.org

Changes in v2:
- Make FD_PREPARE() use a separate scope.
- Convert most easy cases.
- Link to v1: https://patch.msgid.link/20251118-work-fd-prepare-v1-0-c20504d97375@kernel.org

---
Christian Brauner (47):
      file: add FD_{ADD,PREPARE}()
      anon_inodes: convert to FD_PREPARE()
      eventfd: convert do_eventfd() to FD_PREPARE()
      fhandle: convert do_handle_open() to FD_PREPARE()
      namespace: convert open_tree() to FD_PREPARE()
      namespace: convert open_tree_attr() to FD_PREPARE()
      namespace: convert fsmount() to FD_PREPARE()
      fanotify: convert fanotify_init() to FD_PREPARE()
      nsfs: convert open_namespace() to FD_PREPARE()
      nsfs: convert ns_ioctl() to FD_PREPARE()
      autofs: convert autofs_dev_ioctl_open_mountpoint() to FD_PREPARE()
      eventpoll: convert do_epoll_create() to FD_PREPARE()
      open: convert do_sys_openat2() to FD_PREPARE()
      signalfd: convert do_signalfd4() to FD_PREPARE()
      timerfd: convert timerfd_create() to FD_PREPARE()
      userfaultfd: convert new_userfaultfd() to FD_PREPARE()
      xfs: convert xfs_open_by_handle() to FD_PREPARE()
      dma: convert dma_buf_fd() to FD_PREPARE()
      af_unix: convert unix_file_open() to FD_PREPARE()
      dma: convert sync_file_ioctl_merge() to FD_PREPARE()
      exec: convert begin_new_exec() to FD_PREPARE()
      ipc: convert do_mq_open() to FD_PREPARE()
      bpf: convert bpf_iter_new_fd() to FD_PREPARE()
      bpf: convert bpf_token_create() to FD_PREPARE()
      memfd: convert memfd_create() to FD_PREPARE()
      secretmem: convert memfd_secret() to FD_PREPARE()
      net/handshake: convert handshake_nl_accept_doit() to FD_PREPARE()
      net/kcm: convert kcm_ioctl() to FD_PREPARE()
      net/sctp: convert sctp_getsockopt_peeloff_common() to FD_PREPARE()
      net/socket: convert sock_map_fd() to FD_PREPARE()
      net/socket: convert __sys_accept4_file() to FD_PREPARE()
      spufs: convert spufs_context_open() to FD_PREPARE()
      papr-hvpipe: convert papr_hvpipe_dev_create_handle() to FD_PREPARE()
      spufs: convert spufs_gang_open() to FD_PREPARE()
      pseries: convert papr_platform_dump_create_handle() to FD_PREPARE()
      pseries: port papr_rtas_setup_file_interface() to FD_PREPARE()
      dma: port sw_sync_ioctl_create_fence() to FD_PREPARE()
      gpio: convert linehandle_create() to FD_PREPARE()
      hv: convert mshv_ioctl_create_partition() to FD_PREPARE()
      media: convert media_request_alloc() to FD_PREPARE()
      ntsync: convert ntsync_obj_get_fd() to FD_PREPARE()
      tty: convert ptm_open_peer() to FD_PREPARE()
      vfio: convert vfio_group_ioctl_get_device_fd() to FD_PREPARE()
      file: convert replace_fd() to FD_PREPARE()
      io_uring: convert io_create_mock_file() to FD_PREPARE()
      kvm: convert kvm_arch_supports_gmem_init_shared() to FD_PREPARE()
      kvm: convert kvm_vcpu_ioctl_get_stats_fd() to FD_PREPARE()

 arch/powerpc/platforms/cell/spufs/inode.c          | 42 +++-------
 arch/powerpc/platforms/pseries/papr-hvpipe.c       | 39 +++-------
 .../powerpc/platforms/pseries/papr-platform-dump.c | 32 +++-----
 arch/powerpc/platforms/pseries/papr-rtas-common.c  | 27 ++-----
 drivers/dma-buf/dma-buf.c                          | 10 +--
 drivers/dma-buf/sw_sync.c                          | 40 ++++------
 drivers/dma-buf/sync_file.c                        | 52 ++++---------
 drivers/gpio/gpiolib-cdev.c                        | 58 ++++++--------
 drivers/hv/mshv_root_main.c                        | 29 ++-----
 drivers/media/mc/mc-request.c                      | 34 +++-----
 drivers/misc/ntsync.c                              | 20 ++---
 drivers/tty/pty.c                                  | 30 ++-----
 drivers/vfio/group.c                               | 28 ++-----
 fs/anon_inodes.c                                   | 23 +-----
 fs/autofs/dev-ioctl.c                              | 30 ++-----
 fs/eventfd.c                                       | 31 +++-----
 fs/eventpoll.c                                     | 32 +++-----
 fs/exec.c                                          |  9 ++-
 fs/fhandle.c                                       | 30 ++++---
 fs/file.c                                          | 19 ++---
 fs/namespace.c                                     | 88 +++++++--------------
 fs/notify/fanotify/fanotify_user.c                 | 60 ++++++--------
 fs/nsfs.c                                          | 46 ++++-------
 fs/open.c                                          | 17 +---
 fs/signalfd.c                                      | 29 +++----
 fs/timerfd.c                                       | 29 +++----
 fs/userfaultfd.c                                   | 30 +++----
 fs/xfs/xfs_handle.c                                | 53 ++++---------
 include/linux/cleanup.h                            |  7 ++
 include/linux/file.h                               | 91 ++++++++++++++++++++++
 io_uring/mock_file.c                               | 44 ++++-------
 ipc/mqueue.c                                       | 31 +++-----
 kernel/bpf/bpf_iter.c                              | 29 ++-----
 kernel/bpf/token.c                                 | 47 ++++-------
 mm/memfd.c                                         | 29 ++-----
 mm/secretmem.c                                     | 20 +----
 net/handshake/netlink.c                            | 37 ++++-----
 net/kcm/kcmsock.c                                  | 23 ++----
 net/sctp/socket.c                                  | 90 ++++++---------------
 net/socket.c                                       | 34 ++------
 net/unix/af_unix.c                                 | 16 +---
 virt/kvm/guest_memfd.c                             | 35 +++------
 virt/kvm/kvm_main.c                                | 20 ++---
 43 files changed, 511 insertions(+), 1009 deletions(-)
---
base-commit: c8e00cdc7425d5c60fd1ce6e7f71e5fb1b236991
change-id: 20251118-work-fd-prepare-f415a3bf5fda


^ permalink raw reply	[flat|nested] 74+ messages in thread

end of thread, other threads:[~2025-11-26 16:11 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-23 16:33 [PATCH v4 00/47] file: FD_{ADD,PREPARE}() Christian Brauner
2025-11-23 16:33 ` [PATCH v4 01/47] file: add FD_{ADD,PREPARE}() Christian Brauner
2025-11-24 15:03   ` Jason Gunthorpe
2025-11-23 16:33 ` [PATCH v4 02/47] anon_inodes: convert to FD_PREPARE() Christian Brauner
2025-11-25 12:16   ` Jan Kara
2025-11-23 16:33 ` [PATCH v4 03/47] eventfd: convert do_eventfd() " Christian Brauner
2025-11-25 12:18   ` Jan Kara
2025-11-23 16:33 ` [PATCH v4 04/47] fhandle: convert do_handle_open() " Christian Brauner
2025-11-25 12:15   ` Jan Kara
2025-11-23 16:33 ` [PATCH v4 05/47] namespace: convert open_tree() " Christian Brauner
2025-11-25 12:32   ` Jan Kara
2025-11-23 16:33 ` [PATCH v4 06/47] namespace: convert open_tree_attr() " Christian Brauner
2025-11-25 12:33   ` Jan Kara
2025-11-23 16:33 ` [PATCH v4 07/47] namespace: convert fsmount() " Christian Brauner
2025-11-25 12:42   ` Jan Kara
2025-11-23 16:33 ` [PATCH v4 08/47] fanotify: convert fanotify_init() " Christian Brauner
2025-11-24 17:13   ` Amir Goldstein
2025-11-25 12:13   ` Jan Kara
2025-11-23 16:33 ` [PATCH v4 09/47] nsfs: convert open_namespace() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 10/47] nsfs: convert ns_ioctl() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 11/47] autofs: convert autofs_dev_ioctl_open_mountpoint() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 12/47] eventpoll: convert do_epoll_create() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 13/47] open: convert do_sys_openat2() " Christian Brauner
2025-11-25 12:20   ` Jan Kara
2025-11-23 16:33 ` [PATCH v4 14/47] signalfd: convert do_signalfd4() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 15/47] timerfd: convert timerfd_create() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 16/47] userfaultfd: convert new_userfaultfd() " Christian Brauner
2025-11-25 11:24   ` Mike Rapoport
2025-11-23 16:33 ` [PATCH v4 17/47] xfs: convert xfs_open_by_handle() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 18/47] dma: convert dma_buf_fd() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 19/47] af_unix: convert unix_file_open() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 20/47] dma: convert sync_file_ioctl_merge() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 21/47] exec: convert begin_new_exec() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 22/47] ipc: convert do_mq_open() " Christian Brauner
2025-11-25 22:30   ` Mark Brown
2025-11-26  0:05     ` Linus Torvalds
2025-11-26 13:20       ` Christian Brauner
2025-11-26 16:10         ` Linus Torvalds
2025-11-23 16:33 ` [PATCH v4 23/47] bpf: convert bpf_iter_new_fd() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 24/47] bpf: convert bpf_token_create() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 25/47] memfd: convert memfd_create() " Christian Brauner
2025-11-25 11:30   ` Mike Rapoport
2025-11-23 16:33 ` [PATCH v4 26/47] secretmem: convert memfd_secret() " Christian Brauner
2025-11-25 11:21   ` Mike Rapoport
2025-11-23 16:33 ` [PATCH v4 27/47] net/handshake: convert handshake_nl_accept_doit() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 28/47] net/kcm: convert kcm_ioctl() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 29/47] net/sctp: convert sctp_getsockopt_peeloff_common() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 30/47] net/socket: convert sock_map_fd() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 31/47] net/socket: convert __sys_accept4_file() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 32/47] spufs: convert spufs_context_open() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 33/47] papr-hvpipe: convert papr_hvpipe_dev_create_handle() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 34/47] spufs: convert spufs_gang_open() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 35/47] pseries: convert papr_platform_dump_create_handle() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 36/47] pseries: port papr_rtas_setup_file_interface() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 37/47] dma: port sw_sync_ioctl_create_fence() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 38/47] gpio: convert linehandle_create() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 39/47] hv: convert mshv_ioctl_create_partition() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 40/47] media: convert media_request_alloc() " Christian Brauner
2025-11-23 16:33 ` [PATCH v4 41/47] ntsync: convert ntsync_obj_get_fd() " Christian Brauner
2025-11-23 16:34 ` [PATCH v4 42/47] tty: convert ptm_open_peer() " Christian Brauner
2025-11-25 22:39   ` Mark Brown
2025-11-26 13:35     ` Christian Brauner
2025-11-26 14:22       ` Mark Brown
2025-11-23 16:34 ` [PATCH v4 43/47] vfio: convert vfio_group_ioctl_get_device_fd() " Christian Brauner
2025-11-24 14:52   ` Jason Gunthorpe
2025-11-23 16:34 ` [PATCH v4 44/47] file: convert replace_fd() " Christian Brauner
2025-11-25 12:29   ` Jan Kara
2025-11-23 16:34 ` [PATCH v4 45/47] io_uring: convert io_create_mock_file() " Christian Brauner
2025-11-25 16:38   ` Jens Axboe
2025-11-23 16:34 ` [PATCH v4 46/47] kvm: convert kvm_arch_supports_gmem_init_shared() " Christian Brauner
2025-11-23 16:34 ` [PATCH v4 47/47] kvm: convert kvm_vcpu_ioctl_get_stats_fd() " Christian Brauner
2025-11-23 16:43 ` [PATCH v4 00/47] file: FD_{ADD,PREPARE}() Linus Torvalds
2025-11-23 16:46   ` Linus Torvalds
2025-11-23 22:53   ` Christian Brauner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).