Merge locking changes + fixes from the vmlocking branch.
This commit is contained in:
parent
e1d841a734
commit
6a3b582fe3
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cd9660_node.c,v 1.18 2007/11/26 19:01:42 pooka Exp $ */
|
||||
/* $NetBSD: cd9660_node.c,v 1.19 2007/12/08 14:41:11 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1989, 1994
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd9660_node.c,v 1.18 2007/11/26 19:01:42 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd9660_node.c,v 1.19 2007/12/08 14:41:11 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -64,13 +64,8 @@ __KERNEL_RCSID(0, "$NetBSD: cd9660_node.c,v 1.18 2007/11/26 19:01:42 pooka Exp $
|
||||
LIST_HEAD(ihashhead, iso_node) *isohashtbl;
|
||||
u_long isohash;
|
||||
#define INOHASH(device, inum) (((device) + ((inum)>>12)) & isohash)
|
||||
struct simplelock cd9660_ihash_slock;
|
||||
|
||||
#ifdef ISODEVMAP
|
||||
LIST_HEAD(idvhashhead, iso_dnode) *idvhashtbl;
|
||||
u_long idvhash;
|
||||
#define DNOHASH(device, inum) (((device) + ((inum)>>12)) & idvhash)
|
||||
#endif
|
||||
kmutex_t cd9660_ihash_lock;
|
||||
kmutex_t cd9660_hashlock;
|
||||
|
||||
extern int prtactive; /* 1 => print out reclaim of active vnodes */
|
||||
|
||||
@ -90,11 +85,8 @@ cd9660_init()
|
||||
"cd9660nopl", &pool_allocator_nointr, IPL_NONE);
|
||||
isohashtbl = hashinit(desiredvnodes, HASH_LIST, M_ISOFSMNT, M_WAITOK,
|
||||
&isohash);
|
||||
simple_lock_init(&cd9660_ihash_slock);
|
||||
#ifdef ISODEVMAP
|
||||
idvhashtbl = hashinit(desiredvnodes / 8, HASH_LIST, M_ISOFSMNT,
|
||||
M_WAITOK, &idvhash);
|
||||
#endif
|
||||
mutex_init(&cd9660_ihash_lock, MUTEX_DEFAULT, IPL_NONE);
|
||||
mutex_init(&cd9660_hashlock, MUTEX_DEFAULT, IPL_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -107,38 +99,16 @@ cd9660_reinit()
|
||||
struct iso_node *ip;
|
||||
struct ihashhead *oldhash1, *hash1;
|
||||
u_long oldmask1, mask1, val;
|
||||
#ifdef ISODEVMAP
|
||||
struct iso_dnode *dp;
|
||||
struct idvhashhead *oldhash2, *hash2;
|
||||
u_long oldmask2, mask2;
|
||||
#endif
|
||||
u_int i;
|
||||
|
||||
hash1 = hashinit(desiredvnodes, HASH_LIST, M_ISOFSMNT, M_WAITOK,
|
||||
&mask1);
|
||||
#ifdef ISODEVMAP
|
||||
hash2 = hashinit(desiredvnodes / 8, HASH_LIST, M_ISOFSMNT, M_WAITOK,
|
||||
&mask2);
|
||||
#endif
|
||||
|
||||
simple_lock(&cd9660_ihash_slock);
|
||||
mutex_enter(&cd9660_ihash_lock);
|
||||
oldhash1 = isohashtbl;
|
||||
oldmask1 = isohash;
|
||||
isohashtbl = hash1;
|
||||
isohash = mask1;
|
||||
#ifdef ISODEVMAP
|
||||
oldhash2 = idvhashtbl;
|
||||
oldmask2 = idvhash;
|
||||
idvhashtbl = hash2;
|
||||
idvhash = mask2;
|
||||
for (i = 0; i <= oldmask2; i++) {
|
||||
while ((dp = LIST_FIRST(&oldhash2[i])) != NULL) {
|
||||
LIST_REMOVE(dp, d_hash);
|
||||
val = DNOHASH(dp->i_dev, dp->i_number);
|
||||
LIST_INSERT_HEAD(&hash2[val], dp, d_hash);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i <= oldmask1; i++) {
|
||||
while ((ip = LIST_FIRST(&oldhash1[i])) != NULL) {
|
||||
LIST_REMOVE(ip, i_hash);
|
||||
@ -146,11 +116,8 @@ cd9660_reinit()
|
||||
LIST_INSERT_HEAD(&hash1[val], ip, i_hash);
|
||||
}
|
||||
}
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
mutex_exit(&cd9660_ihash_lock);
|
||||
hashdone(oldhash1, M_ISOFSMNT);
|
||||
#ifdef ISODEVMAP
|
||||
hashdone(oldhash2, M_ISOFSMNT);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -160,87 +127,42 @@ void
|
||||
cd9660_done()
|
||||
{
|
||||
hashdone(isohashtbl, M_ISOFSMNT);
|
||||
#ifdef ISODEVMAP
|
||||
hashdone(idvhashtbl, M_ISOFSMNT);
|
||||
#endif
|
||||
pool_destroy(&cd9660_node_pool);
|
||||
mutex_destroy(&cd9660_ihash_lock);
|
||||
mutex_destroy(&cd9660_hashlock);
|
||||
malloc_type_detach(M_ISOFSMNT);
|
||||
}
|
||||
|
||||
#ifdef ISODEVMAP
|
||||
/*
|
||||
* Enter a new node into the device hash list
|
||||
*/
|
||||
struct iso_dnode *
|
||||
iso_dmap(device, inum, create)
|
||||
dev_t device;
|
||||
ino_t inum;
|
||||
int create;
|
||||
{
|
||||
struct iso_dnode *dp;
|
||||
struct idvhashhead *hp;
|
||||
|
||||
hp = &idvhashtbl[DNOHASH(device, inum)];
|
||||
LIST_FOREACH(dp, hp, d_hash) {
|
||||
if (inum == dp->i_number && device == dp->i_dev)
|
||||
return (dp);
|
||||
}
|
||||
|
||||
if (!create)
|
||||
return (NULL);
|
||||
|
||||
MALLOC(dp, struct iso_dnode *, sizeof(struct iso_dnode), M_CACHE,
|
||||
M_WAITOK);
|
||||
dp->i_dev = device;
|
||||
dp->i_number = inum;
|
||||
LIST_INSERT_HEAD(hp, dp, d_hash);
|
||||
return (dp);
|
||||
}
|
||||
|
||||
void
|
||||
iso_dunmap(device)
|
||||
dev_t device;
|
||||
{
|
||||
struct idvhashhead *dpp;
|
||||
struct iso_dnode *dp, *dq;
|
||||
|
||||
for (dpp = idvhashtbl; dpp <= idvhashtbl + idvhash; dpp++) {
|
||||
for (dp = LIST_FIRST(dpp); dp != NULL; dp = dq) {
|
||||
dq = LIST_NEXT(dp, d_hash);
|
||||
if (device == dp->i_dev) {
|
||||
LIST_REMOVE(dp, d_hash);
|
||||
FREE(dp, M_CACHE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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 *
|
||||
cd9660_ihashget(dev, inum)
|
||||
cd9660_ihashget(dev, inum, flags)
|
||||
dev_t dev;
|
||||
ino_t inum;
|
||||
int flags;
|
||||
{
|
||||
struct iso_node *ip;
|
||||
struct vnode *vp;
|
||||
|
||||
loop:
|
||||
simple_lock(&cd9660_ihash_slock);
|
||||
mutex_enter(&cd9660_ihash_lock);
|
||||
LIST_FOREACH(ip, &isohashtbl[INOHASH(dev, inum)], i_hash) {
|
||||
if (inum == ip->i_number && dev == ip->i_dev) {
|
||||
vp = ITOV(ip);
|
||||
simple_lock(&vp->v_interlock);
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
|
||||
goto loop;
|
||||
if (flags == 0) {
|
||||
mutex_exit(&cd9660_ihash_lock);
|
||||
} else {
|
||||
simple_lock(&vp->v_interlock);
|
||||
mutex_exit(&cd9660_ihash_lock);
|
||||
if (vget(vp, flags | LK_INTERLOCK))
|
||||
goto loop;
|
||||
}
|
||||
return (vp);
|
||||
}
|
||||
}
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
mutex_exit(&cd9660_ihash_lock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -255,10 +177,12 @@ cd9660_ihashins(ip)
|
||||
{
|
||||
struct ihashhead *ipp;
|
||||
|
||||
simple_lock(&cd9660_ihash_slock);
|
||||
KASSERT(mutex_owned(&cd9660_hashlock));
|
||||
|
||||
mutex_enter(&cd9660_ihash_lock);
|
||||
ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)];
|
||||
LIST_INSERT_HEAD(ipp, ip, i_hash);
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
mutex_exit(&cd9660_ihash_lock);
|
||||
|
||||
lockmgr(&ip->i_vnode->v_lock, LK_EXCLUSIVE, &ip->i_vnode->v_interlock);
|
||||
}
|
||||
@ -270,9 +194,9 @@ void
|
||||
cd9660_ihashrem(ip)
|
||||
struct iso_node *ip;
|
||||
{
|
||||
simple_lock(&cd9660_ihash_slock);
|
||||
mutex_enter(&cd9660_ihash_lock);
|
||||
LIST_REMOVE(ip, i_hash);
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
mutex_exit(&cd9660_ihash_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cd9660_node.h,v 1.12 2005/12/03 22:16:16 christos Exp $ */
|
||||
/* $NetBSD: cd9660_node.h,v 1.13 2007/12/08 14:41:11 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
@ -61,18 +61,6 @@ typedef struct {
|
||||
dev_t iso_rdev; /* Major/Minor number for special */
|
||||
} ISO_RRIP_INODE;
|
||||
|
||||
#ifdef ISODEVMAP
|
||||
/*
|
||||
* FOr device# (major,minor) translation table
|
||||
*/
|
||||
struct iso_dnode {
|
||||
LIST_ENTRY(iso_dnode) d_hash;
|
||||
dev_t i_dev; /* device where dnode resides */
|
||||
ino_t i_number; /* the identity of the inode */
|
||||
dev_t d_dev; /* device # for translation */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct iso_node {
|
||||
struct genfs_node i_gnode;
|
||||
LIST_ENTRY(iso_node) i_hash;
|
||||
@ -140,16 +128,15 @@ void cd9660_defattr(struct iso_directory_record *,
|
||||
struct iso_node *, struct buf *);
|
||||
void cd9660_deftstamp(struct iso_directory_record *,
|
||||
struct iso_node *, struct buf *);
|
||||
struct vnode *cd9660_ihashget(dev_t, ino_t);
|
||||
struct vnode *cd9660_ihashget(dev_t, ino_t, int);
|
||||
void cd9660_ihashins(struct iso_node *);
|
||||
void cd9660_ihashrem(struct iso_node *);
|
||||
int cd9660_tstamp_conv7(u_char *, struct timespec *);
|
||||
int cd9660_tstamp_conv17(u_char *, struct timespec *);
|
||||
int cd9660_vget_internal(struct mount *, ino_t, struct vnode **, int,
|
||||
struct iso_directory_record *);
|
||||
#ifdef ISODEVMAP
|
||||
struct iso_dnode *iso_dmap(dev_t, ino_t, int);
|
||||
void iso_dunmap(dev_t);
|
||||
#endif
|
||||
|
||||
extern kmutex_t cd9660_hashlock;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _ISOFS_CD9660_CD9660_NODE_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cd9660_vfsops.c,v 1.50 2007/11/26 19:01:42 pooka Exp $ */
|
||||
/* $NetBSD: cd9660_vfsops.c,v 1.51 2007/12/08 14:41:12 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd9660_vfsops.c,v 1.50 2007/11/26 19:01:42 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd9660_vfsops.c,v 1.51 2007/12/08 14:41:12 ad Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
@ -539,11 +539,6 @@ cd9660_unmount(mp, mntflags)
|
||||
|
||||
isomp = VFSTOISOFS(mp);
|
||||
|
||||
#ifdef ISODEVMAP
|
||||
if (isomp->iso_ftype == ISO_FTYPE_RRIP)
|
||||
iso_dunmap(isomp->im_dev);
|
||||
#endif
|
||||
|
||||
if (isomp->im_devvp->v_type != VBAD)
|
||||
isomp->im_devvp->v_specmountpoint = NULL;
|
||||
|
||||
@ -700,9 +695,6 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
{
|
||||
struct iso_mnt *imp;
|
||||
struct iso_node *ip;
|
||||
#ifdef ISODEVMAP
|
||||
struct iso_dnode *dp;
|
||||
#endif
|
||||
struct buf *bp;
|
||||
struct vnode *vp, *nvp;
|
||||
dev_t dev;
|
||||
@ -710,7 +702,9 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
|
||||
imp = VFSTOISOFS(mp);
|
||||
dev = imp->im_dev;
|
||||
if ((*vpp = cd9660_ihashget(dev, ino)) != NULLVP)
|
||||
|
||||
retry:
|
||||
if ((*vpp = cd9660_ihashget(dev, ino, LK_EXCLUSIVE)) != NULLVP)
|
||||
return (0);
|
||||
|
||||
/* Allocate a new vnode/iso_node. */
|
||||
@ -719,11 +713,27 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
return (error);
|
||||
}
|
||||
ip = pool_get(&cd9660_node_pool, PR_WAITOK);
|
||||
|
||||
/*
|
||||
* If someone beat us to it, put back the freshly allocated
|
||||
* vnode/inode pair and retry.
|
||||
*/
|
||||
mutex_enter(&cd9660_hashlock);
|
||||
if (cd9660_ihashget(dev, ino, 0) != NULL) {
|
||||
mutex_exit(&cd9660_hashlock);
|
||||
ungetnewvnode(vp);
|
||||
pool_put(&cd9660_node_pool, ip);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
memset(ip, 0, sizeof(struct iso_node));
|
||||
vp->v_data = ip;
|
||||
ip->i_vnode = vp;
|
||||
ip->i_dev = dev;
|
||||
ip->i_number = ino;
|
||||
ip->i_mnt = imp;
|
||||
ip->i_devvp = imp->im_devvp;
|
||||
genfs_node_init(vp, &cd9660_genfsops);
|
||||
|
||||
/*
|
||||
* Put it onto its hash chain and lock it so that other requests for
|
||||
@ -732,6 +742,7 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
* disk portion of this inode to be read.
|
||||
*/
|
||||
cd9660_ihashins(ip);
|
||||
mutex_exit(&cd9660_hashlock);
|
||||
|
||||
if (isodir == 0) {
|
||||
int lbn, off;
|
||||
@ -787,8 +798,6 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
} else
|
||||
bp = 0;
|
||||
|
||||
ip->i_mnt = imp;
|
||||
ip->i_devvp = imp->im_devvp;
|
||||
VREF(ip->i_devvp);
|
||||
|
||||
if (relocated) {
|
||||
@ -851,10 +860,6 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
/*
|
||||
* if device, look at device number table for translation
|
||||
*/
|
||||
#ifdef ISODEVMAP
|
||||
if ((dp = iso_dmap(dev, ino, 0)) != NULL)
|
||||
ip->inode.iso_rdev = dp->d_dev;
|
||||
#endif
|
||||
vp->v_op = cd9660_specop_p;
|
||||
if ((nvp = checkalias(vp, ip->inode.iso_rdev, mp)) != NULL) {
|
||||
/*
|
||||
@ -897,7 +902,6 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
* XXX need generation number?
|
||||
*/
|
||||
|
||||
genfs_node_init(vp, &cd9660_genfsops);
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cd9660_vnops.c,v 1.30 2007/11/26 19:01:43 pooka Exp $ */
|
||||
/* $NetBSD: cd9660_vnops.c,v 1.31 2007/12/08 14:41:12 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.30 2007/11/26 19:01:43 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.31 2007/12/08 14:41:12 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -84,63 +84,6 @@ struct isoreaddir {
|
||||
int iso_uiodir(struct isoreaddir *, struct dirent *, off_t);
|
||||
int iso_shipdir(struct isoreaddir *);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Mknod vnode call
|
||||
* Actually remap the device number
|
||||
*/
|
||||
int
|
||||
cd9660_mknod(ndp, vap, cred, p)
|
||||
struct nameidata *ndp;
|
||||
kauth_cred_t cred;
|
||||
struct vattr *vap;
|
||||
struct proc *p;
|
||||
{
|
||||
#ifndef ISODEVMAP
|
||||
PNBUF_PUT(ndp->ni_pnbuf);
|
||||
vput(ndp->ni_dvp);
|
||||
vput(ndp->ni_vp);
|
||||
return (EINVAL);
|
||||
#else
|
||||
struct vnode *vp;
|
||||
struct iso_node *ip;
|
||||
struct iso_dnode *dp;
|
||||
|
||||
vp = ndp->ni_vp;
|
||||
ip = VTOI(vp);
|
||||
|
||||
if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP
|
||||
|| vap->va_type != vp->v_type
|
||||
|| (vap->va_type != VCHR && vap->va_type != VBLK)) {
|
||||
PNBUF_PUT(ndp->ni_pnbuf);
|
||||
vput(ndp->ni_dvp);
|
||||
vput(ndp->ni_vp);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
dp = iso_dmap(ip->i_dev, ip->i_number, 1);
|
||||
if (ip->inode.iso_rdev == vap->va_rdev ||
|
||||
vap->va_rdev == (dev_t)VNOVAL) {
|
||||
/* same as the unmapped one, delete the mapping */
|
||||
LIST_REMOVE(dp, d_hash);
|
||||
FREE(dp, M_CACHE);
|
||||
} else
|
||||
/* enter new mapping */
|
||||
dp->d_dev = vap->va_rdev;
|
||||
|
||||
/*
|
||||
* Remove inode so that it will be reloaded by iget and
|
||||
* checked to see if it is an alias of an existing entry
|
||||
* in the inode cache.
|
||||
*/
|
||||
vput(vp);
|
||||
vp->v_type = VNON;
|
||||
vgone(vp);
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
|
||||
* The mode is shifted to select the owner/group/other fields. The
|
||||
|
Loading…
Reference in New Issue
Block a user