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.
This commit is contained in:
Ian Dowse 2001-07-13 20:50:38 +00:00
parent 5bfda1cf23
commit 50c7c3a7c8
3 changed files with 9 additions and 9 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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);