summaryrefslogtreecommitdiffstats
path: root/sys/isofs
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2005-03-14 13:22:41 +0000
committerphk <phk@FreeBSD.org>2005-03-14 13:22:41 +0000
commitd26364a9a9523fcaf47f48750b4c5f6c369cea92 (patch)
tree0433332e412d74e1f69c6e19d3adb43354cb208f /sys/isofs
parent8ef3f502d08b321a9ca55323f411a12a33c0618a (diff)
downloadFreeBSD-src-d26364a9a9523fcaf47f48750b4c5f6c369cea92.zip
FreeBSD-src-d26364a9a9523fcaf47f48750b4c5f6c369cea92.tar.gz
Use vfs_hash instead of home-rolled.
Diffstat (limited to 'sys/isofs')
-rw-r--r--sys/isofs/cd9660/cd9660_node.c114
-rw-r--r--sys/isofs/cd9660/cd9660_node.h2
-rw-r--r--sys/isofs/cd9660/cd9660_vfsops.c40
-rw-r--r--sys/isofs/cd9660/cd9660_vnops.c3
-rw-r--r--sys/isofs/cd9660/iso.h2
5 files changed, 26 insertions, 135 deletions
diff --git a/sys/isofs/cd9660/cd9660_node.c b/sys/isofs/cd9660/cd9660_node.c
index dcec0ad..8d281de 100644
--- a/sys/isofs/cd9660/cd9660_node.c
+++ b/sys/isofs/cd9660/cd9660_node.c
@@ -51,120 +51,9 @@ __FBSDID("$FreeBSD$");
#include <isofs/cd9660/cd9660_node.h>
#include <isofs/cd9660/cd9660_mount.h>
-/*
- * 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/isofs/cd9660/cd9660_node.h b/sys/isofs/cd9660/cd9660_node.h
index a482181..b80dffa 100644
--- a/sys/isofs/cd9660/cd9660_node.h
+++ b/sys/isofs/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/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c
index df1a628..bcbcae8 100644
--- a/sys/isofs/cd9660/cd9660_vfsops.c
+++ b/sys/isofs/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/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c
index 5b3d723..f3d279f 100644
--- a/sys/isofs/cd9660/cd9660_vnops.c
+++ b/sys/isofs/cd9660/cd9660_vnops.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/namei.h>
#include <sys/kernel.h>
+#include <sys/conf.h>
#include <sys/stat.h>
#include <sys/bio.h>
#include <sys/buf.h>
@@ -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/isofs/cd9660/iso.h b/sys/isofs/cd9660/iso.h
index f0b5221..8645f58 100644
--- a/sys/isofs/cd9660/iso.h
+++ b/sys/isofs/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)
OpenPOWER on IntegriCloud