Am 22.07.2025 um 14:00 hat Brian Song geschrieben:
> On 7/20/25 8:53 PM, Stefan Hajnoczi wrote:
> > On Wed, Jul 16, 2025 at 02:38:24PM -0400, Brian Song wrote:
> >> +    case FUSE_FSYNC:
> >> +        ret = fuse_co_fsync(exp);
> >> +        break;
> >> +
> >> +    case FUSE_FLUSH:
> >> +        ret = fuse_co_flush(exp);
> >> +        break;
> >> +
> >> +#ifdef CONFIG_FUSE_LSEEK
> >> +    case FUSE_LSEEK: {
> >> +        const struct fuse_lseek_in *in =
> >> +                        (const struct fuse_lseek_in *)&rrh->op_in;
> >> +        ret = fuse_co_lseek(exp, (struct fuse_lseek_out *)out_op_hdr,
> >> +                            in->offset, in->whence);
> >> +        break;
> >> +    }
> >> +#endif
> >> +
> >> +    default:
> >> +        ret = -ENOSYS;
> >> +    }
> >
> > It would be nice to reuse the non-io_uring code rather than duplicating
> > the switch statement that covers each FUSE opcode. Is the memory layout
> > so different that the code cannot be shared?
> 
> Yes. But I think the main issue is that we have to handle too many
> differences when it comes to various operations and the final step of
> replying to the request. There would be a lot of #ifdef
> CONFIG_LINUX_IO_URING and if statements. So, for simplicity, I made it a
> separate function.
> 
> In the traditional model:
> q->request_buf = fuse_in_header + struct fuse_opsxx_in +
> FUSE_IN_PLACE_WRITE_BYTES (used for part of the payload data)
> q->spillover_buf is used for the rest of the payload data.
> 
> In Fuse-over-io_uring:
> FuseRingEnt contains req_header (which includes in_out for
> fuse_in/out_header, and op_in for struct fuse_opsxx_in)
> op_payload corresponds to the final FUSE_IN_PLACE_WRITE_BYTES bytes from
> request_buf + spillover_buf in the traditional model but carries either
> the out operation headers (fuse_ops_out) or the file data to be written
> or read.

The individual opcode handlers you call from both functions are already
generic enough to work for both cases, e.g. fuse_co_write() takes both
an in_place_buf and spillover_buf. In the io_uring case you just pass
NULL for in_place_buf.

Why doesn't the same approach work for fuse_co_process_request()? Can't
you just pass three pointers for header, in_place_buf and spillover_buf
to it and have two very small wrappers around it that take care of
passing the right pointers for the respective case?

Kevin


Reply via email to