mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 12:00:22 +09:00
ANDROID: fuse-bpf: Fix read_iter
We had a size mismatch for the return value, leading to EIOCBQUEUED getting interpreted as a return size instead of an error code. Test: generic/467, generic/013, and fuse_test Bug: 217570523 Signed-off-by: Daniel Rosenberg <drosen@google.com> Change-Id: I64f9d5263f8b37d3c0e286467f9351997b294cc2
This commit is contained in:
@@ -846,29 +846,33 @@ static void fuse_bpf_aio_rw_complete(struct kiocb *iocb, long res, long res2)
|
||||
|
||||
|
||||
int fuse_file_read_iter_initialize(
|
||||
struct fuse_args *fa, struct fuse_read_in *fri,
|
||||
struct fuse_args *fa, struct fuse_file_read_iter_io *fri,
|
||||
struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct fuse_file *ff = file->private_data;
|
||||
|
||||
*fri = (struct fuse_read_in) {
|
||||
fri->fri = (struct fuse_read_in) {
|
||||
.fh = ff->fh,
|
||||
.offset = iocb->ki_pos,
|
||||
.size = to->count,
|
||||
};
|
||||
|
||||
fri->frio = (struct fuse_read_iter_out) {
|
||||
.ret = fri->fri.size,
|
||||
};
|
||||
|
||||
/* TODO we can't assume 'to' is a kvec */
|
||||
/* TODO we also can't assume the vector has only one component */
|
||||
*fa = (struct fuse_args) {
|
||||
.opcode = FUSE_READ,
|
||||
.nodeid = ff->nodeid,
|
||||
.in_numargs = 1,
|
||||
.in_args[0].size = sizeof(*fri),
|
||||
.in_args[0].value = fri,
|
||||
.in_args[0].size = sizeof(fri->fri),
|
||||
.in_args[0].value = &fri->fri,
|
||||
.out_numargs = 1,
|
||||
.out_args[0].size = fri->size,
|
||||
.out_args[0].value = to->kvec->iov_base,
|
||||
.out_args[0].size = sizeof(fri->frio),
|
||||
.out_args[0].value = &fri->frio,
|
||||
/*
|
||||
* TODO Design this properly.
|
||||
* Possible approach: do not pass buf to bpf
|
||||
@@ -884,6 +888,7 @@ int fuse_file_read_iter_initialize(
|
||||
int fuse_file_read_iter_backing(struct fuse_args *fa,
|
||||
struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
struct fuse_read_iter_out *frio = fa->out_args[0].value;
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct fuse_file *ff = file->private_data;
|
||||
ssize_t ret;
|
||||
@@ -918,8 +923,7 @@ int fuse_file_read_iter_backing(struct fuse_args *fa,
|
||||
fuse_bpf_aio_cleanup_handler(aio_req);
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
fa->out_args[0].size = ret;
|
||||
frio->ret = ret;
|
||||
|
||||
/* TODO Need to point value at the buffer for post-modification */
|
||||
|
||||
@@ -932,7 +936,9 @@ out:
|
||||
void *fuse_file_read_iter_finalize(struct fuse_args *fa,
|
||||
struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
return ERR_PTR(fa->out_args[0].size);
|
||||
struct fuse_read_iter_out *frio = fa->out_args[0].value;
|
||||
|
||||
return ERR_PTR(frio->ret);
|
||||
}
|
||||
|
||||
int fuse_file_write_iter_initialize(
|
||||
|
||||
@@ -1643,7 +1643,7 @@ static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
struct fuse_err_ret fer;
|
||||
|
||||
fer = fuse_bpf_backing(inode, struct fuse_read_in,
|
||||
fer = fuse_bpf_backing(inode, struct fuse_file_read_iter_io,
|
||||
fuse_file_read_iter_initialize,
|
||||
fuse_file_read_iter_backing,
|
||||
fuse_file_read_iter_finalize,
|
||||
|
||||
@@ -1512,8 +1512,16 @@ int fuse_removexattr_backing(struct fuse_args *fa,
|
||||
void *fuse_removexattr_finalize(struct fuse_args *fa,
|
||||
struct dentry *dentry, const char *name);
|
||||
|
||||
struct fuse_read_iter_out {
|
||||
uint64_t ret;
|
||||
};
|
||||
struct fuse_file_read_iter_io {
|
||||
struct fuse_read_in fri;
|
||||
struct fuse_read_iter_out frio;
|
||||
};
|
||||
|
||||
int fuse_file_read_iter_initialize(
|
||||
struct fuse_args *fa, struct fuse_read_in *fri,
|
||||
struct fuse_args *fa, struct fuse_file_read_iter_io *fri,
|
||||
struct kiocb *iocb, struct iov_iter *to);
|
||||
int fuse_file_read_iter_backing(struct fuse_args *fa,
|
||||
struct kiocb *iocb, struct iov_iter *to);
|
||||
|
||||
Reference in New Issue
Block a user