On 17/06/2020 20:23, Kanchan Joshi wrote: > From: Selvakumar S <selvakuma.s1@xxxxxxxxxxx> > > 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 <selvakuma.s1@xxxxxxxxxxx> > Signed-off-by: Kanchan Joshi <joshi.k@xxxxxxxxxxx> > Signed-off-by: Nitesh Shetty <nj.shetty@xxxxxxxxxxx> > Signed-off-by: Javier Gonzalez <javier.gonz@xxxxxxxxxxx> > --- > 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; IIRC, zone_size is pow2 and bit operations should suffice. Anyway, this can use a temporary variable. > +} > +#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; > -- Pavel Begunkov