Use vfs_hash() instead of home-rolled

This commit is contained in:
Poul-Henning Kamp 2005-03-14 13:30:06 +00:00
parent dfb9f846e9
commit 9236b51d40
9 changed files with 65 additions and 138 deletions

View File

@ -1003,7 +1003,6 @@ gnu/ext2fs/ext2_alloc.c optional ext2fs \
warning "kernel contains GPL contaminated ext2fs filesystem"
gnu/ext2fs/ext2_balloc.c optional ext2fs
gnu/ext2fs/ext2_bmap.c optional ext2fs
gnu/ext2fs/ext2_ihash.c optional ext2fs
gnu/ext2fs/ext2_inode.c optional ext2fs
gnu/ext2fs/ext2_inode_cnv.c optional ext2fs
gnu/ext2fs/ext2_linux_balloc.c optional ext2fs

View File

@ -59,13 +59,6 @@ void ext2_dirbad(struct inode *ip, doff_t offset, char *how);
void ext2_ei2i(struct ext2_inode *, struct inode *);
int ext2_getlbns(struct vnode *, int32_t, struct indir *, int *);
void ext2_i2ei(struct inode *, struct ext2_inode *);
int ext2_ihashget(struct cdev *, ino_t, int, struct vnode **);
void ext2_ihashinit(void);
void ext2_ihashins(struct inode *);
struct vnode *
ext2_ihashlookup(struct cdev *, ino_t);
void ext2_ihashrem(struct inode *);
void ext2_ihashuninit(void);
void ext2_itimes(struct vnode *vp);
int ext2_reallocblks(struct vop_reallocblks_args *);
int ext2_reclaim(struct vop_reclaim_args *);

View File

@ -48,7 +48,7 @@ static MALLOC_DEFINE(M_EXT2IHASH, "EXT2 ihash", "EXT2 Inode hash tables");
*/
static LIST_HEAD(ihashhead, inode) *ihashtbl;
static u_long ihash; /* size of hash table - 1 */
#define INOHASH(device, inum) (&ihashtbl[(minor(device) + (inum)) & ihash])
#define INOHASH(inum) (&ihashtbl[(inum) & ihash])
static struct mtx ext2_ihash_mtx;
/*
@ -86,7 +86,7 @@ ext2_ihashlookup(dev, inum)
struct inode *ip;
mtx_lock(&ext2_ihash_mtx);
LIST_FOREACH(ip, INOHASH(dev, inum), i_hash)
LIST_FOREACH(ip, INOHASH(inum), i_hash)
if (inum == ip->i_number && dev == ip->i_dev)
break;
mtx_unlock(&ext2_ihash_mtx);
@ -115,7 +115,7 @@ ext2_ihashget(dev, inum, flags, vpp)
*vpp = NULL;
loop:
mtx_lock(&ext2_ihash_mtx);
LIST_FOREACH(ip, INOHASH(dev, inum), i_hash) {
LIST_FOREACH(ip, INOHASH(inum), i_hash) {
if (inum == ip->i_number && dev == ip->i_dev) {
vp = ITOV(ip);
mtx_lock(&vp->v_interlock);
@ -147,7 +147,7 @@ ext2_ihashins(ip)
vn_lock(ITOV(ip), LK_EXCLUSIVE | LK_RETRY, td);
mtx_lock(&ext2_ihash_mtx);
ipp = INOHASH(ip->i_dev, ip->i_number);
ipp = INOHASH(ip->i_number);
LIST_INSERT_HEAD(ipp, ip, i_hash);
ip->i_flag |= IN_HASHED;
mtx_unlock(&ext2_ihash_mtx);

View File

@ -528,10 +528,7 @@ ext2_reclaim(ap)
ip->i_flag |= IN_MODIFIED;
ext2_update(vp, 0);
}
/*
* Remove the inode from its hash chain.
*/
ext2_ihashrem(ip);
vfs_hash_remove(vp);
/*
* Purge old data structures associated with the inode.
*/

View File

