summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2001-07-13 20:50:38 +0000
committeriedowse <iedowse@FreeBSD.org>2001-07-13 20:50:38 +0000
commit991ee425934fead0e7232cabef1dee2a966dc689 (patch)
treeb3e9a65b6a6af2212cc302dcbc397a50e3e52ca8
parenta110615d801b5bbff9ce7817c401a98a8953caac (diff)
downloadFreeBSD-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.h3
-rw-r--r--sys/ufs/ufs/ufs_dirhash.c7
-rw-r--r--sys/ufs/ufs/ufs_lookup.c8
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);
OpenPOWER on IntegriCloud