diff options
author | phk <phk@FreeBSD.org> | 2005-03-14 13:30:06 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2005-03-14 13:30:06 +0000 |
commit | 6ead7c4f270898b9ea90b3134fcacdbcd2adf669 (patch) | |
tree | 660fc5b3afc8d9c187611e4db8814fd90b517adb /sys/gnu/ext2fs | |
parent | d26364a9a9523fcaf47f48750b4c5f6c369cea92 (diff) | |
download | FreeBSD-src-6ead7c4f270898b9ea90b3134fcacdbcd2adf669.zip FreeBSD-src-6ead7c4f270898b9ea90b3134fcacdbcd2adf669.tar.gz |
Use vfs_hash() instead of home-rolled
Diffstat (limited to 'sys/gnu/ext2fs')
-rw-r--r-- | sys/gnu/ext2fs/ext2_extern.h | 7 | ||||
-rw-r--r-- | sys/gnu/ext2fs/ext2_ihash.c | 8 | ||||
-rw-r--r-- | sys/gnu/ext2fs/ext2_inode.c | 5 | ||||
-rw-r--r-- | sys/gnu/ext2fs/ext2_vfsops.c | 80 |
4 files changed, 32 insertions, 68 deletions
diff --git a/sys/gnu/ext2fs/ext2_extern.h b/sys/gnu/ext2fs/ext2_extern.h index 367b633..24c8f45 100644 --- a/sys/gnu/ext2fs/ext2_extern.h +++ b/sys/gnu/ext2fs/ext2_extern.h @@ -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 *); diff --git a/sys/gnu/ext2fs/ext2_ihash.c b/sys/gnu/ext2fs/ext2_ihash.c index 7bc049e..5106f37 100644 --- a/sys/gnu/ext2fs/ext2_ihash.c +++ b/sys/gnu/ext2fs/ext2_ihash.c @@ -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); diff --git a/sys/gnu/ext2fs/ext2_inode.c b/sys/gnu/ext2fs/ext2_inode.c index 2f48f9c..7a8e5e0 100644 --- a/sys/gnu/ext2fs/ext2_inode.c +++ b/sys/gnu/ext2fs/ext2_inode.c @@ -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. */ diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c index 1e73e12..81787f8 100644 --- a/sys/gnu/ext2fs/ext2_vfsops.c +++ b/sys/gnu/ext2fs/ext2_vfsops.c @@ -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. + * 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. */ - ext2_ihashins(ip); + lockmgr(vp->v_vnlock, LK_EXCLUSIVE, (struct mtx *)0, curthread); - if (ext2fs_inode_hash_lock < 0) - wakeup(&ext2fs_inode_hash_lock); - ext2fs_inode_hash_lock = 0; + /* + * 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); -} |