@ -74,8 +74,6 @@ static vfs_sync_t ext2_sync;
static vfs_vget_t ext2_vget;
static vfs_fhtovp_t ext2_fhtovp;
static vfs_vptofh_t ext2_vptofh;
static vfs_init_t ext2_init;
static vfs_uninit_t ext2_uninit;
static vfs_mount_t ext2_mount;
MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
@ -83,12 +81,10 @@ static MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
static struct vfsops ext2fs_vfsops = {
.vfs_fhtovp = ext2_fhtovp,
.vfs_init = ext2_init,
.vfs_mount = ext2_mount,
.vfs_root = ext2_root, /* root inode via vget */
.vfs_statfs = ext2_statfs,
.vfs_sync = ext2_sync,
.vfs_uninit = ext2_uninit,
.vfs_unmount = ext2_unmount,
.vfs_vget = ext2_vget,
.vfs_vptofh = ext2_vptofh,
@ -99,8 +95,6 @@ VFS_SET(ext2fs_vfsops, ext2fs, 0);
#define bsd_malloc malloc
#define bsd_free free
static int ext2fs_inode_hash_lock;
static int ext2_check_sb_compat(struct ext2_super_block *es, struct cdev *dev,
int ronly);
static int compute_sb_data(struct vnode * devvp,
@ -921,27 +915,14 @@ ext2_vget(mp, ino, flags, vpp)
int i, error;
int used_blocks;
ump = VFSTOEXT2(mp);
dev = ump->um_dev;
restart:
if ((error = ext2_ihashget(dev, ino, flags, vpp)) != 0)
error = vfs_hash_get(mp, ino, flags, curthread, vpp);
if (error)
return (error);
if (*vpp != NULL)
return (0);
/*
* Lock out the creation of new entries in the FFS hash table in
* case getnewvnode() or MALLOC() blocks, otherwise a duplicate
* may occur!
*/
if (ext2fs_inode_hash_lock) {
while (ext2fs_inode_hash_lock) {
ext2fs_inode_hash_lock = -1;
tsleep(&ext2fs_inode_hash_lock, PVM, "e2vget", 0);
}
goto restart;
}
ext2fs_inode_hash_lock = 1;
ump = VFSTOEXT2(mp);
dev = ump->um_dev;
/*
* If this MALLOC() is performed after the getnewvnode()
@ -950,34 +931,43 @@ restart:
* which will cause a panic because ext2_sync() blindly
* dereferences vp->v_data (as well it should).
*/
MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
ip = malloc(sizeof(struct inode), M_EXT2NODE, M_WAITOK | M_ZERO);
/* Allocate a new vnode/inode. */
if ((error = getnewvnode("ext2fs", mp, &ext2_vnodeops, &vp)) != 0) {
if (ext2fs_inode_hash_lock < 0)
wakeup(&ext2fs_inode_hash_lock);
ext2fs_inode_hash_lock = 0;
*vpp = NULL;
FREE(ip, M_EXT2NODE);
free(ip, M_EXT2NODE);
return (error);
}
bzero((caddr_t)ip, sizeof(struct inode));
vp->v_data = ip;
ip->i_vnode = vp;
ip->i_e2fs = fs = ump->um_e2fs;
ip->i_dev = dev;
ip->i_number = ino;
/*
* Put it onto its hash chain and lock it so that other requests for
* this inode will block if they arrive while we are sleeping waiting
* for old data structures to be purged or for the contents of the
* disk portion of this inode to be read.
*/
ext2_ihashins(ip);
if (ext2fs_inode_hash_lock < 0)
wakeup(&ext2fs_inode_hash_lock);
ext2fs_inode_hash_lock = 0;
/*
* Exclusively lock the vnode before adding to hash. Note, that we
* must not release nor downgrade the lock (despite flags argument
* says) till it is fully initialized.
*/
lockmgr(vp->v_vnlock, LK_EXCLUSIVE, (struct mtx *)0, curthread);
/*
* Atomicaly (in terms of vfs_hash operations) check the hash for
* duplicate of vnode being created and add it to the hash. If a
* duplicate vnode was found, it will be vget()ed from hash for us.
*/
if ((error = vfs_hash_insert(vp, ino, flags, curthread, vpp)) != 0) {
vput(vp);
*vpp = NULL;
return (error);
}
/* We lost the race, then throw away our vnode and return existing */
if (*vpp != NULL) {
vput(vp);
return (0);
}
/* Read in the disk contents for the inode, copy into the inode. */
#if 0
@ -1159,19 +1149,3 @@ ext2_root(mp, vpp, td)
*vpp = nvp;
return (0);
}
static int
ext2_init(struct vfsconf *vfsp)
{
ext2_ihashinit();
return (0);
}
static int
ext2_uninit(struct vfsconf *vfsp)
{
ext2_ihashuninit();
return (0);
}

View File

@ -59,13 +59,6 @@ void ext2_dirbad(struct inode *ip, doff_t offset, char *how);
void ext2_ei2i(struct ext2_inode *, struct inode *);
int ext2_getlbns(struct vnode *, int32_t, struct indir *, int *);
void ext2_i2ei(struct inode *, struct ext2_inode *);
int ext2_ihashget(struct cdev *, ino_t, int, struct vnode **);
void ext2_ihashinit(void);
void ext2_ihashins(struct inode *);
struct vnode *
ext2_ihashlookup(struct cdev *, ino_t);
void ext2_ihashrem(struct inode *);
void ext2_ihashuninit(void);
void ext2_itimes(struct vnode *vp);
int ext2_reallocblks(struct vop_reallocblks_args *);
int ext2_reclaim(struct vop_reclaim_args *);

View File

@ -528,10 +528,7 @@ ext2_reclaim(ap)
ip->i_flag |= IN_MODIFIED;
ext2_update(vp, 0);
}
/*
* Remove the inode from its hash chain.
*/
ext2_ihashrem(ip);
vfs_hash_remove(vp);
/*
* Purge old data structures associated with the inode.
*/

View File

