Message ID | 20181204233729.26776-4-axboe@kernel.dk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/26] fs: add an iopoll method to struct file_operations | expand |
Jens Axboe <axboe@kernel.dk> writes: > From: Christoph Hellwig <hch@lst.de> > > Just call blk_poll on the iocb cookie, we can derive the block device > from the inode trivially. Does this work for multi-device file systems? -Jeff > > Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> > Signed-off-by: Christoph Hellwig <hch@lst.de> > Signed-off-by: Jens Axboe <axboe@kernel.dk> > --- > fs/block_dev.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/fs/block_dev.c b/fs/block_dev.c > index e1886cc7048f..6de8d35f6e41 100644 > --- a/fs/block_dev.c > +++ b/fs/block_dev.c > @@ -281,6 +281,14 @@ struct blkdev_dio { > > static struct bio_set blkdev_dio_pool; > > +static int blkdev_iopoll(struct kiocb *kiocb, bool wait) > +{ > + struct block_device *bdev = I_BDEV(kiocb->ki_filp->f_mapping->host); > + struct request_queue *q = bdev_get_queue(bdev); > + > + return blk_poll(q, READ_ONCE(kiocb->ki_cookie), wait); > +} > + > static void blkdev_bio_end_io(struct bio *bio) > { > struct blkdev_dio *dio = bio->bi_private; > @@ -398,6 +406,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) > bio->bi_opf |= REQ_HIPRI; > > qc = submit_bio(bio); > + WRITE_ONCE(iocb->ki_cookie, qc); > break; > } > > @@ -2070,6 +2079,7 @@ const struct file_operations def_blk_fops = { > .llseek = block_llseek, > .read_iter = blkdev_read_iter, > .write_iter = blkdev_write_iter, > + .iopoll = blkdev_iopoll, > .mmap = generic_file_mmap, > .fsync = blkdev_fsync, > .unlocked_ioctl = block_ioctl,
On 12/6/18 12:11 PM, Jeff Moyer wrote: > Jens Axboe <axboe@kernel.dk> writes: > >> From: Christoph Hellwig <hch@lst.de> >> >> Just call blk_poll on the iocb cookie, we can derive the block device >> from the inode trivially. > > Does this work for multi-device file systems? It should, that's the whole purpose of having fops->iopoll. You should be able to derive it from inode + cookie.
On Thu, Dec 06, 2018 at 12:14:29PM -0700, Jens Axboe wrote: > On 12/6/18 12:11 PM, Jeff Moyer wrote: > > Jens Axboe <axboe@kernel.dk> writes: > > > >> From: Christoph Hellwig <hch@lst.de> > >> > >> Just call blk_poll on the iocb cookie, we can derive the block device > >> from the inode trivially. > > > > Does this work for multi-device file systems? > > It should, that's the whole purpose of having fops->iopoll. You should > be able to derive it from inode + cookie. It still assumes the whole I/O will got to a single device. For XFS this is always tree, but for btrfs this might mean I/O could need splitting if ->iopoll was to be supported there.
On 12/6/18 12:15 PM, Christoph Hellwig wrote: > On Thu, Dec 06, 2018 at 12:14:29PM -0700, Jens Axboe wrote: >> On 12/6/18 12:11 PM, Jeff Moyer wrote: >>> Jens Axboe <axboe@kernel.dk> writes: >>> >>>> From: Christoph Hellwig <hch@lst.de> >>>> >>>> Just call blk_poll on the iocb cookie, we can derive the block device >>>> from the inode trivially. >>> >>> Does this work for multi-device file systems? >> >> It should, that's the whole purpose of having fops->iopoll. You should >> be able to derive it from inode + cookie. > > It still assumes the whole I/O will got to a single device. For > XFS this is always tree, but for btrfs this might mean I/O could > need splitting if ->iopoll was to be supported there. Right, we can only support one target for one particular piece of IO, but multi-device works fine in general.
diff --git a/fs/block_dev.c b/fs/block_dev.c index e1886cc7048f..6de8d35f6e41 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -281,6 +281,14 @@ struct blkdev_dio { static struct bio_set blkdev_dio_pool; +static int blkdev_iopoll(struct kiocb *kiocb, bool wait) +{ + struct block_device *bdev = I_BDEV(kiocb->ki_filp->f_mapping->host); + struct request_queue *q = bdev_get_queue(bdev); + + return blk_poll(q, READ_ONCE(kiocb->ki_cookie), wait); +} + static void blkdev_bio_end_io(struct bio *bio) { struct blkdev_dio *dio = bio->bi_private; @@ -398,6 +406,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) bio->bi_opf |= REQ_HIPRI; qc = submit_bio(bio); + WRITE_ONCE(iocb->ki_cookie, qc); break; } @@ -2070,6 +2079,7 @@ const struct file_operations def_blk_fops = { .llseek = block_llseek, .read_iter = blkdev_read_iter, .write_iter = blkdev_write_iter, + .iopoll = blkdev_iopoll, .mmap = generic_file_mmap, .fsync = blkdev_fsync, .unlocked_ioctl = block_ioctl,