From 1e7f37465524228103006505e318b7b67ba46a56 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Mon, 14 Apr 2014 22:46:05 +0000 Subject: [PATCH 12/14] Convert ufs (ffs, ext2fs) to use vinotab(9). --- sys/rump/fs/lib/libffs/Makefile | 2 +- sys/ufs/ext2fs/ext2fs_vfsops.c | 95 ++++++++++---------- sys/ufs/ffs/ffs_vfsops.c | 98 ++++++++++----------- sys/ufs/files.ufs | 1 - sys/ufs/ufs/inode.h | 6 +- sys/ufs/ufs/ufs_dirhash.c | 6 +- sys/ufs/ufs/ufs_extern.h | 11 +-- sys/ufs/ufs/ufs_ihash.c | 188 ---------------------------------------- sys/ufs/ufs/ufs_inode.c | 6 +- sys/ufs/ufs/ufs_vfsops.c | 27 +++++- sys/ufs/ufs/ufsmount.h | 1 + 11 files changed, 123 insertions(+), 318 deletions(-) delete mode 100644 sys/ufs/ufs/ufs_ihash.c diff --git a/sys/rump/fs/lib/libffs/Makefile b/sys/rump/fs/lib/libffs/Makefile index 0d2ce9f..52310a0 100644 --- a/sys/rump/fs/lib/libffs/Makefile +++ b/sys/rump/fs/lib/libffs/Makefile @@ -9,7 +9,7 @@ SRCS= ffs_alloc.c ffs_appleufs.c ffs_balloc.c ffs_bswap.c ffs_inode.c \ ffs_snapshot.c ffs_subr.c ffs_tables.c ffs_vfsops.c ffs_vnops.c \ ffs_wapbl.c ffs_quota2.c -SRCS+= ufs_bmap.c ufs_dirhash.c ufs_extattr.c ufs_ihash.c ufs_inode.c \ +SRCS+= ufs_bmap.c ufs_dirhash.c ufs_extattr.c ufs_inode.c \ ufs_lookup.c ufs_rename.c ufs_vfsops.c ufs_vnops.c ufs_wapbl.c \ ufs_quota.c ufs_quota2.c quota2_subr.c diff --git a/sys/ufs/ext2fs/ext2fs_vfsops.c b/sys/ufs/ext2fs/ext2fs_vfsops.c index a04e51b..212ddec 100644 --- a/sys/ufs/ext2fs/ext2fs_vfsops.c +++ b/sys/ufs/ext2fs/ext2fs_vfsops.c @@ -88,6 +88,7 @@ __KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.179 2014/03/23 15:21:16 hannken #include #include #include +#include #include #include @@ -664,6 +665,7 @@ ext2fs_mountfs(struct vnode *devvp, struct mount *mp) ump = kmem_zalloc(sizeof(*ump), KM_SLEEP); ump->um_fstype = UFS1; ump->um_ops = &ext2fs_ufsops; + ump->um_vinotab = vinotab_create(mp, &ufs_vinotab_ops); ump->um_e2fs = kmem_zalloc(sizeof(struct m_ext2fs), KM_SLEEP); e2fs_sbload((struct ext2fs *)bp->b_data, &ump->um_e2fs->e2fs); brelse(bp, 0); @@ -743,6 +745,7 @@ out: brelse(bp, 0); if (ump) { kmem_free(ump->um_e2fs, sizeof(struct m_ext2fs)); + vinotab_destroy(ump->um_vinotab); kmem_free(ump, sizeof(*ump)); mp->mnt_data = NULL; } @@ -780,6 +783,7 @@ ext2fs_unmount(struct mount *mp, int mntflags) vput(ump->um_devvp); kmem_free(fs->e2fs_gd, fs->e2fs_ngdb * fs->e2fs_bsize); kmem_free(fs, sizeof(*fs)); + vinotab_destroy(ump->um_vinotab); kmem_free(ump, sizeof(*ump)); mp->mnt_data = NULL; mp->mnt_flag &= ~MNT_LOCAL; @@ -960,31 +964,25 @@ ext2fs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) ump = VFSTOUFS(mp); dev = ump->um_dev; -retry: - if ((*vpp = ufs_ihashget(dev, ino, 0, true)) != NULL) - return (0); - /* Allocate a new vnode/inode. */ - error = getnewvnode(VT_EXT2FS, mp, ext2fs_vnodeop_p, NULL, 0, &vp); - if (error) { - *vpp = NULL; - return (error); +retry: /* Get the vnode for this inode number if it exists. */ + error = vinotab_get(ump->um_vinotab, &ino, flags, &vp); + if (__predict_true(error == 0)) { + *vpp = vp; + return 0; } - ip = pool_get(&ext2fs_inode_pool, PR_WAITOK); + if (error != ENOENT) + goto fail0; - mutex_enter(&ufs_hashlock); - if ((*vpp = ufs_ihashget(dev, ino, 0, false)) != NULL) { - mutex_exit(&ufs_hashlock); - ungetnewvnode(vp); - pool_put(&ext2fs_inode_pool, ip); - goto retry; - } + /* Allocate a new vnode/inode. */ + error = getnewvnode(VT_EXT2FS, mp, ext2fs_vnodeop_p, NULL, 0, &vp); + if (error) + goto fail0; vp->v_vflag |= VV_LOCKSWORK; + ip = vp->v_data = pool_get(&ext2fs_inode_pool, PR_WAITOK); memset(ip, 0, sizeof(struct inode)); - vp->v_data = ip; - ip->i_vnode = vp; ip->i_ump = ump; ip->i_e2fs = fs = ump->um_e2fs; ip->i_dev = dev; @@ -993,33 +991,20 @@ retry: ip->i_e2fs_last_blk = 0; genfs_node_init(vp, &ext2fs_genfsops); - /* - * 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. - */ - - ufs_ihashins(ip); - mutex_exit(&ufs_hashlock); + /* Cache this vnode. If someone beat us, back out and try again. */ + error = vinotab_insert(ump->um_vinotab, vp, flags); + if (error) { + genfs_node_destroy(vp); + pool_put(&ext2fs_inode_pool, ip); + ungetnewvnode(vp); + goto retry; + } /* Read in the disk contents for the inode, copy into the inode. */ error = bread(ump->um_devvp, EXT2_FSBTODB(fs, ino_to_fsba(fs, ino)), (int)fs->e2fs_bsize, NOCRED, 0, &bp); - if (error) { - - /* - * The inode does not contain anything useful, so it would - * be misleading to leave it on its hash chain. With mode - * still zero, it will be unlinked and returned to the free - * list by vrele(). - */ - - vready_fail(vp); - vrele(vp); - *vpp = NULL; - return (error); - } + if (error) + goto fail1; cp = (char *)bp->b_data + (ino_to_fsbo(fs, ino) * EXT2_DINODE_SIZE(fs)); ip->i_din.e2fs_din = pool_get(&ext2fs_dinode_pool, PR_WAITOK); e2fs_iload((struct ext2fs_dinode *)cp, ip->i_din.e2fs_din); @@ -1036,19 +1021,21 @@ retry: /* * Initialize the vnode from the inode, check for aliases. + * + * XXX We no longer eliminate aliases, so this cannot fail. */ - error = ext2fs_vinit(mp, ext2fs_specop_p, ext2fs_fifoop_p, &vp); - if (error) { - vready_fail(vp); - vrele(vp); - *vpp = NULL; - return (error); - } + if (error) + goto fail1; + /* * Finish inode initialization now that aliasing has been resolved. + * + * XXX We no longer eliminate aliases, so this need not be + * separated from the rest of initialization. (It's also not + * clear to me that struct inode needs to have a pointter to + * the device vnode.) */ - ip->i_devvp = ump->um_devvp; vref(ip->i_devvp); @@ -1056,7 +1043,6 @@ retry: * Set up a generation number for this inode if it does not * already have one. This should only happen on old filesystems. */ - if (ip->i_e2fs_gen == 0) { if (++ext2gennumber < (u_long)time_second) ext2gennumber = time_second; @@ -1064,10 +1050,17 @@ retry: if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) ip->i_flag |= IN_MODIFIED; } + uvm_vnp_setsize(vp, ext2fs_size(ip)); vready(vp); *vpp = vp; - return (0); + return 0; + +fail1: vready_fail(vp); + vrele(vp); +fail0: KASSERT(error); + *vpp = NULL; + return error; } /* diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index c0d5d21..0e56c4a 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -94,6 +94,7 @@ __KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.296 2014/04/01 14:28:17 christos Ex #include #include #include +#include #include #include @@ -891,6 +892,7 @@ ffs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l) ump = kmem_zalloc(sizeof(*ump), KM_SLEEP); mutex_init(&ump->um_lock, MUTEX_DEFAULT, IPL_NONE); + ump->um_vinotab = vinotab_create(mp, &ufs_vinotab_ops); error = ffs_snapshot_init(ump); if (error) goto out; @@ -1300,6 +1302,7 @@ out: if (ump) { if (ump->um_oldfscompat) kmem_free(ump->um_oldfscompat, 512 + 3*sizeof(int32_t)); + vinotab_destroy(ump->um_vinotab); mutex_destroy(&ump->um_lock); kmem_free(ump, sizeof(*ump)); mp->mnt_data = NULL; @@ -1490,6 +1493,7 @@ ffs_unmount(struct mount *mp, int mntflags) kmem_free(ump->um_oldfscompat, 512 + 3*sizeof(int32_t)); mutex_destroy(&ump->um_lock); ffs_snapshot_fini(ump); + vinotab_destroy(ump->um_vinotab); kmem_free(ump, sizeof(*ump)); mp->mnt_data = NULL; mp->mnt_flag &= ~MNT_LOCAL; @@ -1742,40 +1746,24 @@ ffs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) ump = VFSTOUFS(mp); dev = ump->um_dev; - retry: - if ((*vpp = ufs_ihashget(dev, ino, 0, true)) != NULL) - return (0); +retry: /* Get the vnode for this inode number if it exists. */ + error = vinotab_get(ump->um_vinotab, &ino, flags, &vp); + if (__predict_true(error == 0)) { + *vpp = vp; + return 0; + } + if (error != ENOENT) + goto fail0; /* Allocate a new vnode/inode. */ error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, NULL, 0, &vp); - if (error) { - *vpp = NULL; - return (error); - } - ip = pool_cache_get(ffs_inode_cache, PR_WAITOK); - - /* - * If someone beat us to it, put back the freshly allocated - * vnode/inode pair and retry. - */ - mutex_enter(&ufs_hashlock); - if (ufs_ihashget(dev, ino, 0, false) != NULL) { - mutex_exit(&ufs_hashlock); - ungetnewvnode(vp); - pool_cache_put(ffs_inode_cache, ip); - goto retry; - } + if (error) + goto fail0; vp->v_vflag |= VV_LOCKSWORK; - /* - * XXX MFS ends up here, too, to allocate an inode. Should we - * XXX create another pool for MFS inodes? - */ - + ip = vp->v_data = pool_cache_get(ffs_inode_cache, PR_WAITOK); memset(ip, 0, sizeof(struct inode)); - vp->v_data = ip; - ip->i_vnode = vp; ip->i_ump = ump; ip->i_fs = fs = ump->um_fs; ip->i_dev = dev; @@ -1790,33 +1778,23 @@ ffs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) */ genfs_node_init(vp, &ffs_genfsops); - /* - * 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. - */ - - ufs_ihashins(ip); - mutex_exit(&ufs_hashlock); + /* Cache this vnode. If someone beat us, back out and try again. */ + error = vinotab_insert(ump->um_vinotab, vp, flags); + if (error) { + genfs_node_destroy(vp); +#if defined(QUOTA) || defined(QUOTA2) + ufsquota_free(ip); +#endif + pool_cache_put(ffs_inode_cache, ip); + ungetnewvnode(vp); + goto retry; + } /* Read in the disk contents for the inode, copy into the inode. */ error = bread(ump->um_devvp, FFS_FSBTODB(fs, ino_to_fsba(fs, ino)), (int)fs->fs_bsize, NOCRED, 0, &bp); - if (error) { - - /* - * The inode does not contain anything useful, so it would - * be misleading to leave it on its hash chain. With mode - * still zero, it will be unlinked and returned to the free - * list by vrele(). - */ - - vready_fail(vp); - vrele(vp); - *vpp = NULL; - return (error); - } + if (error) + goto fail1; if (ip->i_ump->um_fstype == UFS1) ip->i_din.ffs1_din = pool_cache_get(ffs_dinode1_cache, PR_WAITOK); @@ -1829,30 +1807,42 @@ ffs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) /* * Initialize the vnode from the inode, check for aliases. * Note that the underlying vnode may have changed. + * + * XXX We no longer eliminate aliases, so this is not an issue. */ - ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp); /* * Finish inode initialization now that aliasing has been resolved. + * + * XXX We no longer eliminate aliases, so this need not be + * separated from the rest of initialization. (It's also not + * clear to me that struct inode needs to have a pointter to + * the device vnode.) */ - ip->i_devvp = ump->um_devvp; vref(ip->i_devvp); /* * Ensure that uid and gid are correct. This is a temporary * fix until fsck has been changed to do the update. + * + * XXX Temporary indeed. That comment was written in 1994! */ - if (fs->fs_old_inodefmt < FS_44INODEFMT) { /* XXX */ ip->i_uid = ip->i_ffs1_ouid; /* XXX */ ip->i_gid = ip->i_ffs1_ogid; /* XXX */ } /* XXX */ + uvm_vnp_setsize(vp, ip->i_size); vready(vp); *vpp = vp; - return (0); + return 0; + +fail1: vready_fail(vp); + vrele(vp); +fail0: *vpp = NULL; + return error; } /* diff --git a/sys/ufs/files.ufs b/sys/ufs/files.ufs index 466d5df..883c73d 100644 --- a/sys/ufs/files.ufs +++ b/sys/ufs/files.ufs @@ -94,7 +94,6 @@ file ufs/mfs/mfs_miniroot.c file ufs/ufs/ufs_bmap.c ffs | mfs | ext2fs | chfs file ufs/ufs/ufs_dirhash.c (ffs | mfs | ext2fs | chfs) & ufs_dirhash file ufs/ufs/ufs_extattr.c (ffs | mfs) & ufs_extattr -file ufs/ufs/ufs_ihash.c ffs | mfs | ext2fs file ufs/ufs/ufs_inode.c ffs | mfs | ext2fs file ufs/ufs/ufs_lookup.c ffs | mfs | ext2fs | chfs file ufs/ufs/ufs_quota.c (quota | quota2) & (ffs | mfs | ext2fs | chfs) diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h index 21696c2..949a832 100644 --- a/sys/ufs/ufs/inode.h +++ b/sys/ufs/ufs/inode.h @@ -40,6 +40,7 @@ #define _UFS_UFS_INODE_H_ #include +#include #include #include #include @@ -93,9 +94,8 @@ struct lfs_inode_ext; */ struct inode { struct genfs_node i_gnode; - LIST_ENTRY(inode) i_hash;/* Hash chain. */ TAILQ_ENTRY(inode) i_nextsnap; /* snapshot file list. */ - struct vnode *i_vnode; /* Vnode associated with this inode. */ + struct vinotab_entry i_vinotab_entry; struct ufsmount *i_ump; /* Mount point associated with this inode. */ struct vnode *i_devvp; /* Vnode for block I/O. */ u_int32_t i_flag; /* flags, see below */ @@ -290,7 +290,7 @@ struct indir { /* Convert between inode pointers and vnode pointers. */ #define VTOI(vp) ((struct inode *)(vp)->v_data) -#define ITOV(ip) ((ip)->i_vnode) +#define ITOV(ip) vinotab_entry_vnode(&(ip)->i_vinotab_entry) /* This overlays the fid structure (see fstypes.h). */ struct ufid { diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c index 9a0cf8a..700cf40 100644 --- a/sys/ufs/ufs/ufs_dirhash.c +++ b/sys/ufs/ufs/ufs_dirhash.c @@ -143,7 +143,7 @@ ufsdirhash_build(struct inode *ip) if (ip->i_nlink == 0) return (-1); - vp = ip->i_vnode; + vp = ITOV(ip); /* Allocate 50% more entries than this dir size could ever need. */ KASSERT(ip->i_size >= dirblksiz); nslots = ip->i_size / UFS_DIRECTSIZ(1); @@ -375,7 +375,7 @@ ufsdirhash_lookup(struct inode *ip, const char *name, int namelen, doff_t *offp, if (dh->dh_score < DH_SCOREMAX) dh->dh_score++; - vp = ip->i_vnode; + vp = ITOV(ip); bmask = VFSTOUFS(vp->v_mount)->um_mountp->mnt_stat.f_iosize - 1; blkoff = -1; bp = NULL; @@ -528,7 +528,7 @@ ufsdirhash_findfree(struct inode *ip, int slotneeded, int *slotsize) KASSERT(dirblock < dh->dh_nblk && dh->dh_blkfree[dirblock] >= howmany(slotneeded, DIRALIGN)); pos = dirblock * dirblksiz; - error = ufs_blkatoff(ip->i_vnode, (off_t)pos, (void *)&dp, &bp, false); + error = ufs_blkatoff(ITOV(ip), (off_t)pos, (void *)&dp, &bp, false); if (error) { DIRHASH_UNLOCK(dh); return (-1); diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index 4413c3b..ca811e9 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -108,15 +108,6 @@ int ufs_bmaparray(struct vnode *, daddr_t, daddr_t *, struct indir *, int *, int *, ufs_issequential_callback_t); int ufs_getlbns(struct vnode *, daddr_t, struct indir *, int *); -/* ufs_ihash.c */ -void ufs_ihashinit(void); -void ufs_ihashreinit(void); -void ufs_ihashdone(void); -struct vnode *ufs_ihashlookup(dev_t, ino_t); -struct vnode *ufs_ihashget(dev_t, ino_t, int, bool); -void ufs_ihashins(struct inode *); -void ufs_ihashrem(struct inode *); - /* ufs_inode.c */ int ufs_reclaim(struct vnode *); int ufs_balloc_range(struct vnode *, off_t, off_t, kauth_cred_t, int); @@ -191,6 +182,8 @@ int ufs_root(struct mount *, int, struct vnode **); int ufs_quotactl(struct mount *, struct quotactl_args *); int ufs_fhtovp(struct mount *, struct ufid *, int, struct vnode **); +extern const struct vinotab_ops ufs_vinotab_ops; + /* ufs_vnops.c */ void ufs_vinit(struct mount *, int (**)(void *), int (**)(void *), struct vnode **); diff --git a/sys/ufs/ufs/ufs_ihash.c b/sys/ufs/ufs/ufs_ihash.c deleted file mode 100644 index d363f9e0..0000000 --- a/sys/ufs/ufs/ufs_ihash.c +++ /dev/null @@ -1,188 +0,0 @@ -/* $NetBSD: ufs_ihash.c,v 1.32 2014/02/27 16:51:39 hannken Exp $ */ - -/* - * Copyright (c) 1982, 1986, 1989, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufs_ihash.c 8.7 (Berkeley) 5/17/95 - */ - -#include -__KERNEL_RCSID(0, "$NetBSD: ufs_ihash.c,v 1.32 2014/02/27 16:51:39 hannken Exp $"); - -#include -#include -#include -#include -#include - -#include -#include - -/* - * Structures associated with inode cacheing. - */ -static LIST_HEAD(ihashhead, inode) *ihashtbl; -static u_long ihash; /* size of hash table - 1 */ -#define INOHASH(device, inum) (((device) + (inum)) & ihash) - -kmutex_t ufs_ihash_lock; -kmutex_t ufs_hashlock; - -/* - * Initialize inode hash table. - */ -void -ufs_ihashinit(void) -{ - - mutex_init(&ufs_hashlock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&ufs_ihash_lock, MUTEX_DEFAULT, IPL_NONE); - ihashtbl = hashinit(desiredvnodes, HASH_LIST, true, &ihash); -} - -/* - * Reinitialize inode hash table. - */ - -void -ufs_ihashreinit(void) -{ - struct inode *ip; - struct ihashhead *oldhash, *hash; - u_long oldmask, mask, val; - int i; - - hash = hashinit(desiredvnodes, HASH_LIST, true, &mask); - mutex_enter(&ufs_ihash_lock); - oldhash = ihashtbl; - oldmask = ihash; - ihashtbl = hash; - ihash = mask; - for (i = 0; i <= oldmask; i++) { - while ((ip = LIST_FIRST(&oldhash[i])) != NULL) { - LIST_REMOVE(ip, i_hash); - val = INOHASH(ip->i_dev, ip->i_number); - LIST_INSERT_HEAD(&hash[val], ip, i_hash); - } - } - mutex_exit(&ufs_ihash_lock); - hashdone(oldhash, HASH_LIST, oldmask); -} - -/* - * Free inode hash table. - */ -void -ufs_ihashdone(void) -{ - - hashdone(ihashtbl, HASH_LIST, ihash); - mutex_destroy(&ufs_hashlock); - mutex_destroy(&ufs_ihash_lock); -} - -/* - * Use the device/inum pair to find the incore inode, and return a pointer - * to it. If it is in core, return it, even if it is locked. - */ -struct vnode * -ufs_ihashlookup(dev_t dev, ino_t inum) -{ - struct inode *ip; - struct ihashhead *ipp; - - KASSERT(mutex_owned(&ufs_ihash_lock)); - - ipp = &ihashtbl[INOHASH(dev, inum)]; - LIST_FOREACH(ip, ipp, i_hash) { - if (inum == ip->i_number && dev == ip->i_dev) - break; - } - if (ip) - return (ITOV(ip)); - return (NULLVP); -} - -/* - * Use the device/inum pair to find the incore inode, and return a pointer - * to it. If it is in core, but locked, wait for it. - */ -struct vnode * -ufs_ihashget(dev_t dev, ino_t inum, int flags, bool do_vget) -{ - struct ihashhead *ipp; - struct inode *ip; - struct vnode *vp; - - loop: - mutex_enter(&ufs_ihash_lock); - ipp = &ihashtbl[INOHASH(dev, inum)]; - LIST_FOREACH(ip, ipp, i_hash) { - if (inum == ip->i_number && dev == ip->i_dev) { - vp = ITOV(ip); - if (!do_vget) { - mutex_exit(&ufs_ihash_lock); - } else { - mutex_enter(vp->v_interlock); - mutex_exit(&ufs_ihash_lock); - if (vget(vp, flags)) - goto loop; - } - return (vp); - } - } - mutex_exit(&ufs_ihash_lock); - return (NULL); -} - -/* - * Insert the inode into the hash table. - */ -void -ufs_ihashins(struct inode *ip) -{ - struct ihashhead *ipp; - - KASSERT(mutex_owned(&ufs_hashlock)); - - mutex_enter(&ufs_ihash_lock); - ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)]; - LIST_INSERT_HEAD(ipp, ip, i_hash); - mutex_exit(&ufs_ihash_lock); -} - -/* - * Remove the inode from the hash table. - */ -void -ufs_ihashrem(struct inode *ip) -{ - mutex_enter(&ufs_ihash_lock); - LIST_REMOVE(ip, i_hash); - mutex_exit(&ufs_ihash_lock); -} diff --git a/sys/ufs/ufs/ufs_inode.c b/sys/ufs/ufs/ufs_inode.c index f42c1d3..b0287c3 100644 --- a/sys/ufs/ufs/ufs_inode.c +++ b/sys/ufs/ufs/ufs_inode.c @@ -190,11 +190,6 @@ ufs_reclaim(struct vnode *vp) } UFS_UPDATE(vp, NULL, NULL, UPDATE_CLOSE); - /* - * Remove the inode from its hash chain. - */ - ufs_ihashrem(ip); - if (ip->i_devvp) { vrele(ip->i_devvp); ip->i_devvp = 0; @@ -206,6 +201,7 @@ ufs_reclaim(struct vnode *vp) if (ip->i_dirhash != NULL) ufsdirhash_free(ip); #endif + vinotab_remove(VFSTOUFS(vp->v_mount)->um_vinotab, vp); return (0); } diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index a368d46..2c32558 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -69,6 +69,30 @@ static int ufs_initcount = 0; pool_cache_t ufs_direct_cache; +static const void * +ufs_vinotab_get_key(void *arg __unused, const void *key, size_t *sizep) +{ + const ino_t *const inop = key; + + *sizep = sizeof(*inop); + return inop; +} + +static const void * +ufs_vinotab_vnode_key(void *arg __unused, struct vnode *vp, size_t *sizep) +{ + const ino_t *const inop = &VTOI(vp)->i_number; + + *sizep = sizeof(*inop); + return inop; +} + +const struct vinotab_ops ufs_vinotab_ops = { + .vto_get_key = ufs_vinotab_get_key, + .vto_vnode_key = ufs_vinotab_vnode_key, + .vto_entry_offset = offsetof(struct inode, i_vinotab_entry), +}; + /* * Make a filesystem operational. * Nothing to do at the moment. @@ -259,7 +283,6 @@ ufs_init(void) ufs_direct_cache = pool_cache_init(sizeof(struct direct), 0, 0, 0, "ufsdir", NULL, IPL_NONE, NULL, NULL, NULL); - ufs_ihashinit(); #if defined(QUOTA) || defined(QUOTA2) dqinit(); #endif @@ -274,7 +297,6 @@ ufs_init(void) void ufs_reinit(void) { - ufs_ihashreinit(); #if defined(QUOTA) || defined(QUOTA2) dqreinit(); #endif @@ -289,7 +311,6 @@ ufs_done(void) if (--ufs_initcount > 0) return; - ufs_ihashdone(); #if defined(QUOTA) || defined(QUOTA2) dqdone(); #endif diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h index c5790aa..3194be3 100644 --- a/sys/ufs/ufs/ufsmount.h +++ b/sys/ufs/ufs/ufsmount.h @@ -76,6 +76,7 @@ struct ufsmount { struct mount *um_mountp; /* filesystem vfs structure */ dev_t um_dev; /* device mounted */ struct vnode *um_devvp; /* block device mounted vnode */ + struct vinotab *um_vinotab; /* inode->vnode table */ u_long um_fstype; u_int32_t um_flags; /* UFS-specific flags - see below */ union { /* pointer to superblock */ -- 1.8.3.1