diff options
author | iedowse <iedowse@FreeBSD.org> | 2001-07-13 20:50:38 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2001-07-13 20:50:38 +0000 |
commit | 991ee425934fead0e7232cabef1dee2a966dc689 (patch) | |
tree | b3e9a65b6a6af2212cc302dcbc397a50e3e52ca8 | |
parent | a110615d801b5bbff9ce7817c401a98a8953caac (diff) | |
download | FreeBSD-src-991ee425934fead0e7232cabef1dee2a966dc689.zip FreeBSD-src-991ee425934fead0e7232cabef1dee2a966dc689.tar.gz |
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.
-rw-r--r-- | sys/ufs/ufs/dirhash.h | 3 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_dirhash.c | 7 | ||||
-rw-r--r-- | 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); |