From patchwork Tue Sep 20 17:53:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 12982479 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64E3FC6FA82 for ; Tue, 20 Sep 2022 17:54:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230518AbiITRyG (ORCPT ); Tue, 20 Sep 2022 13:54:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231476AbiITRx4 (ORCPT ); Tue, 20 Sep 2022 13:53:56 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB64F101FC for ; Tue, 20 Sep 2022 10:53:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1663696435; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=oNM9autimC6RvLv11sl2gSLRIEAUQLnjCfK9GHsQmCY=; b=hIsMkLt8UPz4XCtK3u3MNg5QVgA24AGjV6I2QarZivt8B7V2z5zYqt7DALrjCHWcAF1qrM gHhb6rZAjJ5tvZaHK0C+hMunBngPzjH03fjqgox9q54iJTge1mEE3zFCbE0aDequJZWv0W 3aDuCiyDZ3DfyGJoWV1LlK9KsTJmBYg= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-255-ZVPtqo5iPcOgIsvrFogxLQ-1; Tue, 20 Sep 2022 13:53:50 -0400 X-MC-Unique: ZVPtqo5iPcOgIsvrFogxLQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1A9FE101A52A; Tue, 20 Sep 2022 17:53:50 +0000 (UTC) Received: from file01.intranet.prod.int.rdu2.redhat.com (file01.intranet.prod.int.rdu2.redhat.com [10.11.5.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0DD7440C6EC2; Tue, 20 Sep 2022 17:53:50 +0000 (UTC) Received: from file01.intranet.prod.int.rdu2.redhat.com (localhost [127.0.0.1]) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4) with ESMTP id 28KHroOC026300; Tue, 20 Sep 2022 13:53:50 -0400 Received: from localhost (mpatocka@localhost) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4/Submit) with ESMTP id 28KHrnsM026296; Tue, 20 Sep 2022 13:53:49 -0400 X-Authentication-Warning: file01.intranet.prod.int.rdu2.redhat.com: mpatocka owned process doing -bs Date: Tue, 20 Sep 2022 13:53:49 -0400 (EDT) From: Mikulas Patocka X-X-Sender: mpatocka@file01.intranet.prod.int.rdu2.redhat.com To: Jens Axboe , Zdenek Kabelac , Christoph Hellwig cc: linux-block@vger.kernel.org, dm-devel@redhat.com Subject: [PATCH v2 1/4] brd: make brd_insert_page return bool In-Reply-To: Message-ID: References: User-Agent: Alpine 2.02 (LRH 1266 2009-07-14) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org brd_insert_page returns a pointer to struct page, however the pointer is never used (it is only compared against NULL), so to clean-up the code, we make it return bool. Signed-off-by: Mikulas Patocka Reviewed-by: Christoph Hellwig Reviewed-by: Chaitanya Kulkarni --- drivers/block/brd.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) Index: linux-2.6/drivers/block/brd.c =================================================================== --- linux-2.6.orig/drivers/block/brd.c +++ linux-2.6/drivers/block/brd.c @@ -78,11 +78,11 @@ static struct page *brd_lookup_page(stru } /* - * Look up and return a brd's page for a given sector. - * If one does not exist, allocate an empty page, and insert that. Then - * return it. + * If the page exists, return true. + * If it does not exist, allocate an empty page, and insert that. Return true + * if the allocation was successful. */ -static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) +static bool brd_insert_page(struct brd_device *brd, sector_t sector) { pgoff_t idx; struct page *page; @@ -90,7 +90,7 @@ static struct page *brd_insert_page(stru page = brd_lookup_page(brd, sector); if (page) - return page; + return true; /* * Must use NOIO because we don't want to recurse back into the @@ -99,11 +99,11 @@ static struct page *brd_insert_page(stru gfp_flags = GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM; page = alloc_page(gfp_flags); if (!page) - return NULL; + return false; if (radix_tree_preload(GFP_NOIO)) { __free_page(page); - return NULL; + return false; } spin_lock(&brd->brd_lock); @@ -121,7 +121,7 @@ static struct page *brd_insert_page(stru radix_tree_preload_end(); - return page; + return true; } /* From patchwork Tue Sep 20 17:56:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 12982480 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3326AC54EE9 for ; Tue, 20 Sep 2022 17:56:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229741AbiITR4b (ORCPT ); Tue, 20 Sep 2022 13:56:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229488AbiITR4a (ORCPT ); Tue, 20 Sep 2022 13:56:30 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF766647F0 for ; Tue, 20 Sep 2022 10:56:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1663696589; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=G+VNMsk+ccruaO0KIV+Hh+rP04prTQH2VaURd0tqhBI=; b=FvCFSn9wJWh6nEEKmyWuoJriB2+PcJqBS+PoCkcQKOTTNaaMIeVb0QcI6TBL0BvldO8n+R LAULVcL6eaqnz9SWnscgfd5RlCI1TK1cMk6a0qBwwQY+4AeCXkT8RVJGob5cbt5d+mOahB nWkasVSmX1Eo0i+99DhhEDmvvlhAXes= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-119--4StJPtENLmlrG4ATPl-Lg-1; Tue, 20 Sep 2022 13:56:25 -0400 X-MC-Unique: -4StJPtENLmlrG4ATPl-Lg-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 676D1299E740; Tue, 20 Sep 2022 17:56:25 +0000 (UTC) Received: from file01.intranet.prod.int.rdu2.redhat.com (file01.intranet.prod.int.rdu2.redhat.com [10.11.5.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5BE8E49BB60; Tue, 20 Sep 2022 17:56:25 +0000 (UTC) Received: from file01.intranet.prod.int.rdu2.redhat.com (localhost [127.0.0.1]) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4) with ESMTP id 28KHuPYk026417; Tue, 20 Sep 2022 13:56:25 -0400 Received: from localhost (mpatocka@localhost) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4/Submit) with ESMTP id 28KHuPwW026413; Tue, 20 Sep 2022 13:56:25 -0400 X-Authentication-Warning: file01.intranet.prod.int.rdu2.redhat.com: mpatocka owned process doing -bs Date: Tue, 20 Sep 2022 13:56:25 -0400 (EDT) From: Mikulas Patocka X-X-Sender: mpatocka@file01.intranet.prod.int.rdu2.redhat.com To: Jens Axboe , Zdenek Kabelac , Christoph Hellwig cc: linux-block@vger.kernel.org, dm-devel@redhat.com Subject: [PATCH v2 2/4] brd: extend the rcu regions to cover read and write In-Reply-To: Message-ID: References: User-Agent: Alpine 2.02 (LRH 1266 2009-07-14) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org This patch extends the rcu regions, so that lookup followed by a read or write of a page is done inside rcu read lock. This si be needed for the following patch that enables discard. Note that we also replace "BUG_ON(!page);" with "if (page) ..." in copy_to_brd - the page may be NULL if write races with discard. In this situation, the result is undefined, so we can actually skip the write operation at all. Signed-off-by: Mikulas Patocka --- drivers/block/brd.c | 59 +++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 32 deletions(-) Index: linux-2.6/drivers/block/brd.c =================================================================== --- linux-2.6.orig/drivers/block/brd.c +++ linux-2.6/drivers/block/brd.c @@ -50,31 +50,12 @@ struct brd_device { /* * Look up and return a brd's page for a given sector. + * This must be called with the rcu lock held. */ static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector) { - pgoff_t idx; - struct page *page; - - /* - * The page lifetime is protected by the fact that we have opened the - * device node -- brd pages will never be deleted under us, so we - * don't need any further locking or refcounting. - * - * This is strictly true for the radix-tree nodes as well (ie. we - * don't actually need the rcu_read_lock()), however that is not a - * documented feature of the radix-tree API so it is better to be - * safe here (we don't have total exclusion from radix tree updates - * here, only deletes). - */ - rcu_read_lock(); - idx = sector >> PAGE_SECTORS_SHIFT; /* sector to page index */ - page = radix_tree_lookup(&brd->brd_pages, idx); - rcu_read_unlock(); - - BUG_ON(page && page->index != idx); - - return page; + pgoff_t idx = sector >> PAGE_SECTORS_SHIFT; /* sector to page index */ + return radix_tree_lookup(&brd->brd_pages, idx); } /* @@ -88,7 +69,9 @@ static bool brd_insert_page(struct brd_d struct page *page; gfp_t gfp_flags; + rcu_read_lock(); page = brd_lookup_page(brd, sector); + rcu_read_unlock(); if (page) return true; @@ -198,23 +181,29 @@ static void copy_to_brd(struct brd_devic size_t copy; copy = min_t(size_t, n, PAGE_SIZE - offset); - page = brd_lookup_page(brd, sector); - BUG_ON(!page); - dst = kmap_atomic(page); - memcpy(dst + offset, src, copy); - kunmap_atomic(dst); + rcu_read_lock(); + page = brd_lookup_page(brd, sector); + if (page) { + dst = kmap_atomic(page); + memcpy(dst + offset, src, copy); + kunmap_atomic(dst); + } + rcu_read_unlock(); if (copy < n) { src += copy; sector += copy >> SECTOR_SHIFT; copy = n - copy; - page = brd_lookup_page(brd, sector); - BUG_ON(!page); - dst = kmap_atomic(page); - memcpy(dst, src, copy); - kunmap_atomic(dst); + rcu_read_lock(); + page = brd_lookup_page(brd, sector); + if (page) { + dst = kmap_atomic(page); + memcpy(dst, src, copy); + kunmap_atomic(dst); + } + rcu_read_unlock(); } } @@ -230,6 +219,8 @@ static void copy_from_brd(void *dst, str size_t copy; copy = min_t(size_t, n, PAGE_SIZE - offset); + + rcu_read_lock(); page = brd_lookup_page(brd, sector); if (page) { src = kmap_atomic(page); @@ -237,11 +228,14 @@ static void copy_from_brd(void *dst, str kunmap_atomic(src); } else memset(dst, 0, copy); + rcu_read_unlock(); if (copy < n) { dst += copy; sector += copy >> SECTOR_SHIFT; copy = n - copy; + + rcu_read_lock(); page = brd_lookup_page(brd, sector); if (page) { src = kmap_atomic(page); @@ -249,6 +243,7 @@ static void copy_from_brd(void *dst, str kunmap_atomic(src); } else memset(dst, 0, copy); + rcu_read_unlock(); } } From patchwork Tue Sep 20 17:58:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 12982483 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24FC4C54EE9 for ; Tue, 20 Sep 2022 17:58:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229885AbiITR64 (ORCPT ); Tue, 20 Sep 2022 13:58:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229950AbiITR6z (ORCPT ); Tue, 20 Sep 2022 13:58:55 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8C2565540 for ; Tue, 20 Sep 2022 10:58:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1663696734; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Yo19XM/iIimPzZPnkTGgbhemyHu89K/JJjSJZr8d8Q8=; b=eXNhc28EHtJaa4g0YwLHxg2h3DGulBLnHQzAxTTmiKQ0f+JglQifZuiErPZCCwRb5Fzi8q LBu4gFgQGtuc2xQWdqHdP7ASrWqkMAPoEIV4mdG9/bBIwn8QjzHgXNXOeEod4b/DO8IOcE Q/URCWUfeokh+7eSUeAYVaS1MSkB4cw= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-488-Px68ixthMYG57Tx4Eu3Gsw-1; Tue, 20 Sep 2022 13:58:52 -0400 X-MC-Unique: Px68ixthMYG57Tx4Eu3Gsw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7E7193C10682; Tue, 20 Sep 2022 17:58:51 +0000 (UTC) Received: from file01.intranet.prod.int.rdu2.redhat.com (file01.intranet.prod.int.rdu2.redhat.com [10.11.5.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6EE642027061; Tue, 20 Sep 2022 17:58:51 +0000 (UTC) Received: from file01.intranet.prod.int.rdu2.redhat.com (localhost [127.0.0.1]) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4) with ESMTP id 28KHwp7U026565; Tue, 20 Sep 2022 13:58:51 -0400 Received: from localhost (mpatocka@localhost) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4/Submit) with ESMTP id 28KHwpHM026562; Tue, 20 Sep 2022 13:58:51 -0400 X-Authentication-Warning: file01.intranet.prod.int.rdu2.redhat.com: mpatocka owned process doing -bs Date: Tue, 20 Sep 2022 13:58:51 -0400 (EDT) From: Mikulas Patocka X-X-Sender: mpatocka@file01.intranet.prod.int.rdu2.redhat.com To: Jens Axboe , Zdenek Kabelac , Christoph Hellwig cc: linux-block@vger.kernel.org, dm-devel@redhat.com Subject: [PATCH v2 3/4] brd: enable discard In-Reply-To: Message-ID: References: User-Agent: Alpine 2.02 (LRH 1266 2009-07-14) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org This patch implements discard in the brd driver. We use RCU to free the page, so that if there are any concurrent readers or writes, they won't touch the page after it is freed. Signed-off-by: Mikulas Patocka --- drivers/block/brd.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) Index: linux-2.6/drivers/block/brd.c =================================================================== --- linux-2.6.orig/drivers/block/brd.c +++ linux-2.6/drivers/block/brd.c @@ -48,6 +48,8 @@ struct brd_device { u64 brd_nr_pages; }; +static bool discard; + /* * Look up and return a brd's page for a given sector. * This must be called with the rcu lock held. @@ -107,6 +109,25 @@ static bool brd_insert_page(struct brd_d return true; } +static void brd_free_page_rcu(struct rcu_head *head) +{ + struct page *page = container_of(head, struct page, rcu_head); + __free_page(page); +} + +static void brd_free_page(struct brd_device *brd, sector_t sector) +{ + struct page *page; + pgoff_t idx; + + spin_lock(&brd->brd_lock); + idx = sector >> PAGE_SECTORS_SHIFT; + page = radix_tree_delete(&brd->brd_pages, idx); + spin_unlock(&brd->brd_lock); + if (page) + call_rcu(&page->rcu_head, brd_free_page_rcu); +} + /* * Free all backing store pages and radix tree. This must only be called when * there are no other users of the device. @@ -277,13 +298,44 @@ out: return err; } +void brd_do_discard(struct brd_device *brd, struct bio *bio) +{ + sector_t sector, len, front_pad; + + if (unlikely(!discard)) { + bio->bi_status = BLK_STS_NOTSUPP; + return; + } + + sector = bio->bi_iter.bi_sector; + len = bio_sectors(bio); + front_pad = -sector & (PAGE_SECTORS - 1); + sector += front_pad; + if (unlikely(len <= front_pad)) + return; + len -= front_pad; + len = round_down(len, PAGE_SECTORS); + while (len) { + brd_free_page(brd, sector); + sector += PAGE_SECTORS; + len -= PAGE_SECTORS; + cond_resched(); + } +} + static void brd_submit_bio(struct bio *bio) { struct brd_device *brd = bio->bi_bdev->bd_disk->private_data; - sector_t sector = bio->bi_iter.bi_sector; + sector_t sector; struct bio_vec bvec; struct bvec_iter iter; + if (bio_op(bio) == REQ_OP_DISCARD) { + brd_do_discard(brd, bio); + goto endio; + } + + sector = bio->bi_iter.bi_sector; bio_for_each_segment(bvec, bio, iter) { unsigned int len = bvec.bv_len; int err; @@ -301,6 +353,7 @@ static void brd_submit_bio(struct bio *b sector += len >> SECTOR_SHIFT; } +endio: bio_endio(bio); } @@ -338,6 +391,10 @@ static int max_part = 1; module_param(max_part, int, 0444); MODULE_PARM_DESC(max_part, "Num Minors to reserve between devices"); +static bool discard = false; +module_param(discard, bool, 0444); +MODULE_PARM_DESC(discard, "Support discard"); + MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); MODULE_ALIAS("rd"); @@ -404,6 +461,11 @@ static int brd_alloc(int i) */ blk_queue_physical_block_size(disk->queue, PAGE_SIZE); + if (discard) { + disk->queue->limits.discard_granularity = PAGE_SIZE; + blk_queue_max_discard_sectors(disk->queue, UINT_MAX); + } + /* Tell the block layer that this is not a rotational device */ blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue); blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, disk->queue); From patchwork Tue Sep 20 17:59:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 12982484 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5AD5C6FA82 for ; Tue, 20 Sep 2022 17:59:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230315AbiITR7z (ORCPT ); Tue, 20 Sep 2022 13:59:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33132 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230283AbiITR7x (ORCPT ); Tue, 20 Sep 2022 13:59:53 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B7182127B for ; Tue, 20 Sep 2022 10:59:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1663696790; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=OHtdE23Tl8Q7YmGts8+e6vQU5dPp5gTmPaXstWBSt1Q=; b=McxVU7B4hkq91VeO+TrGAVSDlARbxz7dmjRwUOGGg28Xzufb8yWl3oLxfX+j4acuMUxYXi iElo3sDgDOfGTKVRT+7nn/IPvQFSADfJnl2RdIcSpsn9yUh684GjCQDgge1MPxj6fbk6LY vZvTTCALqOAw7jrTyi8cR+wJwq0Y8OY= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-663-EE1Nq2b8PFClrSMW4ir5Uw-1; Tue, 20 Sep 2022 13:59:46 -0400 X-MC-Unique: EE1Nq2b8PFClrSMW4ir5Uw-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2D5AF811E87; Tue, 20 Sep 2022 17:59:46 +0000 (UTC) Received: from file01.intranet.prod.int.rdu2.redhat.com (file01.intranet.prod.int.rdu2.redhat.com [10.11.5.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1AA98492CA2; Tue, 20 Sep 2022 17:59:46 +0000 (UTC) Received: from file01.intranet.prod.int.rdu2.redhat.com (localhost [127.0.0.1]) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4) with ESMTP id 28KHxk5j026622; Tue, 20 Sep 2022 13:59:46 -0400 Received: from localhost (mpatocka@localhost) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4/Submit) with ESMTP id 28KHxk9W026618; Tue, 20 Sep 2022 13:59:46 -0400 X-Authentication-Warning: file01.intranet.prod.int.rdu2.redhat.com: mpatocka owned process doing -bs Date: Tue, 20 Sep 2022 13:59:46 -0400 (EDT) From: Mikulas Patocka X-X-Sender: mpatocka@file01.intranet.prod.int.rdu2.redhat.com To: Jens Axboe , Zdenek Kabelac , Christoph Hellwig cc: linux-block@vger.kernel.org, dm-devel@redhat.com Subject: [PATCH v2 4/4] brd: implement secure erase and write zeroes In-Reply-To: Message-ID: References: User-Agent: Alpine 2.02 (LRH 1266 2009-07-14) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org 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 --- drivers/block/brd.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) 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 */