All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrey Albershteyn <aalbersh@redhat.com>
To: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	fsverity@lists.linux.dev
Cc: djwong@kernel.org, ebiggers@kernel.org, david@fromorbit.com,
	dchinner@redhat.com, Andrey Albershteyn <aalbersh@redhat.com>
Subject: [PATCH v3 07/28] fsverity: always use bitmap to track verified status
Date: Fri,  6 Oct 2023 20:49:01 +0200	[thread overview]
Message-ID: <20231006184922.252188-8-aalbersh@redhat.com> (raw)
In-Reply-To: <20231006184922.252188-1-aalbersh@redhat.com>

The bitmap is used to track verified status of the Merkle tree
blocks which are smaller than a PAGE. Blocks which fits exactly in a
page - use PageChecked() for tracking "verified" status.

This patch switches to always use bitmap to track verified status.
This is needed to move fs-verity away from page management and work
only with Merkle tree blocks.

Also, this patch removes spinlock. The lock was used to reset bits
in bitmap belonging to one page. This patch works only with one
Merkle tree block and won't reset other blocks status.

Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---
 fs/verity/fsverity_private.h |  1 -
 fs/verity/open.c             | 49 ++++++++++++-------------
 fs/verity/verify.c           | 71 +++++-------------------------------
 3 files changed, 33 insertions(+), 88 deletions(-)

diff --git a/fs/verity/fsverity_private.h b/fs/verity/fsverity_private.h
index d071a6e32581..9611eeae3527 100644
--- a/fs/verity/fsverity_private.h
+++ b/fs/verity/fsverity_private.h
@@ -69,7 +69,6 @@ struct fsverity_info {
 	u8 file_digest[FS_VERITY_MAX_DIGEST_SIZE];
 	const struct inode *inode;
 	unsigned long *hash_block_verified;
-	spinlock_t hash_page_init_lock;
 };
 
 #define FS_VERITY_MAX_SIGNATURE_SIZE	(FS_VERITY_MAX_DESCRIPTOR_SIZE - \
