Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/ufs/ufs/ufs_dirhash.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/ufs/ufs/ufs_dirhash.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.21.6.2 retrieving revision 1.27.10.2 diff -u -p -r1.21.6.2 -r1.27.10.2 --- src/sys/ufs/ufs/ufs_dirhash.c 2008/06/05 19:14:37 1.21.6.2 +++ src/sys/ufs/ufs/ufs_dirhash.c 2009/07/23 23:33:03 1.27.10.2 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_dirhash.c,v 1.21.6.2 2008/06/05 19:14:37 mjf Exp $ */ +/* $NetBSD: ufs_dirhash.c,v 1.27.10.2 2009/07/23 23:33:03 jym Exp $ */ /* * Copyright (c) 2001, 2002 Ian Dowse. All rights reserved. @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ufs_dirhash.c,v 1.21.6.2 2008/06/05 19:14:37 mjf Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_dirhash.c,v 1.27.10.2 2009/07/23 23:33:03 jym Exp $"); /* * This implements a hash-based lookup scheme for UFS directories. @@ -93,6 +93,8 @@ static TAILQ_HEAD(, dirhash) ufsdirhash_ /* Protects: ufsdirhash_list, `dh_list' field, ufs_dirhashmem. */ static kmutex_t ufsdirhash_lock; +static struct sysctllog *ufsdirhash_sysctl_log; + /* * Locking order: * ufsdirhash_lock @@ -138,7 +140,7 @@ ufsdirhash_build(struct inode *ip) } /* Don't hash removed directories. */ - if (ip->i_ffs_effnlink == 0) + if (ip->i_nlink == 0) return (-1); vp = ip->i_vnode; @@ -163,6 +165,8 @@ ufsdirhash_build(struct inode *ip) /* Try to free some space. */ if (ufsdirhash_recycle(memreqd) != 0) return (-1); + else + DIRHASHLIST_UNLOCK(); } /* @@ -176,6 +180,7 @@ ufsdirhash_build(struct inode *ip) } memset(dh, 0, sizeof(*dh)); mutex_init(&dh->dh_lock, MUTEX_DEFAULT, IPL_NONE); + DIRHASH_LOCK(dh); dh->dh_hashsz = narrays * sizeof(dh->dh_hash[0]); dh->dh_hash = kmem_zalloc(dh->dh_hashsz, KM_NOSLEEP); dh->dh_blkfreesz = nblocks * sizeof(dh->dh_blkfree[0]); @@ -245,10 +250,12 @@ ufsdirhash_build(struct inode *ip) DIRHASHLIST_LOCK(); TAILQ_INSERT_TAIL(&ufsdirhash_list, dh, dh_list); dh->dh_onlist = 1; + DIRHASH_UNLOCK(dh); DIRHASHLIST_UNLOCK(); return (0); fail: + DIRHASH_UNLOCK(dh); if (dh->dh_hash != NULL) { for (i = 0; i < narrays; i++) if (dh->dh_hash[i] != NULL) @@ -409,7 +416,7 @@ restart: brelse(bp, 0); blkoff = offset & ~bmask; if (ufs_blkatoff(vp, (off_t)blkoff, - NULL, &bp, true) != 0) { + NULL, &bp, false) != 0) { DIRHASH_UNLOCK(dh); return (EJUSTRETURN); } @@ -423,7 +430,7 @@ restart: return (EJUSTRETURN); } if (dp->d_namlen == namelen && - bcmp(dp->d_name, name, namelen) == 0) { + memcmp(dp->d_name, name, namelen) == 0) { /* Found. Get the prev offset if needed. */ if (prevoffp != NULL) { if (offset & (dirblksiz - 1)) { @@ -1081,82 +1088,84 @@ ufsdirhash_recycle(int wanted) DIRHASHLIST_LOCK(); ufs_dirhashmem -= mem; } - DIRHASHLIST_LOCK(); /* Success. */ return (0); } -void -ufsdirhash_init() -{ - - mutex_init(&ufsdirhash_lock, MUTEX_DEFAULT, IPL_NONE); - ufsdirhashblk_cache = pool_cache_init(DH_NBLKOFF * sizeof(daddr_t), 0, - 0, 0, "dirhashblk", NULL, IPL_NONE, NULL, NULL, NULL); - ufsdirhash_cache = pool_cache_init(sizeof(struct dirhash), 0, - 0, 0, "dirhash", NULL, IPL_NONE, NULL, NULL, NULL); - TAILQ_INIT(&ufsdirhash_list); -} - -void -ufsdirhash_done(void) -{ - - KASSERT(TAILQ_EMPTY(&ufsdirhash_list)); - pool_cache_destroy(ufsdirhashblk_cache); - pool_cache_destroy(ufsdirhash_cache); - mutex_destroy(&ufsdirhash_lock); -} - -SYSCTL_SETUP(sysctl_vfs_ufs_setup, "sysctl vfs.ufs.dirhash subtree setup") +static void +ufsdirhash_sysctl_init(void) { const struct sysctlnode *rnode, *cnode; - sysctl_createv(clog, 0, NULL, &rnode, + sysctl_createv(&ufsdirhash_sysctl_log, 0, NULL, &rnode, CTLFLAG_PERMANENT, CTLTYPE_NODE, "vfs", NULL, NULL, 0, NULL, 0, CTL_VFS, CTL_EOL); - sysctl_createv(clog, 0, &rnode, &rnode, + sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &rnode, CTLFLAG_PERMANENT, CTLTYPE_NODE, "ufs", SYSCTL_DESCR("ufs"), NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, &rnode, &rnode, + sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &rnode, CTLFLAG_PERMANENT, CTLTYPE_NODE, "dirhash", SYSCTL_DESCR("dirhash"), NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, &rnode, &cnode, + sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &cnode, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "minblocks", SYSCTL_DESCR("minimum hashed directory size in blocks"), NULL, 0, &ufs_dirhashminblks, 0, CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, &rnode, &cnode, + sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &cnode, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "maxmem", SYSCTL_DESCR("maximum dirhash memory usage"), NULL, 0, &ufs_dirhashmaxmem, 0, CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, &rnode, &cnode, + sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &cnode, CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_INT, "memused", SYSCTL_DESCR("current dirhash memory usage"), NULL, 0, &ufs_dirhashmem, 0, CTL_CREATE, CTL_EOL); - sysctl_createv(clog, 0, &rnode, &cnode, + sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &cnode, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "docheck", SYSCTL_DESCR("enable extra sanity checks"), NULL, 0, &ufs_dirhashcheck, 0, CTL_CREATE, CTL_EOL); } + +void +ufsdirhash_init(void) +{ + + mutex_init(&ufsdirhash_lock, MUTEX_DEFAULT, IPL_NONE); + ufsdirhashblk_cache = pool_cache_init(DH_NBLKOFF * sizeof(daddr_t), 0, + 0, 0, "dirhashblk", NULL, IPL_NONE, NULL, NULL, NULL); + ufsdirhash_cache = pool_cache_init(sizeof(struct dirhash), 0, + 0, 0, "dirhash", NULL, IPL_NONE, NULL, NULL, NULL); + TAILQ_INIT(&ufsdirhash_list); + ufsdirhash_sysctl_init(); +} + +void +ufsdirhash_done(void) +{ + + KASSERT(TAILQ_EMPTY(&ufsdirhash_list)); + pool_cache_destroy(ufsdirhashblk_cache); + pool_cache_destroy(ufsdirhash_cache); + mutex_destroy(&ufsdirhash_lock); + sysctl_teardown(&ufsdirhash_sysctl_log); +}