From d26364a9a9523fcaf47f48750b4c5f6c369cea92 Mon Sep 17 00:00:00 2001 From: phk Date: Mon, 14 Mar 2005 13:22:41 +0000 Subject: Use vfs_hash instead of home-rolled. --- sys/fs/cd9660/cd9660_node.c | 114 +----------------------------------------- sys/fs/cd9660/cd9660_node.h | 2 - sys/fs/cd9660/cd9660_vfsops.c | 40 ++++++++------- sys/fs/cd9660/cd9660_vnops.c | 3 +- sys/fs/cd9660/iso.h | 2 - 5 files changed, 26 insertions(+), 135 deletions(-) (limited to 'sys/fs') diff --git a/sys/fs/cd9660/cd9660_node.c b/sys/fs/cd9660/cd9660_node.c index dcec0ad..8d281de 100644 --- a/sys/fs/cd9660/cd9660_node.c +++ b/sys/fs/cd9660/cd9660_node.c @@ -51,120 +51,9 @@ __FBSDID("$FreeBSD$"); #include #include -/* - * Structures associated with iso_node caching. - */ -static struct iso_node **isohashtbl; -static u_long isohash; -#define INOHASH(device, inum) ((minor(device) + ((inum)>>12)) & isohash) -static struct mtx cd9660_ihash_mtx; - -static void cd9660_ihashrem(struct iso_node *); static unsigned cd9660_chars2ui(unsigned char *begin, int len); /* - * Initialize hash links for inodes and dnodes. - */ -int -cd9660_init(vfsp) - struct vfsconf *vfsp; -{ - - isohashtbl = hashinit(desiredvnodes, M_ISOFSMNT, &isohash); - mtx_init(&cd9660_ihash_mtx, "cd9660_ihash", NULL, MTX_DEF); - return (0); -} - -int -cd9660_uninit(vfsp) - struct vfsconf *vfsp; -{ - - if (isohashtbl != NULL) - free(isohashtbl, M_ISOFSMNT); - return (0); -} - - -/* - * 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. - */ -int -cd9660_ihashget(dev, inum, flags, vpp) - struct cdev *dev; - ino_t inum; - int flags; - struct vnode **vpp; -{ - struct thread *td = curthread; /* XXX */ - struct iso_node *ip; - struct vnode *vp; - int error; - - *vpp = NULL; -loop: - mtx_lock(&cd9660_ihash_mtx); - for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) { - if (inum == ip->i_number && dev == ip->i_dev) { - vp = ITOV(ip); - mtx_lock(&vp->v_interlock); - mtx_unlock(&cd9660_ihash_mtx); - error = vget(vp, flags | LK_INTERLOCK, td); - if (error == ENOENT) - goto loop; - if (error) - return (error); - *vpp = vp; - return (0); - } - } - mtx_unlock(&cd9660_ihash_mtx); - return (0); -} - -/* - * Insert the inode into the hash table, and return it locked. - */ -void -cd9660_ihashins(ip) - struct iso_node *ip; -{ - struct iso_node **ipp, *iq; - - mtx_lock(&cd9660_ihash_mtx); - ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)]; - if ((iq = *ipp) != NULL) - iq->i_prev = &ip->i_next; - ip->i_next = iq; - ip->i_prev = ipp; - *ipp = ip; - mtx_unlock(&cd9660_ihash_mtx); - - vn_lock(ITOV(ip), LK_EXCLUSIVE | LK_RETRY, curthread); -} - -/* - * Remove the inode from the hash table. - */ -static void -cd9660_ihashrem(ip) - struct iso_node *ip; -{ - struct iso_node *iq; - - mtx_lock(&cd9660_ihash_mtx); - if ((iq = ip->i_next) != NULL) - iq->i_prev = ip->i_prev; - *ip->i_prev = iq; -#ifdef DIAGNOSTIC - ip->i_next = NULL; - ip->i_prev = NULL; -#endif - mtx_unlock(&cd9660_ihash_mtx); -} - -/* * Last reference to an inode, write the inode out and if necessary, * truncate and deallocate the file. */ @@ -211,7 +100,8 @@ cd9660_reclaim(ap) /* * Remove the inode from its hash chain. */ - cd9660_ihashrem(ip); + vfs_hash_remove(vp); + /* * Purge old data structures associated with the inode. */ diff --git a/sys/fs/cd9660/cd9660_node.h b/sys/fs/cd9660/cd9660_node.h index a482181..b80dffa 100644 --- a/sys/fs/cd9660/cd9660_node.h +++ b/sys/fs/cd9660/cd9660_node.h @@ -112,8 +112,6 @@ void cd9660_defattr(struct iso_directory_record *, struct iso_node *, struct buf *, enum ISO_FTYPE); void cd9660_deftstamp(struct iso_directory_record *, struct iso_node *, struct buf *, enum ISO_FTYPE); -int cd9660_ihashget(struct cdev *, ino_t, int, struct vnode **); -void cd9660_ihashins(struct iso_node *); int cd9660_tstamp_conv7(u_char *, struct timespec *, enum ISO_FTYPE); int cd9660_tstamp_conv17(u_char *, struct timespec *); diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index df1a628..bcbcae8 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -78,12 +78,10 @@ static vfs_vptofh_t cd9660_vptofh; static struct vfsops cd9660_vfsops = { .vfs_fhtovp = cd9660_fhtovp, - .vfs_init = cd9660_init, .vfs_mount = cd9660_mount, .vfs_cmount = cd9660_cmount, .vfs_root = cd9660_root, .vfs_statfs = cd9660_statfs, - .vfs_uninit = cd9660_uninit, .vfs_unmount = cd9660_unmount, .vfs_vget = cd9660_vget, .vfs_vptofh = cd9660_vptofh, @@ -663,13 +661,15 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) struct cdev *dev; int error; - imp = VFSTOISOFS(mp); - dev = imp->im_dev; - if ((error = cd9660_ihashget(dev, ino, flags, vpp)) != 0) + error = vfs_hash_get(mp, ino, flags, curthread, vpp); + if (error) return (error); if (*vpp != NULL) return (0); + imp = VFSTOISOFS(mp); + dev = imp->im_dev; + /* Allocate a new vnode/iso_node. */ if ((error = getnewvnode("isofs", mp, &cd9660_vnodeops, &vp)) != 0) { *vpp = NULLVP; @@ -683,24 +683,28 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) ip->i_number = ino; /* - * Check to be sure that it did not show up. We have to put it - * on the hash chain as the cleanup from vput expects to find - * it there. + * 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 = cd9660_ihashget(dev, ino, flags, vpp)) != 0 || - *vpp != NULL) { - cd9660_ihashins(ip); + if ((error = vfs_hash_insert(vp, ino, flags, curthread, vpp)) != 0) { vput(vp); + *vpp = NULL; return (error); } - /* - * 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. - */ - cd9660_ihashins(ip); + /* We lost the race, then throw away our vnode and return existing */ + if (*vpp != NULL) { + vput(vp); + return (0); + } if (isodir == 0) { int lbn, off; diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index 5b3d723..f3d279f 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -187,7 +188,7 @@ cd9660_getattr(ap) struct vattr *vap = ap->a_vap; struct iso_node *ip = VTOI(vp); - vap->va_fsid = dev2udev(ip->i_dev); + vap->va_fsid = dev2udev(ip->i_dev); /* XXX WRONG! */ vap->va_fileid = ip->i_number; vap->va_mode = ip->inode.iso_mode; diff --git a/sys/fs/cd9660/iso.h b/sys/fs/cd9660/iso.h index f0b5221..8645f58 100644 --- a/sys/fs/cd9660/iso.h +++ b/sys/fs/cd9660/iso.h @@ -258,8 +258,6 @@ struct iso_mnt { int cd9660_vget_internal(struct mount *, ino_t, int, struct vnode **, int, struct iso_directory_record *); -int cd9660_init(struct vfsconf *); -int cd9660_uninit(struct vfsconf *); #define cd9660_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \ size_t, struct proc *))eopnotsupp) -- cgit v1.1