On 2024-03-17 09:33:34, Darrick J. Wong wrote: > From: Darrick J. Wong <djwong@xxxxxxxxxx> > > Now that fsverity tells our merkle tree io functions about what a hash > of a data block full of zeroes looks like, we can use this information > to avoid writing out merkle tree blocks for sparse regions of the file. > For verified gold master images this can save quite a bit of overhead. > > Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> Looks good to me: Reviewed-by: Andrey Albershteyn <aalbersh@xxxxxxxxxx> > --- > fs/xfs/xfs_verity.c | 37 ++++++++++++++++++++++++++++++++++--- > 1 file changed, 34 insertions(+), 3 deletions(-) > > > diff --git a/fs/xfs/xfs_verity.c b/fs/xfs/xfs_verity.c > index abd95bc1ba6e..ba96e7049f61 100644 > --- a/fs/xfs/xfs_verity.c > +++ b/fs/xfs/xfs_verity.c > @@ -619,6 +619,20 @@ xfs_verity_read_merkle( > xfs_verity_merkle_key_to_disk(&name, block->offset); > > error = xfs_attr_get(&args); > + if (error == -ENOATTR) { > + u8 *p; > + unsigned int i; > + > + /* > + * No attribute found. Synthesize a buffer full of the zero > + * digests on the assumption that we elided them at write time. > + */ > + for (i = 0, p = new_mk->data; > + i < block->size; > + i += req->digest_size, p += req->digest_size) > + memcpy(p, req->zero_digest, req->digest_size); > + error = 0; > + } > if (error) > goto out_new_mk; > > @@ -676,12 +690,29 @@ xfs_verity_write_merkle( > .value = (void *)buf, > .valuelen = size, > }; > - const char *p = buf + size - 1; > + const char *p; > + unsigned int i; > > - /* Don't store trailing zeroes. */ > + /* > + * If this is a block full of hashes of zeroed blocks, don't bother > + * storing the block. We can synthesize them later. > + */ > + for (i = 0, p = buf; > + i < size; > + i += req->digest_size, p += req->digest_size) > + if (memcmp(p, req->zero_digest, req->digest_size)) > + break; > + if (i == size) > + return 0; > + > + /* > + * Don't store trailing zeroes. Store at least one byte so that the > + * block cannot be mistaken for an elided one. > + */ > + p = buf + size - 1; > while (p >= (const char *)buf && *p == 0) > p--; > - args.valuelen = p - (const char *)buf + 1; > + args.valuelen = max(1, p - (const char *)buf + 1); > > xfs_verity_merkle_key_to_disk(&name, pos); > return xfs_attr_set(&args); > -- - Andrey