@ -74,8 +74,6 @@ static vfs_sync_t ext2_sync;
static vfs_vget_t ext2_vget;
static vfs_fhtovp_t ext2_fhtovp;
static vfs_vptofh_t ext2_vptofh;
static vfs_init_t ext2_init;
static vfs_uninit_t ext2_uninit;
static vfs_mount_t ext2_mount;
MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
@ -83,12 +81,10 @@ static MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
static struct vfsops ext2fs_vfsops = {
.vfs_fhtovp = ext2_fhtovp,
.vfs_init = ext2_init,
.vfs_mount = ext2_mount,
.vfs_root = ext2_root, /* root inode via vget */
.vfs_statfs = ext2_statfs,
.vfs_sync = ext2_sync,
.vfs_uninit = ext2_uninit,
.vfs_unmount = ext2_unmount,
.vfs_vget = ext2_vget,
.vfs_vptofh = ext2_vptofh,
@ -99,8 +95,6 @@ VFS_SET(ext2fs_vfsops, ext2fs, 0);
#define bsd_malloc malloc
#define bsd_free free
static int ext2fs_inode_hash_lock;
static int ext2_check_sb_compat(struct ext2_super_block *es, struct cdev *dev,
int ronly);
static int compute_sb_data(struct vnode * devvp,
@ -921,27 +915,14 @@ ext2_vget(mp, ino, flags, vpp)
int i, error;
int used_blocks;
ump = VFSTOEXT2(mp);
dev = ump->um_dev;
restart:
if ((error = ext2_ihashget(dev, ino, flags, vpp)) != 0)
error = vfs_hash_get(mp, ino, flags, curthread, vpp);
if (error)
return (error);
if (*vpp != NULL)
return (0);
/*
* Lock out the creation of new entries in the FFS hash table in
* case getnewvnode() or MALLOC() blocks, otherwise a duplicate
* may occur!
*/
if (ext2fs_inode_hash_lock) {
while (ext2fs_inode_hash_lock) {
ext2fs_inode_hash_lock = -1;
tsleep(&ext2fs_inode_hash_lock, PVM, "e2vget", 0);
}
goto restart;
}
ext2fs_inode_hash_lock = 1;
ump = VFSTOEXT2(mp);
dev = ump->um_dev;
/*
* If this MALLOC() is performed after the getnewvnode()
@ -950,34 +931,43 @@ restart:
* which will cause a panic because ext2_sync() blindly
* dereferences vp->v_data (as well it should).
*/
MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
ip = malloc(sizeof(struct inode), M_EXT2NODE, M_WAITOK | M_ZERO);
/* Allocate a new vnode/inode. */
if ((error = getnewvnode("ext2fs", mp, &ext2_vnodeops, &vp)) != 0) {
if (ext2fs_inode_hash_lock < 0)
wakeup(&ext2fs_inode_hash_lock);
ext2fs_inode_hash_lock = 0;
*vpp = NULL;
FREE(ip, M_EXT2NODE);
free(ip, M_EXT2NODE);
return (error);
}
bzero((caddr_t)ip, sizeof(struct inode));
vp->v_data = ip;
ip->i_vnode = vp;
ip->i_e2fs = fs = ump->um_e2fs;
ip->i_dev = dev;
ip->i_number = ino;
/*
* Put it onto its hash chain and lock it so that other requests for
* this inode will block if they arrive while we are sleeping waiting
* for old data structures to be purged or for the contents of the
* disk portion of this inode to be read.
*/
ext2_ihashins(ip);
if (ext2fs_inode_hash_lock < 0)
wakeup(&ext2fs_inode_hash_lock);
ext2fs_inode_hash_lock = 0;
/*
* Exclusively lock the vnode before adding to hash. Note, that we
* must not release nor downgrade the lock (despite flags argument
* says) till it is fully initialized.
*/
lockmgr(vp->v_vnlock, LK_EXCLUSIVE, (struct mtx *)0, curthread);
/*
* Atomicaly (in terms of vfs_hash operations) check the hash for
* duplicate of vnode being created and add it to the hash. If a
* duplicate vnode was found, it will be vget()ed from hash for us.
*/
if ((error = vfs_hash_insert(vp, ino, flags, curthread, vpp)) != 0) {
vput(vp);
*vpp = NULL;
return (error);
}
/* We lost the race, then throw away our vnode and return existing */
if (*vpp != NULL) {
vput(vp);
return (0);
}
/* Read in the disk contents for the inode, copy into the inode. */
#if 0
@ -1159,19 +1149,3 @@ ext2_root(mp, vpp, td)
*vpp = nvp;
return (0);
}
static int
ext2_init(struct vfsconf *vfsp)
{
ext2_ihashinit();
return (0);
}
static int
ext2_uninit(struct vfsconf *vfsp)
{
ext2_ihashuninit();
return (0);
}

View File

@ -3,7 +3,7 @@
.PATH: ${.CURDIR}/../../gnu/ext2fs
KMOD= ext2fs
SRCS= opt_ddb.h opt_quota.h opt_suiddir.h vnode_if.h \
ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_ihash.c ext2_inode.c \
ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_inode.c \
ext2_inode_cnv.c ext2_linux_balloc.c ext2_linux_ialloc.c \
ext2_lookup.c ext2_subr.c ext2_vfsops.c ext2_vnops.c