From: Darrick J. Wong <djwong@xxxxxxxxxx> Create a new hashing function for extended attribute names. The next patch needs this so it can modify the hash strategy for verity xattrs. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_attr.c | 16 ++++++++++++++-- fs/xfs/libxfs/xfs_attr.h | 3 +++ fs/xfs/libxfs/xfs_attr_leaf.c | 4 ++-- fs/xfs/scrub/attr.c | 8 +++++--- fs/xfs/xfs_attr_item.c | 3 ++- fs/xfs/xfs_attr_list.c | 3 ++- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index b7aa1bc12fd1..b1fa45197eac 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -238,6 +238,16 @@ xfs_attr_get_ilocked( return xfs_attr_node_get(args); } +/* Compute hash for an extended attribute name. */ +xfs_dahash_t +xfs_attr_hashname( + unsigned int attr_flags, + const uint8_t *name, + unsigned int namelen) +{ + return xfs_da_hashname(name, namelen); +} + /* * Retrieve an extended attribute by name, and its value if requested. * @@ -268,7 +278,8 @@ xfs_attr_get( args->geo = args->dp->i_mount->m_attr_geo; args->whichfork = XFS_ATTR_FORK; - args->hashval = xfs_da_hashname(args->name, args->namelen); + args->hashval = xfs_attr_hashname(args->attr_filter, args->name, + args->namelen); /* Entirely possible to look up a name which doesn't exist */ args->op_flags = XFS_DA_OP_OKNOENT; @@ -942,7 +953,8 @@ xfs_attr_set( args->geo = mp->m_attr_geo; args->whichfork = XFS_ATTR_FORK; - args->hashval = xfs_da_hashname(args->name, args->namelen); + args->hashval = xfs_attr_hashname(args->attr_filter, args->name, + args->namelen); /* * We have no control over the attribute names that userspace passes us diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 92711c8d2a9f..19db6c1cc71f 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -619,4 +619,7 @@ extern struct kmem_cache *xfs_attr_intent_cache; int __init xfs_attr_intent_init_cache(void); void xfs_attr_intent_destroy_cache(void); +xfs_dahash_t xfs_attr_hashname(unsigned int attr_flags, + const uint8_t *name_string, unsigned int name_length); + #endif /* __XFS_ATTR_H__ */ diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index ac904cc1a97b..fcece25fd13e 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -911,8 +911,8 @@ xfs_attr_shortform_to_leaf( nargs.namelen = sfe->namelen; nargs.value = &sfe->nameval[nargs.namelen]; nargs.valuelen = sfe->valuelen; - nargs.hashval = xfs_da_hashname(sfe->nameval, - sfe->namelen); + nargs.hashval = xfs_attr_hashname(sfe->flags, sfe->nameval, + sfe->namelen); nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK; error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == -ENOATTR); diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c index c69dee281984..e7d50589f72d 100644 --- a/fs/xfs/scrub/attr.c +++ b/fs/xfs/scrub/attr.c @@ -253,7 +253,6 @@ xchk_xattr_listent( .dp = context->dp, .name = name, .namelen = namelen, - .hashval = xfs_da_hashname(name, namelen), .trans = context->tp, .valuelen = valuelen, }; @@ -263,6 +262,7 @@ xchk_xattr_listent( sx = container_of(context, struct xchk_xattr, context); ab = sx->sc->buf; + args.hashval = xfs_attr_hashname(flags, name, namelen); if (xchk_should_terminate(sx->sc, &error)) { context->seen_enough = error; @@ -600,7 +600,8 @@ xchk_xattr_rec( xchk_da_set_corrupt(ds, level); goto out; } - calc_hash = xfs_da_hashname(lentry->nameval, lentry->namelen); + calc_hash = xfs_attr_hashname(ent->flags, lentry->nameval, + lentry->namelen); } else { rentry = (struct xfs_attr_leaf_name_remote *) (((char *)bp->b_addr) + nameidx); @@ -608,7 +609,8 @@ xchk_xattr_rec( xchk_da_set_corrupt(ds, level); goto out; } - calc_hash = xfs_da_hashname(rentry->name, rentry->namelen); + calc_hash = xfs_attr_hashname(ent->flags, rentry->name, + rentry->namelen); } if (calc_hash != hash) xchk_da_set_corrupt(ds, level); diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 703770cf1482..4d8264f0a537 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -536,7 +536,8 @@ xfs_attri_recover_work( args->whichfork = XFS_ATTR_FORK; args->name = nv->name.i_addr; args->namelen = nv->name.i_len; - args->hashval = xfs_da_hashname(args->name, args->namelen); + args->hashval = xfs_attr_hashname(attrp->alfi_attr_filter, args->name, + args->namelen); args->attr_filter = attrp->alfi_attr_filter & XFS_ATTRI_FILTER_MASK; args->op_flags = XFS_DA_OP_RECOVERY | XFS_DA_OP_OKNOENT | XFS_DA_OP_LOGGED; diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index fa74378577c5..96169474d023 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -135,7 +135,8 @@ xfs_attr_shortform_list( } sbp->entno = i; - sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen); + sbp->hash = xfs_attr_hashname(sfe->flags, sfe->nameval, + sfe->namelen); sbp->name = sfe->nameval; sbp->namelen = sfe->namelen; /* These are bytes, and both on-disk, don't endian-flip */