mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:19:34 +02:00
Merge tag 'fuse-update-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse updates from Miklos Szeredi: - Improve performance of the io-uring transport by introducing buffer pools and zero-copy (Joanne) - Fix lots of bugs (Baokun Li) - Fix io-uring initialization issues (Joanne, Bernd) - More prep work for large folios (Joanne) - Don't limit buffered read to 128k (Jim Harris) - Fix zeroing of page end (dirtied with mmap) on file size extension (Jimmy Zuber) - Improve performance in certain cases with wake_up_sync() when queuing request (Xuewen Yan) - Misc fixes and cleanups (Xuewen Yan) * tag 'fuse-update-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: (35 commits) fuse: zero the partial EOF page when extending a file io_uring: Add missing include for ITER_SOURCE and ITER_DEST fuse: Fix the condition to enable over-io-uring fuse: invalidate the correct range after O_APPEND direct write selftests/fuse: test post-EOF page zeroing when a file is extended fuse: wake one waiter per freed slot when raising max_background fuse: use min_not_zero() in fuse_init_server_timeout() fuse: copy request headers via a stack buffer for io-uring fuse: give wakeup hints to the scheduler for synchronous requests fuse: check for NULL root inode in fuse_fill_super_submount fuse: reject a duplicate fd= mount option cuse: wait for pending RCU callbacks on module exit fuse: fix invalidate lock leak on open O_TRUNC DAX failure fuse: fix invalidate lock leak on setattr writeback failure fuse: wait for FR_FINISHED on abort_on_kill to prevent use-after-free fuse: make dentry_tree_work static docs: fuse: document io-uring buffer pool and zero-copy uapi fuse: add zero-copy over io-uring fuse: support registered buffer pools in io-uring fuse: add io-uring buffer pools ...
This commit is contained in:
+1
-1
@@ -3236,7 +3236,7 @@ static int __init io_uring_init(void)
|
||||
io_uring_optable_init();
|
||||
|
||||
/* imu->dir is u8 */
|
||||
BUILD_BUG_ON((IO_IMU_DEST | IO_IMU_SOURCE) > U8_MAX);
|
||||
BUILD_BUG_ON((IO_BUF_DEST | IO_BUF_SOURCE) > U8_MAX);
|
||||
|
||||
/*
|
||||
* Allow user copy in the per-command field, which starts after the
|
||||
|
||||
+92
-39
@@ -912,7 +912,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
|
||||
imu->release = io_release_ubuf;
|
||||
imu->priv = imu;
|
||||
imu->flags = 0;
|
||||
imu->dir = IO_IMU_DEST | IO_IMU_SOURCE;
|
||||
imu->dir = IO_BUF_DEST | IO_BUF_SOURCE;
|
||||
if (coalesced)
|
||||
imu->folio_shift = data.folio_shift;
|
||||
refcount_set(&imu->refs, 1);
|
||||
@@ -1015,71 +1015,124 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
|
||||
void (*release)(void *), unsigned int index,
|
||||
unsigned int issue_flags)
|
||||
static struct io_mapped_ubuf *io_kernel_buffer_init(struct io_ring_ctx *ctx,
|
||||
unsigned int nr_bvecs,
|
||||
unsigned int total_bytes,
|
||||
u8 dir,
|
||||
void (*release)(void *),
|
||||
void *priv,
|
||||
unsigned int index)
|
||||
{
|
||||
struct io_ring_ctx *ctx = cmd_to_io_kiocb(cmd)->ctx;
|
||||
struct io_rsrc_data *data = &ctx->buf_table;
|
||||
struct req_iterator rq_iter;
|
||||
struct io_mapped_ubuf *imu;
|
||||
struct io_rsrc_node *node;
|
||||
struct bio_vec bv;
|
||||
unsigned int nr_bvecs = 0;
|
||||
int ret = 0;
|
||||
|
||||
io_ring_submit_lock(ctx, issue_flags);
|
||||
if (index >= data->nr) {
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
if (index >= data->nr)
|
||||
return ERR_PTR(-EINVAL);
|
||||
index = array_index_nospec(index, data->nr);
|
||||
|
||||
if (data->nodes[index]) {
|
||||
ret = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
if (data->nodes[index])
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER);
|
||||
if (!node) {
|
||||
ret = -ENOMEM;
|
||||
goto unlock;
|
||||
if (!node)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
imu = io_alloc_imu(ctx, nr_bvecs);
|
||||
if (!imu) {
|
||||
io_cache_free(&ctx->node_cache, node);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
imu->ubuf = 0;
|
||||
imu->len = total_bytes;
|
||||
imu->folio_shift = PAGE_SHIFT;
|
||||
imu->nr_bvecs = nr_bvecs;
|
||||
refcount_set(&imu->refs, 1);
|
||||
imu->release = release;
|
||||
imu->priv = priv;
|
||||
imu->dir = dir;
|
||||
imu->flags = IO_REGBUF_F_KBUF;
|
||||
|
||||
node->buf = imu;
|
||||
data->nodes[index] = node;
|
||||
|
||||
return imu;
|
||||
}
|
||||
|
||||
int io_buffer_register_request(struct io_uring_cmd *cmd, struct request *rq,
|
||||
void (*release)(void *), unsigned int index,
|
||||
unsigned int issue_flags)
|
||||
{
|
||||
struct io_ring_ctx *ctx = cmd_to_io_kiocb(cmd)->ctx;
|
||||
struct req_iterator rq_iter;
|
||||
struct io_mapped_ubuf *imu;
|
||||
struct bio_vec bv;
|
||||
/*
|
||||
* blk_rq_nr_phys_segments() may overestimate the number of bvecs
|
||||
* but avoids needing to iterate over the bvecs
|
||||
*/
|
||||
imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq));
|
||||
if (!imu) {
|
||||
io_cache_free(&ctx->node_cache, node);
|
||||
ret = -ENOMEM;
|
||||
unsigned int nr_bvecs = blk_rq_nr_phys_segments(rq);
|
||||
unsigned int total_bytes = blk_rq_bytes(rq);
|
||||
int ret = 0;
|
||||
|
||||
io_ring_submit_lock(ctx, issue_flags);
|
||||
|
||||
imu = io_kernel_buffer_init(ctx, nr_bvecs, total_bytes,
|
||||
1 << rq_data_dir(rq), release, rq, index);
|
||||
if (IS_ERR(imu)) {
|
||||
ret = PTR_ERR(imu);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
imu->ubuf = 0;
|
||||
imu->len = blk_rq_bytes(rq);
|
||||
imu->folio_shift = PAGE_SHIFT;
|
||||
refcount_set(&imu->refs, 1);
|
||||
imu->release = release;
|
||||
imu->priv = rq;
|
||||
imu->flags = IO_REGBUF_F_KBUF;
|
||||
imu->dir = 1 << rq_data_dir(rq);
|
||||
|
||||
nr_bvecs = 0;
|
||||
rq_for_each_bvec(bv, rq, rq_iter)
|
||||
imu->bvec[nr_bvecs++] = bv;
|
||||
imu->nr_bvecs = nr_bvecs;
|
||||
|
||||
node->buf = imu;
|
||||
data->nodes[index] = node;
|
||||
unlock:
|
||||
io_ring_submit_unlock(ctx, issue_flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(io_buffer_register_request);
|
||||
|
||||
/*
|
||||
* bvs is copied internally. caller may free it on return.
|
||||
*/
|
||||
int io_buffer_register_bvec(struct io_uring_cmd *cmd, const struct bio_vec *bvs,
|
||||
unsigned int nr_bvecs, void (*release)(void *),
|
||||
void *priv, u8 dir, unsigned int index,
|
||||
unsigned int issue_flags)
|
||||
{
|
||||
struct io_ring_ctx *ctx = cmd_to_io_kiocb(cmd)->ctx;
|
||||
struct io_mapped_ubuf *imu;
|
||||
struct bio_vec *bvec;
|
||||
unsigned int i, total_bytes = 0;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < nr_bvecs; i++)
|
||||
total_bytes += bvs[i].bv_len;
|
||||
|
||||
io_ring_submit_lock(ctx, issue_flags);
|
||||
imu = io_kernel_buffer_init(ctx, nr_bvecs, total_bytes, dir, release,
|
||||
priv, index);
|
||||
if (IS_ERR(imu)) {
|
||||
ret = PTR_ERR(imu);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
bvec = imu->bvec;
|
||||
for (i = 0; i < nr_bvecs; i++)
|
||||
bvec[i] = bvs[i];
|
||||
|
||||
unlock:
|
||||
io_ring_submit_unlock(ctx, issue_flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(io_buffer_register_bvec);
|
||||
|
||||
int io_buffer_unregister_bvec(struct io_uring_cmd *cmd, unsigned int index,
|
||||
unsigned int issue_flags)
|
||||
int io_buffer_unregister(struct io_uring_cmd *cmd, unsigned int index,
|
||||
unsigned int issue_flags)
|
||||
{
|
||||
struct io_ring_ctx *ctx = cmd_to_io_kiocb(cmd)->ctx;
|
||||
struct io_rsrc_data *data = &ctx->buf_table;
|
||||
@@ -1109,7 +1162,7 @@ unlock:
|
||||
io_ring_submit_unlock(ctx, issue_flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(io_buffer_unregister_bvec);
|
||||
EXPORT_SYMBOL_GPL(io_buffer_unregister);
|
||||
|
||||
static int validate_fixed_range(u64 buf_addr, size_t len,
|
||||
const struct io_mapped_ubuf *imu)
|
||||
|
||||
@@ -25,11 +25,6 @@ struct io_rsrc_node {
|
||||
};
|
||||
};
|
||||
|
||||
enum {
|
||||
IO_IMU_DEST = 1 << ITER_DEST,
|
||||
IO_IMU_SOURCE = 1 << ITER_SOURCE,
|
||||
};
|
||||
|
||||
enum {
|
||||
IO_REGBUF_F_KBUF = 1,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user