[PATCH 1/3] fs,block: Introduce IOCB_ZONE_APPEND and direct-io handling
From: Kanchan Joshi <hidden>
Date: 2020-06-17 17:27:11
Also in:
io-uring, linux-fsdevel, lkml
Subsystem:
filesystems (vfs and infrastructure), the rest · Maintainers:
Alexander Viro, Christian Brauner, Linus Torvalds
From: Selvakumar S <redacted> Introduce IOCB_ZONE_APPEND flag, which is set in kiocb->ki_flags for zone-append. Direct I/O submission path uses this flag to send bio with append op. And completion path uses the same to return zone-relative offset to upper layer. Signed-off-by: SelvaKumar S <redacted> Signed-off-by: Kanchan Joshi <redacted> Signed-off-by: Nitesh Shetty <redacted> Signed-off-by: Javier Gonzalez <redacted> --- fs/block_dev.c | 19 ++++++++++++++++++- include/linux/fs.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 47860e5..4c84b4d0 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c@@ -185,6 +185,10 @@ static unsigned int dio_bio_write_op(struct kiocb *iocb) /* avoid the need for a I/O completion work item */ if (iocb->ki_flags & IOCB_DSYNC) op |= REQ_FUA; +#ifdef CONFIG_BLK_DEV_ZONED + if (iocb->ki_flags & IOCB_ZONE_APPEND) + op |= REQ_OP_ZONE_APPEND | REQ_NOMERGE; +#endif return op; }
@@ -295,6 +299,14 @@ static int blkdev_iopoll(struct kiocb *kiocb, bool wait) return blk_poll(q, READ_ONCE(kiocb->ki_cookie), wait); } +#ifdef CONFIG_BLK_DEV_ZONED +static inline long blkdev_bio_end_io_append(struct bio *bio) +{ + return (bio->bi_iter.bi_sector % + blk_queue_zone_sectors(bio->bi_disk->queue)) << SECTOR_SHIFT; +} +#endif + static void blkdev_bio_end_io(struct bio *bio) { struct blkdev_dio *dio = bio->bi_private;
@@ -307,15 +319,20 @@ static void blkdev_bio_end_io(struct bio *bio) if (!dio->is_sync) { struct kiocb *iocb = dio->iocb; ssize_t ret; + long res = 0; if (likely(!dio->bio.bi_status)) { ret = dio->size; iocb->ki_pos += ret; +#ifdef CONFIG_BLK_DEV_ZONED + if (iocb->ki_flags & IOCB_ZONE_APPEND) + res = blkdev_bio_end_io_append(bio); +#endif } else { ret = blk_status_to_errno(dio->bio.bi_status); } - dio->iocb->ki_complete(iocb, ret, 0); + dio->iocb->ki_complete(iocb, ret, res); if (dio->multi_bio) bio_put(&dio->bio); } else {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6c4ab4d..dc547b9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h@@ -315,6 +315,7 @@ enum rw_hint { #define IOCB_SYNC (1 << 5) #define IOCB_WRITE (1 << 6) #define IOCB_NOWAIT (1 << 7) +#define IOCB_ZONE_APPEND (1 << 8) struct kiocb { struct file *ki_filp;
--
2.7.4