Use vfs_hash instead of home-rolled.
This commit is contained in:
parent
8ef3f502d0
commit
d26364a9a9
@ -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.
|
||||
*/
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user