On 18/03/2021 05:45, Christoph Hellwig wrote: > On Wed, Mar 17, 2021 at 04:10:25PM -0600, Jens Axboe wrote: >> +static int blkdev_uring_ioctl(struct block_device *bdev, >> + struct io_uring_cmd *cmd) >> +{ >> + struct block_uring_cmd *bcmd = (struct block_uring_cmd *) &cmd->pdu; >> + >> + switch (bcmd->ioctl_cmd) { >> + case BLKBSZGET: >> + return block_size(bdev); >> + default: >> + return -ENOTTY; >> + } >> +} >> + >> static int blkdev_uring_cmd(struct io_uring_cmd *cmd, >> enum io_uring_cmd_flags flags) >> { >> struct block_device *bdev = I_BDEV(cmd->file->f_mapping->host); >> >> + switch (cmd->op) { >> + case BLOCK_URING_OP_IOCTL: >> + return blkdev_uring_ioctl(bdev, cmd); > > I don't think the two level dispatch here makes any sense. Then again At least it's in my plans to rework it a bit to resolve callbacks in advance and get rid of double dispatching (for some cases). Like struct io_cmd { void (*cb)(...); ... }; struct file_operations { struct io_cmd *get_cmd(...); }; // registration ctx->cmds[i] = file->get_cmd(...); And first we do registration, and then use it > I don't think this code makes sense either except as an example.. -- Pavel Begunkov