Change adosfs from hashlist to vcache.
- point ap->block to real file header block for hard links.
This commit is contained in:
parent
e0a0745c3d
commit
ea4bd7d40f
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: adosfs.h,v 1.12 2012/10/03 07:20:50 mlelstv Exp $ */
|
/* $NetBSD: adosfs.h,v 1.13 2014/08/05 08:50:54 hannken Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Christian E. Hopps
|
* Copyright (c) 1994 Christian E. Hopps
|
||||||
|
@ -73,7 +73,6 @@ enum anode_type { AROOT, ADIR, AFILE, ALDIR, ALFILE, ASLINK };
|
||||||
*/
|
*/
|
||||||
struct anode {
|
struct anode {
|
||||||
struct genfs_node gnode;
|
struct genfs_node gnode;
|
||||||
LIST_ENTRY(anode) link;
|
|
||||||
enum anode_type type;
|
enum anode_type type;
|
||||||
char name[ADMAXNAMELEN+1]; /* (r/d/f) name for object */
|
char name[ADMAXNAMELEN+1]; /* (r/d/f) name for object */
|
||||||
struct datestamp mtimev; /* (r) volume modified */
|
struct datestamp mtimev; /* (r) volume modified */
|
||||||
|
@ -112,7 +111,6 @@ struct anode {
|
||||||
#define ANODEHASHSZ (512)
|
#define ANODEHASHSZ (512)
|
||||||
|
|
||||||
struct adosfsmount {
|
struct adosfsmount {
|
||||||
LIST_HEAD(anodechain, anode) anodetab[ANODEHASHSZ];
|
|
||||||
struct mount *mp; /* owner mount */
|
struct mount *mp; /* owner mount */
|
||||||
u_int32_t dostype; /* type of volume */
|
u_int32_t dostype; /* type of volume */
|
||||||
u_long rootb; /* root block number */
|
u_long rootb; /* root block number */
|
||||||
|
@ -169,10 +167,6 @@ int adoshash(const u_char *, int, int, int);
|
||||||
int adunixprot(int);
|
int adunixprot(int);
|
||||||
int adosfs_getblktype(struct adosfsmount *, struct buf *);
|
int adosfs_getblktype(struct adosfsmount *, struct buf *);
|
||||||
|
|
||||||
struct vnode *adosfs_ahashget(struct mount *, ino_t);
|
|
||||||
void adosfs_ainshash(struct adosfsmount *, struct anode *);
|
|
||||||
void adosfs_aremhash(struct anode *);
|
|
||||||
|
|
||||||
int adosfs_lookup(void *);
|
int adosfs_lookup(void *);
|
||||||
|
|
||||||
extern int (**adosfs_vnodeop_p)(void *);
|
extern int (**adosfs_vnodeop_p)(void *);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $ */
|
/* $NetBSD: adutil.c,v 1.17 2014/08/05 08:50:54 hannken Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Christian E. Hopps
|
* Copyright (c) 1994 Christian E. Hopps
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.17 2014/08/05 08:50:54 hannken Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
|
@ -47,62 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $");
|
||||||
/*
|
/*
|
||||||
* look for anode in the mount's hash table, return locked.
|
* look for anode in the mount's hash table, return locked.
|
||||||
*/
|
*/
|
||||||
#define AHASH(an) ((an) & (ANODEHASHSZ - 1))
|
|
||||||
static int CapitalChar(int, int);
|
static int CapitalChar(int, int);
|
||||||
|
|
||||||
extern kmutex_t adosfs_hashlock;
|
|
||||||
|
|
||||||
struct vnode *
|
|
||||||
adosfs_ahashget(struct mount *mp, ino_t an)
|
|
||||||
{
|
|
||||||
struct anodechain *hp;
|
|
||||||
struct anode *ap;
|
|
||||||
struct vnode *vp;
|
|
||||||
|
|
||||||
hp = &VFSTOADOSFS(mp)->anodetab[AHASH(an)];
|
|
||||||
|
|
||||||
start_over:
|
|
||||||
mutex_enter(&adosfs_hashlock);
|
|
||||||
for (ap = hp->lh_first; ap != NULL; ap = ap->link.le_next) {
|
|
||||||
if (ap->block == an) {
|
|
||||||
vp = ATOV(ap);
|
|
||||||
mutex_enter(vp->v_interlock);
|
|
||||||
mutex_exit(&adosfs_hashlock);
|
|
||||||
if (vget(vp, LK_EXCLUSIVE))
|
|
||||||
goto start_over;
|
|
||||||
return (ATOV(ap));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex_exit(&adosfs_hashlock);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* insert in hash table and lock
|
|
||||||
*
|
|
||||||
* ap->vp must have been initialized before this call.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
adosfs_ainshash(struct adosfsmount *amp, struct anode *ap)
|
|
||||||
{
|
|
||||||
int error __diagused;
|
|
||||||
|
|
||||||
error = VOP_LOCK(ATOV(ap), LK_EXCLUSIVE);
|
|
||||||
KASSERT(error == 0);
|
|
||||||
|
|
||||||
mutex_enter(&adosfs_hashlock);
|
|
||||||
LIST_INSERT_HEAD(&->anodetab[AHASH(ap->block)], ap, link);
|
|
||||||
mutex_exit(&adosfs_hashlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
adosfs_aremhash(struct anode *ap)
|
|
||||||
{
|
|
||||||
mutex_enter(&adosfs_hashlock);
|
|
||||||
LIST_REMOVE(ap, link);
|
|
||||||
mutex_exit(&adosfs_hashlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
adosfs_getblktype(struct adosfsmount *amp, struct buf *bp)
|
adosfs_getblktype(struct adosfsmount *amp, struct buf *bp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: advfsops.c,v 1.70 2014/04/16 18:55:18 maxv Exp $ */
|
/* $NetBSD: advfsops.c,v 1.71 2014/08/05 08:50:54 hannken Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Christian E. Hopps
|
* Copyright (c) 1994 Christian E. Hopps
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: advfsops.c,v 1.70 2014/04/16 18:55:18 maxv Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: advfsops.c,v 1.71 2014/08/05 08:50:54 hannken Exp $");
|
||||||
|
|
||||||
#if defined(_KERNEL_OPT)
|
#if defined(_KERNEL_OPT)
|
||||||
#include "opt_compat_netbsd.h"
|
#include "opt_compat_netbsd.h"
|
||||||
|
@ -70,8 +70,6 @@ static struct sysctllog *adosfs_sysctl_log;
|
||||||
int adosfs_mountfs(struct vnode *, struct mount *, struct lwp *);
|
int adosfs_mountfs(struct vnode *, struct mount *, struct lwp *);
|
||||||
int adosfs_loadbitmap(struct adosfsmount *);
|
int adosfs_loadbitmap(struct adosfsmount *);
|
||||||
|
|
||||||
kmutex_t adosfs_hashlock;
|
|
||||||
|
|
||||||
struct pool adosfs_node_pool;
|
struct pool adosfs_node_pool;
|
||||||
|
|
||||||
MALLOC_JUSTDEFINE(M_ANODE, "adosfs anode","adosfs anode structures and tables");
|
MALLOC_JUSTDEFINE(M_ANODE, "adosfs anode","adosfs anode structures and tables");
|
||||||
|
@ -169,7 +167,7 @@ adosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l)
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
struct vnode *rvp;
|
struct vnode *rvp;
|
||||||
size_t bitmap_sz = 0;
|
size_t bitmap_sz = 0;
|
||||||
int error, i;
|
int error;
|
||||||
uint64_t numsecs;
|
uint64_t numsecs;
|
||||||
unsigned secsize;
|
unsigned secsize;
|
||||||
unsigned long secsperblk, blksperdisk, resvblks;
|
unsigned long secsperblk, blksperdisk, resvblks;
|
||||||
|
@ -263,12 +261,6 @@ adosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l)
|
||||||
mp->mnt_dev_bshift = DEV_BSHIFT;
|
mp->mnt_dev_bshift = DEV_BSHIFT;
|
||||||
mp->mnt_flag |= MNT_LOCAL;
|
mp->mnt_flag |= MNT_LOCAL;
|
||||||
|
|
||||||
/*
|
|
||||||
* init anode table.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < ANODEHASHSZ; i++)
|
|
||||||
LIST_INIT(&->anodetab[i]);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get the root anode, if not a valid fs this will fail.
|
* get the root anode, if not a valid fs this will fail.
|
||||||
*/
|
*/
|
||||||
|
@ -371,50 +363,55 @@ adosfs_statvfs(struct mount *mp, struct statvfs *sbp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lookup an anode, check mount's hash table if not found, create
|
* lookup an anode, if not found, create
|
||||||
* return locked and referenced al la vget(vp, 1);
|
* return locked and referenced al la vget(vp, LK_EXCLUSIVE);
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
adosfs_vget(struct mount *mp, ino_t an, struct vnode **vpp)
|
adosfs_vget(struct mount *mp, ino_t an, struct vnode **vpp)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = vcache_get(mp, &an, sizeof(an), vpp);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
error = vn_lock(*vpp, LK_EXCLUSIVE);
|
||||||
|
if (error) {
|
||||||
|
vrele(*vpp);
|
||||||
|
*vpp = NULL;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize this vnode / anode pair.
|
||||||
|
* Caller assures no other thread will try to load this inode.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
adosfs_loadvnode(struct mount *mp, struct vnode *vp,
|
||||||
|
const void *key, size_t key_len, const void **new_key)
|
||||||
{
|
{
|
||||||
struct adosfsmount *amp;
|
struct adosfsmount *amp;
|
||||||
struct vnode *vp;
|
|
||||||
struct anode *ap;
|
struct anode *ap;
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
ino_t an;
|
||||||
char *nam, *tmp;
|
char *nam, *tmp;
|
||||||
int namlen, error;
|
int namlen, error;
|
||||||
|
|
||||||
error = 0;
|
KASSERT(key_len == sizeof(an));
|
||||||
|
memcpy(&an, key, key_len);
|
||||||
amp = VFSTOADOSFS(mp);
|
amp = VFSTOADOSFS(mp);
|
||||||
bp = NULL;
|
|
||||||
|
|
||||||
/*
|
if ((error = bread(amp->devvp, an * amp->bsize / DEV_BSIZE,
|
||||||
* check hash table. we are done if found
|
amp->bsize, NOCRED, 0, &bp)) != 0)
|
||||||
*/
|
return error;
|
||||||
if ((*vpp = adosfs_ahashget(mp, an)) != NULL)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
error = getnewvnode(VT_ADOSFS, mp, adosfs_vnodeop_p, NULL, &vp);
|
ap = pool_get(&adosfs_node_pool, PR_WAITOK);
|
||||||
if (error)
|
|
||||||
return (error);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* setup, insert in hash, and lock before io.
|
|
||||||
*/
|
|
||||||
vp->v_data = ap = pool_get(&adosfs_node_pool, PR_WAITOK);
|
|
||||||
memset(ap, 0, sizeof(struct anode));
|
memset(ap, 0, sizeof(struct anode));
|
||||||
ap->vp = vp;
|
ap->vp = vp;
|
||||||
ap->amp = amp;
|
ap->amp = amp;
|
||||||
ap->block = an;
|
ap->block = an;
|
||||||
ap->nwords = amp->nwords;
|
ap->nwords = amp->nwords;
|
||||||
genfs_node_init(vp, &adosfs_genfsops);
|
|
||||||
adosfs_ainshash(amp, ap);
|
|
||||||
|
|
||||||
if ((error = bread(amp->devvp, an * amp->bsize / DEV_BSIZE,
|
|
||||||
amp->bsize, NOCRED, 0, &bp)) != 0) {
|
|
||||||
vput(vp);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get type and fill rest in based on that.
|
* get type and fill rest in based on that.
|
||||||
|
@ -468,9 +465,8 @@ adosfs_vget(struct mount *mp, ino_t an, struct vnode **vpp)
|
||||||
ap->fsize = namlen;
|
ap->fsize = namlen;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
brelse(bp, 0);
|
error = EINVAL;
|
||||||
vput(vp);
|
goto bad;
|
||||||
return (EINVAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -488,9 +484,8 @@ adosfs_vget(struct mount *mp, ino_t an, struct vnode **vpp)
|
||||||
printf("adosfs: aget: name length too long blk %llu\n",
|
printf("adosfs: aget: name length too long blk %llu\n",
|
||||||
(unsigned long long)an);
|
(unsigned long long)an);
|
||||||
#endif
|
#endif
|
||||||
brelse(bp, 0);
|
error = EINVAL;
|
||||||
vput(vp);
|
goto bad;
|
||||||
return (EINVAL);
|
|
||||||
}
|
}
|
||||||
memcpy(ap->name, nam, namlen);
|
memcpy(ap->name, nam, namlen);
|
||||||
ap->name[namlen] = 0;
|
ap->name[namlen] = 0;
|
||||||
|
@ -531,15 +526,9 @@ adosfs_vget(struct mount *mp, ino_t an, struct vnode **vpp)
|
||||||
bp = NULL;
|
bp = NULL;
|
||||||
error = bread(amp->devvp, ap->linkto * amp->bsize / DEV_BSIZE,
|
error = bread(amp->devvp, ap->linkto * amp->bsize / DEV_BSIZE,
|
||||||
amp->bsize, NOCRED, 0, &bp);
|
amp->bsize, NOCRED, 0, &bp);
|
||||||
if (error) {
|
if (error)
|
||||||
vput(vp);
|
goto bad;
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
ap->fsize = adoswordn(bp, ap->nwords - 47);
|
ap->fsize = adoswordn(bp, ap->nwords - 47);
|
||||||
/*
|
|
||||||
* Should ap->block be set to the real file header block?
|
|
||||||
*/
|
|
||||||
ap->block = ap->linkto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ap->type == AROOT) {
|
if (ap->type == AROOT) {
|
||||||
|
@ -586,10 +575,20 @@ adosfs_vget(struct mount *mp, ino_t an, struct vnode **vpp)
|
||||||
ap->mtime.mins = adoswordn(bp, ap->nwords - 22);
|
ap->mtime.mins = adoswordn(bp, ap->nwords - 22);
|
||||||
ap->mtime.ticks = adoswordn(bp, ap->nwords - 21);
|
ap->mtime.ticks = adoswordn(bp, ap->nwords - 21);
|
||||||
|
|
||||||
*vpp = vp;
|
|
||||||
brelse(bp, 0);
|
brelse(bp, 0);
|
||||||
|
vp->v_tag = VT_ADOSFS;
|
||||||
|
vp->v_op = adosfs_vnodeop_p;
|
||||||
|
vp->v_data = ap;
|
||||||
|
genfs_node_init(vp, &adosfs_genfsops);
|
||||||
uvm_vnp_setsize(vp, ap->fsize);
|
uvm_vnp_setsize(vp, ap->fsize);
|
||||||
return (0);
|
*new_key = &ap->block;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
if (bp)
|
||||||
|
brelse(bp, 0);
|
||||||
|
pool_put(&adosfs_node_pool, ap);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -761,7 +760,6 @@ adosfs_init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
malloc_type_attach(M_ANODE);
|
malloc_type_attach(M_ANODE);
|
||||||
mutex_init(&adosfs_hashlock, MUTEX_DEFAULT, IPL_NONE);
|
|
||||||
pool_init(&adosfs_node_pool, sizeof(struct anode), 0, 0, 0, "adosndpl",
|
pool_init(&adosfs_node_pool, sizeof(struct anode), 0, 0, 0, "adosndpl",
|
||||||
&pool_allocator_nointr, IPL_NONE);
|
&pool_allocator_nointr, IPL_NONE);
|
||||||
}
|
}
|
||||||
|
@ -771,7 +769,6 @@ adosfs_done(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
pool_destroy(&adosfs_node_pool);
|
pool_destroy(&adosfs_node_pool);
|
||||||
mutex_destroy(&adosfs_hashlock);
|
|
||||||
malloc_type_detach(M_ANODE);
|
malloc_type_detach(M_ANODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,6 +794,7 @@ struct vfsops adosfs_vfsops = {
|
||||||
.vfs_statvfs = adosfs_statvfs,
|
.vfs_statvfs = adosfs_statvfs,
|
||||||
.vfs_sync = adosfs_sync,
|
.vfs_sync = adosfs_sync,
|
||||||
.vfs_vget = adosfs_vget,
|
.vfs_vget = adosfs_vget,
|
||||||
|
.vfs_loadvnode = adosfs_loadvnode,
|
||||||
.vfs_fhtovp = adosfs_fhtovp,
|
.vfs_fhtovp = adosfs_fhtovp,
|
||||||
.vfs_vptofh = adosfs_vptofh,
|
.vfs_vptofh = adosfs_vptofh,
|
||||||
.vfs_init = adosfs_init,
|
.vfs_init = adosfs_init,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: advnops.c,v 1.44 2014/07/25 08:20:51 dholland Exp $ */
|
/* $NetBSD: advnops.c,v 1.45 2014/08/05 08:50:54 hannken Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Christian E. Hopps
|
* Copyright (c) 1994 Christian E. Hopps
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.44 2014/07/25 08:20:51 dholland Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.45 2014/08/05 08:50:54 hannken Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -880,7 +880,7 @@ adosfs_reclaim(void *v)
|
||||||
#endif
|
#endif
|
||||||
vp = sp->a_vp;
|
vp = sp->a_vp;
|
||||||
ap = VTOA(vp);
|
ap = VTOA(vp);
|
||||||
LIST_REMOVE(ap, link);
|
vcache_remove(vp->v_mount, &ap->block, sizeof(ap->block));
|
||||||
if (vp->v_type == VDIR && ap->tab)
|
if (vp->v_type == VDIR && ap->tab)
|
||||||
free(ap->tab, M_ANODE);
|
free(ap->tab, M_ANODE);
|
||||||
else if (vp->v_type == VLNK && ap->slinkto)
|
else if (vp->v_type == VLNK && ap->slinkto)
|
||||||
|
|
Loading…
Reference in New Issue