Use vfs_hash instead of home-rolled.

This commit is contained in:
phk 2005-03-14 13:22:41 +00:00
parent 8ef3f502d0
commit d26364a9a9
10 changed files with 52 additions and 270 deletions

View File

@ -51,119 +51,8 @@ __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.
*/

View File

@ -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 *);

View File

@ -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.
*/
if ((error = cd9660_ihashget(dev, ino, flags, vpp)) != 0 ||
*vpp != NULL) {
cd9660_ihashins(ip);
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);
}
/*
* 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;

View File

@ -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;

View File

@ -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)

View File

@ -51,119 +51,8 @@ __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.
*/

View File

@ -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 *);

View File

@ -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.
*/
if ((error = cd9660_ihashget(dev, ino, flags, vpp)) != 0 ||
*vpp != NULL) {
cd9660_ihashins(ip);
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);
}
/*
* 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;

View File

@ -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;

View File

@ -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)