mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 07:04:10 +08:00
xfs: devirtualize ->m_dirnameops
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>
This commit is contained in:
parent
537dabcfdb
commit
d8d11fc703
@ -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"
|
||||
@ -2093,18 +2093,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,
|
||||
|
@ -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__ */
|
||||
|
@ -52,7 +52,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)
|
||||
{
|
||||
@ -65,14 +65,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;
|
||||
@ -89,11 +89,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)
|
||||
@ -163,12 +158,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;
|
||||
}
|
||||
|
||||
@ -279,7 +268,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;
|
||||
@ -375,7 +364,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;
|
||||
@ -447,7 +436,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;
|
||||
@ -508,7 +497,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;
|
||||
|
@ -660,13 +660,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)
|
||||
@ -718,7 +716,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;
|
||||
@ -1218,8 +1216,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);
|
||||
|
@ -236,7 +236,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)
|
||||
|
@ -1288,7 +1288,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;
|
||||
|
@ -875,7 +875,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 &&
|
||||
|
@ -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,
|
||||
@ -191,4 +194,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 (unlikely(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__ */
|
||||
|
@ -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);
|
||||
|
@ -9,7 +9,6 @@
|
||||
struct xlog;
|
||||
struct xfs_inode;
|
||||
struct xfs_mru_cache;
|
||||
struct xfs_nameops;
|
||||
struct xfs_ail;
|
||||
struct xfs_quotainfo;
|
||||
struct xfs_da_geometry;
|
||||
@ -154,7 +153,6 @@ typedef struct xfs_mount {
|
||||
int m_dalign; /* stripe unit */
|
||||
int m_swidth; /* stripe width */
|
||||
uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
|
||||
const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */
|
||||
atomic_t m_active_trans; /* number trans frozen */
|
||||
struct xfs_mru_cache *m_filestream; /* per-mount filestream data */
|
||||
struct delayed_work m_reclaim_work; /* background inode reclaim */
|
||||
|
Loading…
Reference in New Issue
Block a user