Message ID | alpine.LRH.2.02.2209201358580.26535@file01.intranet.prod.int.rdu2.redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | brd: implement discard | expand |
> /* > @@ -300,23 +303,34 @@ out: > > void brd_do_discard(struct brd_device *brd, struct bio *bio) > { > - sector_t sector, len, front_pad; > + bool zero_padding; > + sector_t sector, len, front_pad, end_pad; > > if (unlikely(!discard)) { > bio->bi_status = BLK_STS_NOTSUPP; > return; > } > > + zero_padding = bio_op(bio) == REQ_OP_SECURE_ERASE || bio_op(bio) == REQ_OP_WRITE_ZEROES; > sector = bio->bi_iter.bi_sector; > len = bio_sectors(bio); > front_pad = -sector & (PAGE_SECTORS - 1); > + > + if (zero_padding && unlikely(front_pad != 0)) > + copy_to_brd(brd, page_address(ZERO_PAGE(0)), sector, min(len, front_pad) << SECTOR_SHIFT); > + > sector += front_pad; > if (unlikely(len <= front_pad)) > return; > len -= front_pad; > - len = round_down(len, PAGE_SECTORS); > + > + end_pad = len & (PAGE_SECTORS - 1); > + if (zero_padding && unlikely(end_pad != 0)) > + copy_to_brd(brd, page_address(ZERO_PAGE(0)), sector + len - end_pad, end_pad << SECTOR_SHIFT); > + len -= end_pad; > + > Is it possible to avoid these long lines ? -ck
> @@ -330,7 +344,9 @@ static void brd_submit_bio(struct bio *b > struct bio_vec bvec; > struct bvec_iter iter; > > - if (bio_op(bio) == REQ_OP_DISCARD) { > + if (bio_op(bio) == REQ_OP_DISCARD || > + bio_op(bio) == REQ_OP_SECURE_ERASE || > + bio_op(bio) == REQ_OP_WRITE_ZEROES) { > brd_do_discard(brd, bio); > goto endio; > } > @@ -464,6 +480,8 @@ static int brd_alloc(int i) > if (discard) { > disk->queue->limits.discard_granularity = PAGE_SIZE; > blk_queue_max_discard_sectors(disk->queue, UINT_MAX); > + blk_queue_max_write_zeroes_sectors(disk->queue, UINT_MAX); > + blk_queue_max_secure_erase_sectors(disk->queue, UINT_MAX); > } > The previous patch has the following description for the discard module param: MODULE_PARM_DESC(discard, "Support discard"); But you are reusing it here to enable write zeroes and sec erase. MODULE_PARM_DESC's "desc" parameter also needs to be updated in this patch. I understand that all these operations kind of do the same thing at the end, so it is upto you to decide if you want to add individual module param for each operation or club them together as you have done here. If you do the latter, then changing the module param variable `discard` to something more generic would give more clarity as well.
On Tue, Sep 20, 2022 at 01:59:46PM -0400, Mikulas Patocka wrote: > This patch implements REQ_OP_SECURE_ERASE and REQ_OP_WRITE_ZEROES on brd. > Write zeroes will free the pages just like discard, but the difference is > that it writes zeroes to the preceding and following page if the range is > not aligned on page boundary. Secure erase is just like write zeroes, > except that it clears the page content before freeing the page. So while I can see the use case for the simple discard you mentioned, and maybe even the WRITE_ZEROES, I'd rather have a really good justification for REQ_OP_SECURE_ERASE. It is a bad interface, and there are alsmost no good reasons for ever using it. So sprinkling it in random drivers just we can is not helpful.
Index: linux-2.6/drivers/block/brd.c =================================================================== --- linux-2.6.orig/drivers/block/brd.c +++ linux-2.6/drivers/block/brd.c @@ -115,7 +115,7 @@ static void brd_free_page_rcu(struct rcu __free_page(page); } -static void brd_free_page(struct brd_device *brd, sector_t sector) +static void brd_free_page(struct brd_device *brd, sector_t sector, bool secure) { struct page *page; pgoff_t idx; @@ -124,8 +124,11 @@ static void brd_free_page(struct brd_dev idx = sector >> PAGE_SECTORS_SHIFT; page = radix_tree_delete(&brd->brd_pages, idx); spin_unlock(&brd->brd_lock); - if (page) + if (page) { + if (secure) + clear_highpage(page); call_rcu(&page->rcu_head, brd_free_page_rcu); + } } /* @@ -300,23 +303,34 @@ out: void brd_do_discard(struct brd_device *brd, struct bio *bio) { - sector_t sector, len, front_pad; + bool zero_padding; + sector_t sector, len, front_pad, end_pad; if (unlikely(!discard)) { bio->bi_status = BLK_STS_NOTSUPP; return; } + zero_padding = bio_op(bio) == REQ_OP_SECURE_ERASE || bio_op(bio) == REQ_OP_WRITE_ZEROES; sector = bio->bi_iter.bi_sector; len = bio_sectors(bio); front_pad = -sector & (PAGE_SECTORS - 1); + + if (zero_padding && unlikely(front_pad != 0)) + copy_to_brd(brd, page_address(ZERO_PAGE(0)), sector, min(len, front_pad) << SECTOR_SHIFT); + sector += front_pad; if (unlikely(len <= front_pad)) return; len -= front_pad; - len = round_down(len, PAGE_SECTORS); + + end_pad = len & (PAGE_SECTORS - 1); + if (zero_padding && unlikely(end_pad != 0)) + copy_to_brd(brd, page_address(ZERO_PAGE(0)), sector + len - end_pad, end_pad << SECTOR_SHIFT); + len -= end_pad; + while (len) { - brd_free_page(brd, sector); + brd_free_page(brd, sector, bio_op(bio) == REQ_OP_SECURE_ERASE); sector += PAGE_SECTORS; len -= PAGE_SECTORS; cond_resched(); @@ -330,7 +344,9 @@ static void brd_submit_bio(struct bio *b struct bio_vec bvec; struct bvec_iter iter; - if (bio_op(bio) == REQ_OP_DISCARD) { + if (bio_op(bio) == REQ_OP_DISCARD || + bio_op(bio) == REQ_OP_SECURE_ERASE || + bio_op(bio) == REQ_OP_WRITE_ZEROES) { brd_do_discard(brd, bio); goto endio; } @@ -464,6 +480,8 @@ static int brd_alloc(int i) if (discard) { disk->queue->limits.discard_granularity = PAGE_SIZE; blk_queue_max_discard_sectors(disk->queue, UINT_MAX); + blk_queue_max_write_zeroes_sectors(disk->queue, UINT_MAX); + blk_queue_max_secure_erase_sectors(disk->queue, UINT_MAX); } /* Tell the block layer that this is not a rotational device */
This patch implements REQ_OP_SECURE_ERASE and REQ_OP_WRITE_ZEROES on brd. Write zeroes will free the pages just like discard, but the difference is that it writes zeroes to the preceding and following page if the range is not aligned on page boundary. Secure erase is just like write zeroes, except that it clears the page content before freeing the page. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> --- drivers/block/brd.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-)