summaryrefslogtreecommitdiffstats
path: root/drivers/block/null_blk_main.c
diff options
context:
space:
mode:
authorAjay Joshi <ajay.joshi@wdc.com>2019-10-17 14:19:43 -0700
committerJens Axboe <axboe@kernel.dk>2019-10-17 19:01:22 -0600
commitdd85b4922de1b70f0729d2a7856db619e210a8ec (patch)
tree10baad9693e32ac04eafed70feef99317b6a8e1b /drivers/block/null_blk_main.c
parent45919fbfe1c487c17ea1d198534339a5e8abeae3 (diff)
downloadlinux-dd85b4922de1b70f0729d2a7856db619e210a8ec.tar.bz2
null_blk: return fixed zoned reads > write pointer
A zoned block device maintains a write pointer within a zone, and reads beyond the write pointer are undefined. Fill data buffer returned above the write pointer with 0xFF. Signed-off-by: Ajay Joshi <ajay.joshi@wdc.com> Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com> Reviewed-by: Matias Bjørling <matias.bjorling@wdc.com> Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/null_blk_main.c')
-rw-r--r--drivers/block/null_blk_main.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c
index f5e0dffb4624..ea7a4d6b7848 100644
--- a/drivers/block/null_blk_main.c
+++ b/drivers/block/null_blk_main.c
@@ -1022,6 +1022,16 @@ next:
return 0;
}
+static void nullb_fill_pattern(struct nullb *nullb, struct page *page,
+ unsigned int len, unsigned int off)
+{
+ void *dst;
+
+ dst = kmap_atomic(page);
+ memset(dst + off, 0xFF, len);
+ kunmap_atomic(dst);
+}
+
static void null_handle_discard(struct nullb *nullb, sector_t sector, size_t n)
{
size_t temp;
@@ -1062,10 +1072,24 @@ static int null_transfer(struct nullb *nullb, struct page *page,
unsigned int len, unsigned int off, bool is_write, sector_t sector,
bool is_fua)
{
+ struct nullb_device *dev = nullb->dev;
+ unsigned int valid_len = len;
int err = 0;
if (!is_write) {
- err = copy_from_nullb(nullb, page, off, sector, len);
+ if (dev->zoned)
+ valid_len = null_zone_valid_read_len(nullb,
+ sector, len);
+
+ if (valid_len) {
+ err = copy_from_nullb(nullb, page, off,
+ sector, valid_len);
+ off += valid_len;
+ len -= valid_len;
+ }
+
+ if (len)
+ nullb_fill_pattern(nullb, page, len, off);
flush_dcache_page(page);
} else {
flush_dcache_page(page);