]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: devirtualize ->m_dirnameops
authorChristoph Hellwig <hch@lst.de>
Wed, 22 Jan 2020 16:29:44 +0000 (11:29 -0500)
committerEric Sandeen <sandeen@redhat.com>
Wed, 22 Jan 2020 16:29:44 +0000 (11:29 -0500)
Source kernel commit: d8d11fc703a22bbe3939e08b08396fa6b816719a

Instead of causing a relatively expensive indirect call for each
hashing and comparism of a file name in a directory just use an
inline function and a simple branch on the ASCII CI bit.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
[darrick: fix unused variable warning]
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
13 files changed:
db/check.c
include/libxfs.h
libxfs/libxfs_api_defs.h
libxfs/xfs_da_btree.c
libxfs/xfs_da_btree.h
libxfs/xfs_dir2.c
libxfs/xfs_dir2_block.c
libxfs/xfs_dir2_data.c
libxfs/xfs_dir2_leaf.c
libxfs/xfs_dir2_node.c
libxfs/xfs_dir2_priv.h
libxfs/xfs_dir2_sf.c
repair/phase6.c

index 657102b928dd2e73efa68dcc6a0f851ab1c4b311..cc9d371247c8faf14296ad57586245799f8686b3 100644 (file)
@@ -2415,7 +2415,7 @@ process_data_dir_v2(
                        (char *)dep - (char *)data);
                xname.name = dep->name;
                xname.len = dep->namelen;
-               dir_hash_add(mp->m_dirnameops->hashname(&xname), addr);
+               dir_hash_add(libxfs_dir2_hashname(mp, &xname), addr);
                ptr += libxfs_dir2_data_entsize(mp, dep->namelen);
                count++;
                lastfree = 0;
index dc8a5d4f81042c83016f1bd94ffd4631e01d3887..3b7c51fe4c439c96d74d44aa75e410b33c338e27 100644 (file)
@@ -40,6 +40,7 @@ struct iomap;
 
 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
 #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+#define unlikely(x) (x)
 
 /*
  * This mirrors the kernel include for xfs_buf.h - it's implicitly included in
@@ -54,6 +55,7 @@ struct iomap;
 #include "xfs_errortag.h"
 #include "xfs_da_format.h"
 #include "xfs_da_btree.h"
+#include "xfs_inode.h"
 #include "xfs_dir2.h"
 #include "xfs_dir2_priv.h"
 #include "xfs_bmap_btree.h"
@@ -62,7 +64,6 @@ struct iomap;
 #include "xfs_attr_sf.h"
 #include "xfs_inode_fork.h"
 #include "xfs_inode_buf.h"
-#include "xfs_inode.h"
 #include "xfs_alloc.h"
 #include "xfs_btree.h"
 #include "xfs_btree_trace.h"
index e887ee5e6f1da344ba53b1f28eb4a07fe34558c3..eed63ace86c9ea7019c817454b61f3d15531992c 100644 (file)
@@ -89,6 +89,7 @@
 #define xfs_dir2_data_use_free         libxfs_dir2_data_use_free
 #define xfs_dir2_data_entsize          libxfs_dir2_data_entsize
 #define xfs_dir2_data_entry_tag_p      libxfs_dir2_data_entry_tag_p
+#define xfs_dir2_hashname              libxfs_dir2_hashname
 #define xfs_dir2_shrink_inode          libxfs_dir2_shrink_inode
 #define xfs_dir2_sf_get_parent_ino     libxfs_dir2_sf_get_parent_ino
 #define xfs_dir2_sf_put_parent_ino     libxfs_dir2_sf_put_parent_ino
index 76b537656394fcf69b972d5b4dcf8e0a9e58630a..5907c8c40d69eae03f32d6333e9a8770bf8b8f50 100644 (file)
@@ -12,9 +12,9 @@
 #include "xfs_trans_resv.h"
 #include "xfs_bit.h"
 #include "xfs_mount.h"
+#include "xfs_inode.h"
 #include "xfs_dir2.h"
 #include "xfs_dir2_priv.h"
-#include "xfs_inode.h"
 #include "xfs_trans.h"
 #include "xfs_bmap.h"
 #include "xfs_attr_leaf.h"
@@ -2090,18 +2090,6 @@ xfs_da_compname(
                                        XFS_CMP_EXACT : XFS_CMP_DIFFERENT;
 }
 
-static xfs_dahash_t
-xfs_default_hashname(
-       struct xfs_name *name)
-{
-       return xfs_da_hashname(name->name, name->len);
-}
-
-const struct xfs_nameops xfs_default_nameops = {
-       .hashname       = xfs_default_hashname,
-       .compname       = xfs_da_compname
-};
-
 int
 xfs_da_grow_inode_int(
        struct xfs_da_args      *args,
index 5af4df71e92bf9b54f449ed061fa2be0a31aa5a5..ed3b558a9c1a7b703caabe6bc98efc4f9de5f269 100644 (file)
@@ -158,16 +158,6 @@ struct xfs_da3_icnode_hdr {
                (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \
                (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1)
 
-/*
- * Name ops for directory and/or attr name operations
- */
-struct xfs_nameops {
-       xfs_dahash_t    (*hashname)(struct xfs_name *);
-       enum xfs_dacmp  (*compname)(struct xfs_da_args *,
-                                       const unsigned char *, int);
-};
-
-
 /*========================================================================
  * Function prototypes.
  *========================================================================*/
