[PATCH v6 3/3] erofs-utils: mkfs: enable xattr name filter
Gao Xiang
hsiangkao at linux.alibaba.com
Tue Aug 29 22:53:53 AEST 2023
On 2023/8/29 20:41, Jingbo Xu wrote:
> Introduce "-Exattr-name-filter" option to enable the xattr name bloom
> filter feature.
>
> Signed-off-by: Jingbo Xu <jefflexu at linux.alibaba.com>
> ---
> include/erofs/config.h | 1 +
> include/erofs/internal.h | 1 +
> lib/xattr.c | 63 ++++++++++++++++++++++++++++++++++++++++
> mkfs/main.c | 7 +++++
> 4 files changed, 72 insertions(+)
>
> diff --git a/include/erofs/config.h b/include/erofs/config.h
> index 8f52d2c..c51f0cd 100644
> --- a/include/erofs/config.h
> +++ b/include/erofs/config.h
> @@ -53,6 +53,7 @@ struct erofs_configure {
> bool c_ignore_mtime;
> bool c_showprogress;
> bool c_extra_ea_name_prefixes;
> + bool c_xattr_name_filter;
>
> #ifdef HAVE_LIBSELINUX
> struct selabel_handle *sehnd;
> diff --git a/include/erofs/internal.h b/include/erofs/internal.h
> index 3e73eef..382024a 100644
> --- a/include/erofs/internal.h
> +++ b/include/erofs/internal.h
> @@ -139,6 +139,7 @@ EROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS)
> EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
> EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
> EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
> +EROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER)
>
> #define EROFS_I_EA_INITED (1 << 0)
> #define EROFS_I_Z_INITED (1 << 1)
> diff --git a/lib/xattr.c b/lib/xattr.c
> index 46a301a..325241d 100644
> --- a/lib/xattr.c
> +++ b/lib/xattr.c
> @@ -18,6 +18,7 @@
> #include "erofs/cache.h"
> #include "erofs/io.h"
> #include "erofs/fragments.h"
> +#include "erofs/xxhash.h"
> #include "liberofs_private.h"
>
> #define EA_HASHTABLE_BITS 16
> @@ -783,6 +784,63 @@ out:
> return ret;
> }
>
> +
> +static int erofs_xattr_filter_hashbit(struct xattr_item *item)
> +{
> + u8 prefix = item->prefix;
> + const char *key = item->kvbuf;
> + unsigned int len = item->len[0];
> + char *name = NULL;
> + uint32_t hashbit;
> +
> + if (prefix & EROFS_XATTR_LONG_PREFIX) {
> + struct ea_type_node *tnode;
> + u16 prefix_len;
> + int ret;
> +
> + list_for_each_entry(tnode, &ea_name_prefixes, list) {
> + if (tnode->index == item->prefix) {
> + ret = asprintf(&name, "%s%.*s",
> + tnode->type.prefix, len, key);
> + if (ret < 0)
> + return -ENOMEM;
> + break;
> + }
> + }
> + if (!name)
> + return -ENOENT;
> +
> + if (!match_base_prefix(name, &prefix, &prefix_len)) {
> + free(name);
> + return -ENOENT;
> + }
> + key = name + prefix_len;
> + len = strlen(key);
> + }
> +
> + hashbit = xxh32(key, len, EROFS_XATTR_FILTER_SEED + prefix) &
> + (EROFS_XATTR_FILTER_BITS - 1);
> + if (name)
> + free(name);
> + return hashbit;
> +}
> +
> +static u32 erofs_xattr_filter_map(struct list_head *ixattrs)
> +{
> + struct inode_xattr_node *node, *n;
> + u32 name_filter;
> + int hashbit;
> +
> + name_filter = 0;
> + list_for_each_entry_safe(node, n, ixattrs, list) {
> + hashbit = erofs_xattr_filter_hashbit(node->item);
> + if (hashbit < 0)
I'd suggest to clear feature bit instead:
erofs_sb_clear_xattr_filter(&sbi);
> + return 0;
> + name_filter |= (1UL << hashbit);
> + }
> + return EROFS_XATTR_FILTER_DEFAULT & ~name_filter;
> +}
> +
> char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size)
> {
> struct inode_xattr_node *node, *n;
> @@ -797,6 +855,11 @@ char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size)
> header = (struct erofs_xattr_ibody_header *)buf;
> header->h_shared_count = 0;
>
> + if (cfg.c_xattr_name_filter) {
> + u32 name_filter = erofs_xattr_filter_map(ixattrs);
Leave a blank line here.
> + header->h_name_filter = cpu_to_le32(name_filter);
Or
header->h_name_filter =
cpu_to_le32(erofs_xattr_filter_map(ixattrs));
Thanks,
Gao Xiang
More information about the Linux-erofs
mailing list