diff options
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/fs/hpfs/hpfs.h | 13 | ||||
-rw-r--r-- | sys/fs/hpfs/hpfs_hash.c | 10 | ||||
-rw-r--r-- | sys/fs/hpfs/hpfs_vfsops.c | 73 | ||||
-rw-r--r-- | sys/fs/hpfs/hpfs_vnops.c | 3 |
5 files changed, 33 insertions, 67 deletions
diff --git a/sys/conf/files b/sys/conf/files index c231006..b85f539 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -892,7 +892,6 @@ fs/fdescfs/fdesc_vfsops.c optional fdescfs fs/fdescfs/fdesc_vnops.c optional fdescfs fs/fifofs/fifo_vnops.c standard fs/hpfs/hpfs_alsubr.c optional hpfs -fs/hpfs/hpfs_hash.c optional hpfs fs/hpfs/hpfs_lookup.c optional hpfs fs/hpfs/hpfs_subr.c optional hpfs fs/hpfs/hpfs_vfsops.c optional hpfs diff --git a/sys/fs/hpfs/hpfs.h b/sys/fs/hpfs/hpfs.h index c818d1b..aaea495 100644 --- a/sys/fs/hpfs/hpfs.h +++ b/sys/fs/hpfs/hpfs.h @@ -329,7 +329,6 @@ struct hpfsmount { u_int8_t * hpm_bitmap; }; -#define H_HASHED 0x0001 /* Present in hash */ #define H_PARVALID 0x0002 /* parent info is valid */ #define H_CHANGE 0x0004 /* node date was changed */ #define H_PARCHANGE 0x0008 /* parent node date was changed */ @@ -337,8 +336,6 @@ struct hpfsmount { struct hpfsnode { struct mtx h_interlock; - LIST_ENTRY(hpfsnode) h_hash; - struct hpfsmount *h_hpmp; struct fnode h_fn; struct vnode * h_vp; @@ -388,13 +385,3 @@ MALLOC_DECLARE(M_HPFSNO); #define FID(f) (*((lsn_t *)(f)->fid_data)) extern struct vop_vector hpfs_vnodeops; - -/* Hash routines, too small to be separate header */ -void hpfs_hphashinit(void); -void hpfs_hphashdestroy(void); -struct hpfsnode *hpfs_hphashlookup(struct cdev *, lsn_t); -struct hpfsnode *hpfs_hphashget(struct cdev *, lsn_t); -int hpfs_hphashvget(struct cdev *, lsn_t, int, struct vnode **, struct thread *); -void hpfs_hphashins(register struct hpfsnode *); -void hpfs_hphashrem(register struct hpfsnode *); -extern struct lock hpfs_hphash_lock; diff --git a/sys/fs/hpfs/hpfs_hash.c b/sys/fs/hpfs/hpfs_hash.c index aa410a8..d5a1e48 100644 --- a/sys/fs/hpfs/hpfs_hash.c +++ b/sys/fs/hpfs/hpfs_hash.c @@ -49,7 +49,7 @@ static MALLOC_DEFINE(M_HPFSHASH, "HPFS hash", "HPFS node hash tables"); */ static LIST_HEAD(hphashhead, hpfsnode) *hpfs_hphashtbl; static u_long hpfs_hphash; /* size of hash table - 1 */ -#define HPNOHASH(dev, lsn) (&hpfs_hphashtbl[(minor(dev) + (lsn)) & hpfs_hphash]) +#define HPNOHASH(lsn) (&hpfs_hphashtbl[(lsn) & hpfs_hphash]) static struct mtx hpfs_hphash_mtx; struct lock hpfs_hphash_lock; @@ -88,7 +88,7 @@ hpfs_hphashlookup(dev, ino) struct hpfsnode *hp; mtx_lock(&hpfs_hphash_mtx); - LIST_FOREACH(hp, HPNOHASH(dev, ino), h_hash) + LIST_FOREACH(hp, HPNOHASH(ino), h_hash) if (ino == hp->h_no && dev == hp->h_dev) break; mtx_unlock(&hpfs_hphash_mtx); @@ -106,7 +106,7 @@ hpfs_hphashget(dev, ino) loop: mtx_lock(&hpfs_hphash_mtx); - LIST_FOREACH(hp, HPNOHASH(dev, ino), h_hash) { + LIST_FOREACH(hp, HPNOHASH(ino), h_hash) { if (ino == hp->h_no && dev == hp->h_dev) { lockmgr(&hp->h_intlock, LK_EXCLUSIVE | LK_INTERLOCK, &hpfs_hphash_slock, NULL); @@ -133,7 +133,7 @@ hpfs_hphashvget(dev, ino, flags, vpp, td) *vpp = NULLVP; loop: mtx_lock(&hpfs_hphash_mtx); - LIST_FOREACH(hp, HPNOHASH(dev, ino), h_hash) { + LIST_FOREACH(hp, HPNOHASH(ino), h_hash) { if (ino == hp->h_no && dev == hp->h_dev) { vp = HPTOV(hp); mtx_lock(&vp->v_interlock); @@ -161,7 +161,7 @@ hpfs_hphashins(hp) struct hphashhead *hpp; mtx_lock(&hpfs_hphash_mtx); - hpp = HPNOHASH(hp->h_dev, hp->h_no); + hpp = HPNOHASH(hp->h_no); hp->h_flag |= H_HASHED; LIST_INSERT_HEAD(hpp, hp, h_hash); mtx_unlock(&hpfs_hphash_mtx); diff --git a/sys/fs/hpfs/hpfs_vfsops.c b/sys/fs/hpfs/hpfs_vfsops.c index af5291d..ae96087 100644 --- a/sys/fs/hpfs/hpfs_vfsops.c +++ b/sys/fs/hpfs/hpfs_vfsops.c @@ -61,8 +61,6 @@ struct sockaddr; static int hpfs_mountfs(register struct vnode *, struct mount *, struct thread *); -static vfs_init_t hpfs_init; -static vfs_uninit_t hpfs_uninit; static vfs_fhtovp_t hpfs_fhtovp; static vfs_vget_t hpfs_vget; static vfs_cmount_t hpfs_cmount; @@ -73,24 +71,6 @@ static vfs_unmount_t hpfs_unmount; static vfs_vptofh_t hpfs_vptofh; static int -hpfs_init ( - struct vfsconf *vcp ) -{ - dprintf(("hpfs_init():\n")); - - hpfs_hphashinit(); - return 0; -} - -static int -hpfs_uninit (vfsp) - struct vfsconf *vfsp; -{ - hpfs_hphashdestroy(); - return 0;; -} - -static int hpfs_cmount ( struct mntarg *ma, void *data, @@ -484,17 +464,16 @@ hpfs_vget( dprintf(("hpfs_vget(0x%x): ",ino)); + error = vfs_hash_get(mp, ino, flags, curthread, vpp); + if (error) + return (error); + if (*vpp != NULL) + return (0); + *vpp = NULL; hp = NULL; vp = NULL; - if ((error = hpfs_hphashvget(hpmp->hpm_dev, ino, flags, vpp, td)) != 0) - return (error); - if (*vpp != NULL) { - dprintf(("hashed\n")); - return (0); - } - /* * We have to lock node creation for a while, * but then we have to call getnewvnode(), @@ -536,30 +515,32 @@ hpfs_vget( hp->h_gid = hpmp->hpm_uid; hp->h_mode = hpmp->hpm_mode; hp->h_devvp = hpmp->hpm_devvp; - VREF(hp->h_devvp); - error = vn_lock(vp, LK_EXCLUSIVE, td); - if (error) { + /* + * 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, td); + + /* + * 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); } - do { - if ((error = - hpfs_hphashvget(hpmp->hpm_dev, ino, flags, vpp, td))) { - vput(vp); - return (error); - } - if (*vpp != NULL) { - dprintf(("hashed2\n")); - vput(vp); - return (0); - } - } while(lockmgr(&hpfs_hphash_lock,LK_EXCLUSIVE|LK_SLEEPFAIL,NULL,NULL)); - - hpfs_hphashins(hp); + /* We lost the race, then throw away our vnode and return existing */ + if (*vpp != NULL) { + vput(vp); + return (0); + } - lockmgr(&hpfs_hphash_lock, LK_RELEASE, NULL, NULL); + VREF(hp->h_devvp); error = bread(hpmp->hpm_devvp, ino, FNODESIZE, NOCRED, &bp); if (error) { @@ -586,12 +567,10 @@ hpfs_vget( static struct vfsops hpfs_vfsops = { .vfs_fhtovp = hpfs_fhtovp, - .vfs_init = hpfs_init, .vfs_cmount = hpfs_cmount, .vfs_mount = hpfs_mount, .vfs_root = hpfs_root, .vfs_statfs = hpfs_statfs, - .vfs_uninit = hpfs_uninit, .vfs_unmount = hpfs_unmount, .vfs_vget = hpfs_vget, .vfs_vptofh = hpfs_vptofh, diff --git a/sys/fs/hpfs/hpfs_vnops.c b/sys/fs/hpfs/hpfs_vnops.c index ce6b965..6b8eef8 100644 --- a/sys/fs/hpfs/hpfs_vnops.c +++ b/sys/fs/hpfs/hpfs_vnops.c @@ -30,6 +30,7 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/proc.h> +#include <sys/conf.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> @@ -599,7 +600,7 @@ hpfs_reclaim(ap) dprintf(("hpfs_reclaim(0x%x0): \n", hp->h_no)); - hpfs_hphashrem(hp); + vfs_hash_remove(vp); /* Purge old data structures associated with the inode. */ if (hp->h_devvp) { |