Skip to content

Commit

Permalink
erofs: Support the new bloom filter erofs compat feature
Browse files Browse the repository at this point in the history
This matches:
  https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git/commit/?h=dev&id=fd73a4395d477ae134f319f7368a9f8a6264fd8b

We set the COMPAT_XATTR_FILTER flag on the superblock, and we add to
each xattr header a 32bit bloom filter which defaults to all bits
set, and then we compute a hash for each key modulo 32, and unset
that bit in the bloom filter.

Older kernels will ignore this, but newer kernels will use it
to make xattr lookup more efficient.

NOTE: This is a format-breaking change, so we also update the test
checksums. We should merge this before freezing the format.

Signed-off-by: Alexander Larsson <alexl@redhat.com>
  • Loading branch information
alexlarsson committed Aug 29, 2023
1 parent ff00dac commit 597a766
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 7 deletions.
30 changes: 28 additions & 2 deletions libcomposefs/lcfs-writer-erofs.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@
#include <assert.h>
#include <linux/fsverity.h>

/* The xxh32 hash function is copied from xxhash with this copyright:
/* The xxh32 hash function is copied from the linux kernel at:
* https://github.com/torvalds/linux/blob/d89775fc929c5a1d91ed518a71b456da0865e5ff/lib/xxhash.c
*
* The original copyright is:
*
* xxHash - Extremely Fast Hash algorithm
* Copyright (C) 2012-2016, Yann Collet.
Expand Down Expand Up @@ -544,6 +547,26 @@ static void compute_erofs_xattr_counts(struct lcfs_node_s *node,
*unshared_xattrs_size_out = unshared_xattrs_size;
}

static uint32_t compute_erofs_xattr_filter(struct lcfs_node_s *node)
{
uint32_t name_filter = 0;

for (size_t i = 0; i < node->n_xattrs; i++) {
struct lcfs_xattr_s *xattr = &node->xattrs[i];
uint32_t name_filter_bit;
uint8_t index;
char *key;

index = xattr_erofs_entry_index(xattr, &key);
name_filter_bit =
xxh32(key, strlen(key), EROFS_XATTR_FILTER_SEED + index) &
(EROFS_XATTR_FILTER_BITS - 1);
name_filter |= 1UL << name_filter_bit;
}

return EROFS_XATTR_FILTER_DEFAULT & ~name_filter;
}

static uint64_t compute_erofs_inode_padding_for_tail(struct lcfs_node_s *node,
uint64_t pos, size_t inode_size,
size_t xattr_size)
Expand Down Expand Up @@ -878,6 +901,8 @@ static int write_erofs_inode_data(struct lcfs_ctx_s *ctx, struct lcfs_node_s *no
if (xattr_size) {
struct erofs_xattr_ibody_header xattr_header = { 0 };
xattr_header.h_shared_count = n_shared_xattrs;
xattr_header.h_name_filter =
lcfs_u32_to_file(compute_erofs_xattr_filter(node));

ret = lcfs_write(ctx, &xattr_header, sizeof(xattr_header));
if (ret < 0)
Expand Down Expand Up @@ -1218,7 +1243,8 @@ int lcfs_write_erofs_to(struct lcfs_ctx_s *ctx)
if (ret < 0)
return ret;

superblock.feature_compat = lcfs_u32_to_file(EROFS_FEATURE_COMPAT_MTIME);
superblock.feature_compat = lcfs_u32_to_file(
EROFS_FEATURE_COMPAT_MTIME | EROFS_FEATURE_COMPAT_XATTR_FILTER);
superblock.inos = lcfs_u64_to_file(ctx->num_inodes);

superblock.build_time = lcfs_u64_to_file(ctx->min_mtim_sec);
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ba8b921eb4600eca90457c7b1f6139b59a3a4ca110e0fcd76c3cb8d681dfb60c
d67e775ced030711b36d70d315ddf7150214312fd18b9345f98a5572035a2076
2 changes: 1 addition & 1 deletion tools/test-assets/config.json.gz.sha256_erofs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
e48676802b93e656265343e71c7d63db472994d8253e591ea3757b0e5b37c61f
f93737bda1b19d79c8fe2828615b9dd24e4ec5d97410a1ce6e3716b1a778f00f
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3fe5370d0fed684ed3852870422c3a93273c612ef9628099ea225a5b17741ae0
8c61b21852d6abfdd3a7a3da71a5ccb56fae2ad099bebe7d564fcaa842cb9532
2 changes: 1 addition & 1 deletion tools/test-assets/cs9-x86_64-minimal.json.gz.sha256_erofs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
e50e762f77d6656f4d48354d3ea127ef091521a6ad00d63fc727c2ad0b2e8174
a168966c314b0b27c8e25270e6f20838a4736a888e5de97993d15d046c797ba3
Original file line number Diff line number Diff line change
@@ -1 +1 @@
40afd104079a9886ab53c6a9fea2b2e76e24f36add35dd4ccb1b18b85151ae52
34bade1be8cef44439944f94a0a7d1421e0661660a506ef0c744135c79cc8ef0

0 comments on commit 597a766

Please sign in to comment.