From 991ee425934fead0e7232cabef1dee2a966dc689 Mon Sep 17 00:00:00 2001 From: iedowse Date: Fri, 13 Jul 2001 20:50:38 +0000 Subject: Return a locked struct buf from ufsdirhash_lookup() to avoid one extra getblk/brelse sequence for each lookup. We already had this buf in ufsdirhash_lookup(), so there was no point in brelse'ing it only to have the caller immediately reaquire the same buffer. This should make the case of sequential lookups marginally faster; in my tests, sequential lookups with dirhash enabled are now only around 1% slower than without dirhash. --- sys/ufs/ufs/dirhash.h | 3 ++- sys/ufs/ufs/ufs_dirhash.c | 7 ++++--- sys/ufs/ufs/ufs_lookup.c | 8 +++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/ufs/ufs/dirhash.h b/sys/ufs/ufs/dirhash.h index 50cdc65..4aea6c1 100644 --- a/sys/ufs/ufs/dirhash.h +++ b/sys/ufs/ufs/dirhash.h @@ -111,7 +111,8 @@ struct dirhash { int ufsdirhash_build(struct inode *); doff_t ufsdirhash_findfree(struct inode *, int, int *); doff_t ufsdirhash_enduseful(struct inode *); -int ufsdirhash_lookup(struct inode *, char *, int, doff_t *, doff_t *); +int ufsdirhash_lookup(struct inode *, char *, int, doff_t *, struct buf **, + doff_t *); void ufsdirhash_newblk(struct inode *, doff_t); void ufsdirhash_add(struct inode *, struct direct *, doff_t); void ufsdirhash_remove(struct inode *, struct direct *, doff_t); diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c index cc2cda9..1a9262a 100644 --- a/sys/ufs/ufs/ufs_dirhash.c +++ b/sys/ufs/ufs/ufs_dirhash.c @@ -298,14 +298,15 @@ ufsdirhash_free(struct inode *ip) * Returns 0 on success, ENOENT if the entry does not exist, or * EJUSTRETURN if the caller should revert to a linear search. * - * If successful, the directory offset is stored in *offp. If + * If successful, the directory offset is stored in *offp, and a + * pointer to a struct buf containing the entry is stored in *bpp. If * prevoffp is non-NULL, the offset of the previous entry within * the DIRBLKSIZ-sized block is stored in *prevoffp (if the entry * is the first in a block, the start of the block is used). */ int ufsdirhash_lookup(struct inode *ip, char *name, int namelen, doff_t *offp, - doff_t *prevoffp) + struct buf **bpp, doff_t *prevoffp) { struct dirhash *dh, *dh_next; struct direct *dp; @@ -428,7 +429,7 @@ restart: dh->dh_seqopt = 1; dh->dh_seqoff = offset + DIRSIZ(0, dp); - brelse(bp); + *bpp = bp; *offp = offset; return (0); } diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 2a3a71e..b4aa6a9 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -212,12 +212,10 @@ ufs_lookup(ap) numdirpasses = 1; entryoffsetinblock = 0; /* silence compiler warning */ switch (ufsdirhash_lookup(dp, cnp->cn_nameptr, cnp->cn_namelen, - &dp->i_offset, nameiop == DELETE ? &prevoff : NULL)) { + &dp->i_offset, &bp, nameiop == DELETE ? &prevoff : NULL)) { case 0: - error = UFS_BLKATOFF(vdp, (off_t)dp->i_offset, - (char **)&ep, &bp); - if (error) - return (error); + ep = (struct direct *)((char *)bp->b_data + + (dp->i_offset & bmask)); goto foundentry; case ENOENT: dp->i_offset = roundup2(dp->i_size, DIRBLKSIZ); -- cgit v1.1