@@ -234,6 +224,5 @@ void        xfs_da3_node_hdr_to_disk(struct xfs_mount *mp,
                struct xfs_da_intnode *to, struct xfs_da3_icnode_hdr *from);
 
 extern struct kmem_zone *xfs_da_state_zone;
-extern const struct xfs_nameops xfs_default_nameops;
 
 #endif /* __XFS_DA_BTREE_H__ */
index df40776005d7322db44551e45ee18963fe5987d7..6ad32c28d019a37860cfc43038dc60cf61fd09d4 100644 (file)
@@ -50,7 +50,7 @@ xfs_mode_to_ftype(
  * ASCII case-insensitive (ie. A-Z) support for directories that was
  * used in IRIX.
  */
-STATIC xfs_dahash_t
+xfs_dahash_t
 xfs_ascii_ci_hashname(
        struct xfs_name *name)
 {
@@ -63,14 +63,14 @@ xfs_ascii_ci_hashname(
        return hash;
 }
 
-STATIC enum xfs_dacmp
+enum xfs_dacmp
 xfs_ascii_ci_compname(
-       struct xfs_da_args *args,
-       const unsigned char *name,
-       int             len)
+       struct xfs_da_args      *args,
+       const unsigned char     *name,
+       int                     len)
 {
-       enum xfs_dacmp  result;
-       int             i;
+       enum xfs_dacmp          result;
+       int                     i;
 
        if (args->namelen != len)
                return XFS_CMP_DIFFERENT;
@@ -87,11 +87,6 @@ xfs_ascii_ci_compname(
        return result;
 }
 
-static const struct xfs_nameops xfs_ascii_ci_nameops = {
-       .hashname       = xfs_ascii_ci_hashname,
-       .compname       = xfs_ascii_ci_compname,
-};
-
 int
 xfs_da_mount(
        struct xfs_mount        *mp)
@@ -161,12 +156,6 @@ xfs_da_mount(
        dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
                                (uint)sizeof(xfs_da_node_entry_t);
        dageo->magicpct = (dageo->blksize * 37) / 100;
-
-       if (xfs_sb_version_hasasciici(&mp->m_sb))
-               mp->m_dirnameops = &xfs_ascii_ci_nameops;
-       else
-               mp->m_dirnameops = &xfs_default_nameops;
-
        return 0;
 }
 
@@ -277,7 +266,7 @@ xfs_dir_createname(
        args->name = name->name;
        args->namelen = name->len;
        args->filetype = name->type;
-       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->hashval = xfs_dir2_hashname(dp->i_mount, name);
        args->inumber = inum;
        args->dp = dp;
        args->total = total;
@@ -373,7 +362,7 @@ xfs_dir_lookup(
        args->name = name->name;
        args->namelen = name->len;
        args->filetype = name->type;
-       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->hashval = xfs_dir2_hashname(dp->i_mount, name);
        args->dp = dp;
        args->whichfork = XFS_DATA_FORK;
        args->trans = tp;
@@ -445,7 +434,7 @@ xfs_dir_removename(
        args->name = name->name;
        args->namelen = name->len;
        args->filetype = name->type;
-       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->hashval = xfs_dir2_hashname(dp->i_mount, name);
        args->inumber = ino;
        args->dp = dp;
        args->total = total;
@@ -506,7 +495,7 @@ xfs_dir_replace(
        args->name = name->name;
        args->namelen = name->len;
        args->filetype = name->type;
-       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->hashval = xfs_dir2_hashname(dp->i_mount, name);
        args->inumber = inum;
        args->dp = dp;
        args->total = total;
index b55136a1d1f63913bda28dc5a54465788ab08c4e..4f9c21a209138fe0c4b26af978500a3f83dde7a1 100644 (file)
@@ -657,13 +657,11 @@ xfs_dir2_block_lookup_int(
        int                     high;           /* binary search high index */
        int                     low;            /* binary search low index */
        int                     mid;            /* binary search current idx */
-       xfs_mount_t             *mp;            /* filesystem mount point */
        xfs_trans_t             *tp;            /* transaction pointer */
        enum xfs_dacmp          cmp;            /* comparison result */
 
        dp = args->dp;
        tp = args->trans;
-       mp = dp->i_mount;
 
        error = xfs_dir3_block_read(tp, dp, &bp);
        if (error)
@@ -715,7 +713,7 @@ xfs_dir2_block_lookup_int(
                 * and buffer. If it's the first case-insensitive match, store
                 * the index and buffer and continue looking for an exact match.
                 */
-               cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen);
+               cmp = xfs_dir2_compname(args, dep->name, dep->namelen);
                if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
                        args->cmpresult = cmp;
                        *bpp = bp;
@@ -1215,8 +1213,7 @@ xfs_dir2_sf_to_block(
                xfs_dir2_data_log_entry(args, bp, dep);
                name.name = sfep->name;
                name.len = sfep->namelen;
-               blp[2 + i].hashval =
-                       cpu_to_be32(mp->m_dirnameops->hashname(&name));
+               blp[2 + i].hashval = cpu_to_be32(xfs_dir2_hashname(mp, &name));
                blp[2 + i].address =
                        cpu_to_be32(xfs_dir2_byte_to_dataptr(newoffset));
                offset = (int)((char *)(tagp + 1) - (char *)hdr);
index 80b237a27e28fef8241e8edc2deab666755e9fca..d34931abc27ce37708627d7c12733520ae462472 100644 (file)
@@ -233,7 +233,7 @@ __xfs_dir3_data_check(
                                                ((char *)dep - (char *)hdr));
                        name.name = dep->name;
                        name.len = dep->namelen;
-                       hash = mp->m_dirnameops->hashname(&name);
+                       hash = xfs_dir2_hashname(mp, &name);
                        for (i = 0; i < be32_to_cpu(btp->count); i++) {
                                if (be32_to_cpu(lep[i].address) == addr &&
                                    be32_to_cpu(lep[i].hashval) == hash)
index 72b97a328d348b063e4158c1779f599b23ed7aee..1bbf050d52c82f58ce1e4422ec7e076b24fed1d7 100644 (file)
@@ -1286,7 +1286,7 @@ xfs_dir2_leaf_lookup_int(
                 * and buffer. If it's the first case-insensitive match, store
                 * the index and buffer and continue looking for an exact match.
                 */
-               cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen);
+               cmp = xfs_dir2_compname(args, dep->name, dep->namelen);
                if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
                        args->cmpresult = cmp;
                        *indexp = index;
index a0c803169898885bbeb9271e337c930f2dfc24b3..30e7d5fa9800580e62addadf94a089b02f0edd95 100644 (file)
@@ -872,7 +872,7 @@ xfs_dir2_leafn_lookup_for_entry(
                 * EEXIST immediately. If it's the first case-insensitive
                 * match, store the block & inode number and continue looking.
                 */
-               cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen);
+               cmp = xfs_dir2_compname(args, dep->name, dep->namelen);
                if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
                        /* If there is a CI match block, drop it */
                        if (args->cmpresult != XFS_CMP_DIFFERENT &&
index 68b9c265dd76b3bc80d7a07d105e8cbf8b128a32..61057362c390676e9b51c080c70e51b12d51ac8f 100644 (file)
@@ -40,6 +40,9 @@ struct xfs_dir3_icfree_hdr {
 };
 
 /* xfs_dir2.c */
+xfs_dahash_t xfs_ascii_ci_hashname(struct xfs_name *name);
+enum xfs_dacmp xfs_ascii_ci_compname(struct xfs_da_args *args,
+               const unsigned char *name, int len);
 extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
                                xfs_dir2_db_t *dbp);
 extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
@@ -197,4 +200,25 @@ xfs_dir2_data_entsize(
        return round_up(len, XFS_DIR2_DATA_ALIGN);
 }
 
+static inline xfs_dahash_t
+xfs_dir2_hashname(
+       struct xfs_mount        *mp,
+       struct xfs_name         *name)
+{
+       if (unlikely(xfs_sb_version_hasasciici(&mp->m_sb)))
+               return xfs_ascii_ci_hashname(name);
+       return xfs_da_hashname(name->name, name->len);
+}
+
+static inline enum xfs_dacmp
+xfs_dir2_compname(
+       struct xfs_da_args      *args,
+       const unsigned char     *name,
+       int                     len)
+{
+       if ((xfs_sb_version_hasasciici(&args->dp->i_mount->m_sb)))
+               return xfs_ascii_ci_compname(args, name, len);
+       return xfs_da_compname(args, name, len);
+}
+
 #endif /* __XFS_DIR2_PRIV_H__ */
index be7464ff4c788625bfa804fa1b8d23c042be6bf3..d38b5d4982f6f34e9427b36b221813ec88b4e917 100644 (file)
@@ -914,8 +914,7 @@ xfs_dir2_sf_lookup(
                 * number. If it's the first case-insensitive match, store the
                 * inode number and continue looking for an exact match.
                 */
-               cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name,
-                                                               sfep->namelen);
+               cmp = xfs_dir2_compname(args, sfep->name, sfep->namelen);
                if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
                        args->cmpresult = cmp;
                        args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep);
index 027c89795966b2e7fa172d61b55d843a2b66323c..3611111c6cdb49b884d5ce3644a917b2f2be9e61 100644 (file)
@@ -235,7 +235,7 @@ dir_hash_add(
        dup = 0;
 
        if (!junk) {
-               hash = mp->m_dirnameops->hashname(&xname);
+               hash = libxfs_dir2_hashname(mp, &xname);
                byhash = DIR_HASH_FUNC(hashtab, hash);
 
                /*