diff --git a/fs/verity/open.c b/fs/verity/open.c
index 6c31a871b84b..dfb9fe6aaae9 100644
--- a/fs/verity/open.c
+++ b/fs/verity/open.c
@@ -182,6 +182,7 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode,
 {
 	struct fsverity_info *vi;
 	int err;
+	unsigned long num_bits;
 
 	vi = kmem_cache_zalloc(fsverity_info_cachep, GFP_KERNEL);
 	if (!vi)
@@ -213,33 +214,29 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode,
 	if (err)
 		goto fail;
 
-	if (vi->tree_params.block_size != PAGE_SIZE) {
-		/*
-		 * When the Merkle tree block size and page size differ, we use
-		 * a bitmap to keep track of which hash blocks have been
-		 * verified.  This bitmap must contain one bit per hash block,
-		 * including alignment to a page boundary at the end.
-		 *
-		 * Eventually, to support extremely large files in an efficient
-		 * way, it might be necessary to make pages of this bitmap
-		 * reclaimable.  But for now, simply allocating the whole bitmap
-		 * is a simple solution that works well on the files on which
-		 * fsverity is realistically used.  E.g., with SHA-256 and 4K
-		 * blocks, a 100MB file only needs a 24-byte bitmap, and the
-		 * bitmap for any file under 17GB fits in a 4K page.
-		 */
-		unsigned long num_bits =
-			vi->tree_params.tree_pages <<
-			vi->tree_params.log_blocks_per_page;
+	/*
+	 * We use a bitmap to keep track of which hash blocks have been
+	 * verified.  This bitmap must contain one bit per hash block,
+	 * including alignment to a page boundary at the end.
+	 *
+	 * Eventually, to support extremely large files in an efficient
+	 * way, it might be necessary to make pages of this bitmap
+	 * reclaimable.  But for now, simply allocating the whole bitmap
+	 * is a simple solution that works well on the files on which
+	 * fsverity is realistically used.  E.g., with SHA-256 and 4K
+	 * blocks, a 100MB file only needs a 24-byte bitmap, and the
+	 * bitmap for any file under 17GB fits in a 4K page.
+	 */
+	num_bits =
+		vi->tree_params.tree_pages <<
+		vi->tree_params.log_blocks_per_page;
 
-		vi->hash_block_verified = kvcalloc(BITS_TO_LONGS(num_bits),
-						   sizeof(unsigned long),
-						   GFP_KERNEL);
-		if (!vi->hash_block_verified) {
-			err = -ENOMEM;
-			goto fail;
-		}
-		spin_lock_init(&vi->hash_page_init_lock);
+	vi->hash_block_verified = kvcalloc(BITS_TO_LONGS(num_bits),
+					   sizeof(unsigned long),
+					   GFP_KERNEL);
+	if (!vi->hash_block_verified) {
+		err = -ENOMEM;
+		goto fail;
 	}
 
 	return vi;
diff --git a/fs/verity/verify.c b/fs/verity/verify.c
index 2fe7bd57b16e..e7b13d143ae9 100644
--- a/fs/verity/verify.c
+++ b/fs/verity/verify.c
@@ -13,69 +13,18 @@
 static struct workqueue_struct *fsverity_read_workqueue;
 
 /*
- * Returns true if the hash block with index @hblock_idx in the tree, located in
- * @hpage, has already been verified.
+ * Returns true if the hash block with index @hblock_idx in the tree has
+ * already been verified.
  */
-static bool is_hash_block_verified(struct fsverity_info *vi, struct page *hpage,
-				   unsigned long hblock_idx)
+static bool is_hash_block_verified(struct fsverity_info *vi,
+				   unsigned long hblock_idx,
+				   bool block_cached)
 {
-	bool verified;
-	unsigned int blocks_per_page;
-	unsigned int i;
-
-	/*
-	 * When the Merkle tree block size and page size are the same, then the
-	 * ->hash_block_verified bitmap isn't allocated, and we use PG_checked
-	 * to directly indicate whether the page's block has been verified.
-	 *
-	 * Using PG_checked also guarantees that we re-verify hash pages that
-	 * get evicted and re-instantiated from the backing storage, as new
-	 * pages always start out with PG_checked cleared.
-	 */
-	if (!vi->hash_block_verified)
-		return PageChecked(hpage);
-
-	/*
-	 * When the Merkle tree block size and page size differ, we use a bitmap
-	 * to indicate whether each hash block has been verified.
-	 *
-	 * However, we still need to ensure that hash pages that get evicted and
-	 * re-instantiated from the backing storage are re-verified.  To do
-	 * this, we use PG_checked again, but now it doesn't really mean
-	 * "checked".  Instead, now it just serves as an indicator for whether
-	 * the hash page is newly instantiated or not.
-	 *
-	 * The first thread that sees PG_checked=0 must clear the corresponding
-	 * bitmap bits, then set PG_checked=1.  This requires a spinlock.  To
-	 * avoid having to take this spinlock in the common case of
-	 * PG_checked=1, we start with an opportunistic lockless read.
-	 */
-	if (PageChecked(hpage)) {
-		/*
-		 * A read memory barrier is needed here to give ACQUIRE
-		 * semantics to the above PageChecked() test.
-		 */
-		smp_rmb();
+	if (block_cached)
 		return test_bit(hblock_idx, vi->hash_block_verified);
-	}
-	spin_lock(&vi->hash_page_init_lock);
-	if (PageChecked(hpage)) {
-		verified = test_bit(hblock_idx, vi->hash_block_verified);
-	} else {
-		blocks_per_page = vi->tree_params.blocks_per_page;
-		hblock_idx = round_down(hblock_idx, blocks_per_page);
-		for (i = 0; i < blocks_per_page; i++)
-			clear_bit(hblock_idx + i, vi->hash_block_verified);
-		/*
-		 * A write memory barrier is needed here to give RELEASE
-		 * semantics to the below SetPageChecked() operation.
-		 */
-		smp_wmb();
-		SetPageChecked(hpage);
-		verified = false;
-	}
-	spin_unlock(&vi->hash_page_init_lock);
-	return verified;
+
+	clear_bit(hblock_idx, vi->hash_block_verified);
+	return false;
 }
 
 /*
@@ -179,7 +128,7 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
 			goto error;
 		}
 		haddr = kmap_local_page(hpage) + hblock_offset_in_page;
-		if (is_hash_block_verified(vi, hpage, hblock_idx)) {
+		if (is_hash_block_verified(vi, hblock_idx, PageChecked(hpage))) {
 			memcpy(_want_hash, haddr + hoffset, hsize);
 			want_hash = _want_hash;
 			kunmap_local(haddr);
-- 
2.40.1


  parent reply	other threads:[~2023-10-06 18:52 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-06 18:48 [PATCH v3 00/28] fs-verity support for XFS Andrey Albershteyn
2023-10-06 18:48 ` [PATCH v3 01/28] xfs: Add new name to attri/d Andrey Albershteyn
2023-10-06 18:48 ` [PATCH v3 02/28] xfs: add parent pointer support to attribute code Andrey Albershteyn
2023-10-06 18:48 ` [PATCH v3 03/28] xfs: define parent pointer xattr format Andrey Albershteyn
2023-10-06 18:48 ` [PATCH v3 04/28] xfs: Add xfs_verify_pptr Andrey Albershteyn
2023-10-11  1:01   ` Darrick J. Wong
2023-10-11 11:09     ` Andrey Albershteyn
2023-10-06 18:48 ` [PATCH v3 05/28] fs: add FS_XFLAG_VERITY for fs-verity sealed inodes Andrey Albershteyn
2023-10-11  4:05   ` Eric Biggers
2023-10-11 11:06     ` Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 06/28] fsverity: add drop_page() callout Andrey Albershteyn
2023-10-11  3:06   ` Eric Biggers
2023-10-11 11:11     ` Andrey Albershteyn
2023-10-06 18:49 ` Andrey Albershteyn [this message]
2023-10-11  3:15   ` [PATCH v3 07/28] fsverity: always use bitmap to track verified status Eric Biggers
2023-10-11 13:03     ` Andrey Albershteyn
2023-10-12  7:27       ` Eric Biggers
2023-10-13  3:12         ` Darrick J. Wong
2023-10-17  4:58           ` Eric Biggers
2023-10-18  2:35             ` Darrick J. Wong
2023-10-17  6:01           ` Christoph Hellwig
2023-10-16 11:52         ` Andrey Albershteyn
2023-10-17  5:57         ` Christoph Hellwig
2023-10-17 17:49           ` Eric Biggers
2023-10-06 18:49 ` [PATCH v3 08/28] fsverity: pass Merkle tree block size to ->read_merkle_tree_page() Andrey Albershteyn
2023-10-11  3:17   ` Eric Biggers
2023-10-11 11:13     ` Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 09/28] fsverity: pass log_blocksize to end_enable_verity() Andrey Albershteyn
2023-10-11  3:19   ` Eric Biggers
2023-10-11 11:17     ` Andrey Albershteyn
2023-10-12  7:34       ` Eric Biggers
2023-10-06 18:49 ` [PATCH v3 10/28] fsverity: operate with Merkle tree blocks instead of pages Andrey Albershteyn
2023-10-07  4:02   ` kernel test robot
2023-10-11  3:56   ` Eric Biggers
2023-10-16 13:00   ` Christoph Hellwig
2023-10-06 18:49 ` [PATCH v3 11/28] iomap: pass readpage operation to read path Andrey Albershteyn
2023-10-11 18:31   ` Darrick J. Wong
2023-10-16 12:35     ` Andrey Albershteyn
2023-10-16  9:15   ` Christoph Hellwig
2023-10-16 12:32     ` Andrey Albershteyn
2023-10-16 12:58       ` Christoph Hellwig
2023-10-06 18:49 ` [PATCH v3 12/28] iomap: allow filesystem to implement read path verification Andrey Albershteyn
2023-10-11 18:39   ` Darrick J. Wong
2023-10-06 18:49 ` [PATCH v3 13/28] xfs: add XBF_VERITY_CHECKED xfs_buf flag Andrey Albershteyn
2023-10-11 18:54   ` Darrick J. Wong
2023-10-06 18:49 ` [PATCH v3 14/28] xfs: add XFS_DA_OP_BUFFER to make xfs_attr_get() return buffer Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 15/28] xfs: introduce workqueue for post read IO work Andrey Albershteyn
2023-10-11 18:55   ` Darrick J. Wong
2023-10-16 12:37     ` Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 16/28] xfs: add bio_set and submit_io for ioend post-processing Andrey Albershteyn
2023-10-11 18:47   ` Darrick J. Wong
2023-10-06 18:49 ` [PATCH v3 17/28] xfs: add attribute type for fs-verity Andrey Albershteyn
2023-10-11 18:48   ` Darrick J. Wong
2023-10-06 18:49 ` [PATCH v3 18/28] xfs: make xfs_buf_get() to take XBF_* flags Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 19/28] xfs: add XBF_DOUBLE_ALLOC to increase size of the buffer Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 20/28] xfs: add fs-verity ro-compat flag Andrey Albershteyn
2023-10-11 18:56   ` Darrick J. Wong
2023-10-06 18:49 ` [PATCH v3 21/28] xfs: add inode on-disk VERITY flag Andrey Albershteyn
2023-10-11 18:57   ` Darrick J. Wong
2023-10-06 18:49 ` [PATCH v3 22/28] xfs: initialize fs-verity on file open and cleanup on inode destruction Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 23/28] xfs: don't allow to enable DAX on fs-verity sealsed inode Andrey Albershteyn
2023-10-11 19:00   ` Darrick J. Wong
2023-10-06 18:49 ` [PATCH v3 24/28] xfs: disable direct read path for fs-verity sealed files Andrey Albershteyn
2023-10-11 19:02   ` Darrick J. Wong
2023-10-06 18:49 ` [PATCH v3 25/28] xfs: add fs-verity support Andrey Albershteyn
2023-10-06 23:40   ` kernel test robot
2023-10-11  1:39   ` Darrick J. Wong
2023-10-11 14:36     ` Andrey Albershteyn
2023-10-18 19:18   ` kernel test robot
2023-10-06 18:49 ` [PATCH v3 26/28] xfs: make scrub aware of verity dinode flag Andrey Albershteyn
2023-10-11  1:06   ` Darrick J. Wong
2023-10-11 14:37     ` Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 27/28] xfs: add fs-verity ioctls Andrey Albershteyn
2023-10-06 18:49 ` [PATCH v3 28/28] xfs: enable ro-compat fs-verity flag Andrey Albershteyn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231006184922.252188-8-aalbersh@redhat.com \
    --to=aalbersh@redhat.com \
    --cc=david@fromorbit.com \
    --cc=dchinner@redhat.com \
    --cc=djwong@kernel.org \
    --cc=ebiggers@kernel.org \
    --cc=fsverity@lists.linux.dev \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.