]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs/ioctl: store btrfs_uring_encoded_data in io_btrfs_cmd
authorCaleb Sander Mateos <csander@purestorage.com>
Tue, 8 Jul 2025 20:22:11 +0000 (14:22 -0600)
committerJens Axboe <axboe@kernel.dk>
Fri, 18 Jul 2025 18:34:56 +0000 (12:34 -0600)
btrfs is the only user of struct io_uring_cmd_data and its op_data
field. Switch its ->uring_cmd() implementations to store the struct
btrfs_uring_encoded_data * in the struct io_btrfs_cmd, overlayed with
io_uring_cmd's pdu field. This avoids having to touch another cache line
to access the struct btrfs_uring_encoded_data *, and allows op_data and
struct io_uring_cmd_data to be removed.

Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Acked-by: David Sterba <dsterba@suse.com>
Link: https://lore.kernel.org/r/20250708202212.2851548-4-csander@purestorage.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/btrfs/ioctl.c

index 913acef3f0a9691f4d21f6a17a96995d4cb55039..9eb06ae79362a902f90dc6be1fde2fdd5255e188 100644 (file)
@@ -4629,6 +4629,13 @@ out_acct:
        return ret;
 }
 
+struct btrfs_uring_encoded_data {
+       struct btrfs_ioctl_encoded_io_args args;
+       struct iovec iovstack[UIO_FASTIOV];
+       struct iovec *iov;
+       struct iov_iter iter;
+};
+
 /*
  * Context that's attached to an encoded read io_uring command, in cmd->pdu. It
  * contains the fields in btrfs_uring_read_extent that are necessary to finish
@@ -4650,6 +4657,7 @@ struct btrfs_uring_priv {
 };
 
 struct io_btrfs_cmd {
+       struct btrfs_uring_encoded_data *data;
        struct btrfs_uring_priv *priv;
 };
 
@@ -4708,6 +4716,7 @@ out:
        kfree(priv->pages);
        kfree(priv->iov);
        kfree(priv);
+       kfree(bc->data);
 }
 
 void btrfs_uring_read_extent_endio(void *ctx, int err)
@@ -4791,13 +4800,6 @@ out_fail:
        return ret;
 }
 
-struct btrfs_uring_encoded_data {
-       struct btrfs_ioctl_encoded_io_args args;
-       struct iovec iovstack[UIO_FASTIOV];
-       struct iovec *iov;
-       struct iov_iter iter;
-};
-
 static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue_flags)
 {
        size_t copy_end_kernel = offsetofend(struct btrfs_ioctl_encoded_io_args, flags);
@@ -4813,7 +4815,11 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue
        struct extent_state *cached_state = NULL;
        u64 start, lockend;
        void __user *sqe_addr;
-       struct btrfs_uring_encoded_data *data = io_uring_cmd_get_async_data(cmd)->op_data;
+       struct io_btrfs_cmd *bc = io_uring_cmd_to_pdu(cmd, struct io_btrfs_cmd);
+       struct btrfs_uring_encoded_data *data = NULL;
+
+       if (cmd->flags & IORING_URING_CMD_REISSUE)
+               data = bc->data;
 
        if (!capable(CAP_SYS_ADMIN)) {
                ret = -EPERM;
@@ -4842,7 +4848,7 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue
                        goto out_acct;
                }
 
-               io_uring_cmd_get_async_data(cmd)->op_data = data;
+               bc->data = data;
 
                if (issue_flags & IO_URING_F_COMPAT) {
 #if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT)
@@ -4940,6 +4946,9 @@ out_acct:
                add_rchar(current, ret);
        inc_syscr(current);
 
+       if (ret != -EIOCBQUEUED && ret != -EAGAIN)
+               kfree(data);
+
        return ret;
 }
 
@@ -4950,7 +4959,11 @@ static int btrfs_uring_encoded_write(struct io_uring_cmd *cmd, unsigned int issu
        struct file *file;
        ssize_t ret;
        void __user *sqe_addr;
-       struct btrfs_uring_encoded_data *data = io_uring_cmd_get_async_data(cmd)->op_data;
+       struct io_btrfs_cmd *bc = io_uring_cmd_to_pdu(cmd, struct io_btrfs_cmd);
+       struct btrfs_uring_encoded_data *data = NULL;
+
+       if (cmd->flags & IORING_URING_CMD_REISSUE)
+               data = bc->data;
 
        if (!capable(CAP_SYS_ADMIN)) {
                ret = -EPERM;
@@ -4972,7 +4985,7 @@ static int btrfs_uring_encoded_write(struct io_uring_cmd *cmd, unsigned int issu
                        goto out_acct;
                }
 
-               io_uring_cmd_get_async_data(cmd)->op_data = data;
+               bc->data = data;
 
                if (issue_flags & IO_URING_F_COMPAT) {
 #if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT)
@@ -5062,6 +5075,9 @@ out_acct:
        if (ret > 0)
                add_wchar(current, ret);
        inc_syscw(current);
+
+       if (ret != -EAGAIN)
+               kfree(data);
        return ret;
 }