Updated msdosfs to use Lite2 vfs configuration and Lite2 locking. It
should now work as (un)well as before the Lite2 merge.
This commit is contained in:
parent
ebbdc73076
commit
af3f60d5a8
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: denode.h,v 1.11 1997/02/22 09:40:44 peter Exp $ */
|
||||
/* $NetBSD: denode.h,v 1.8 1994/08/21 18:43:49 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -148,8 +148,7 @@ struct denode {
|
||||
long de_refcnt; /* reference count */
|
||||
struct msdosfsmount *de_pmp; /* addr of our mount struct */
|
||||
struct lockf *de_lockf; /* byte level lock list */
|
||||
pid_t de_lockholder; /* current lock holder */
|
||||
pid_t de_lockwaiter; /* lock wanter */
|
||||
struct lock de_lock; /* denode lock */
|
||||
/* the next two fields must be contiguous in memory... */
|
||||
u_char de_Name[8]; /* name, from directory entry */
|
||||
u_char de_Extension[3]; /* extension, from directory entry */
|
||||
@ -165,8 +164,6 @@ struct denode {
|
||||
/*
|
||||
* Values for the de_flag field of the denode.
|
||||
*/
|
||||
#define DE_LOCKED 0x0001 /* directory entry is locked */
|
||||
#define DE_WANTED 0x0002 /* someone wants this de */
|
||||
#define DE_UPDATE 0x0004 /* modification time update request */
|
||||
#define DE_MODIFIED 0x0080 /* denode has been modified, but DE_UPDATE
|
||||
* isn't set */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: msdosfs_denode.c,v 1.22 1997/02/22 09:40:46 peter Exp $ */
|
||||
/* $NetBSD: msdosfs_denode.c,v 1.9 1994/08/21 18:44:00 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -70,7 +70,8 @@
|
||||
|
||||
struct denode **dehashtbl;
|
||||
u_long dehash; /* size of hash table - 1 */
|
||||
#define DEHASH(dev, deno) (((dev) + (deno)) & dehash)
|
||||
#define DEHASH(dev, deno) (dehashtbl[((dev) + (deno)) & dehash])
|
||||
static struct simplelock dehash_slock;
|
||||
|
||||
union _qcvt {
|
||||
quad_t qcvt;
|
||||
@ -99,6 +100,7 @@ int msdosfs_init(vfsp)
|
||||
struct vfsconf *vfsp;
|
||||
{
|
||||
dehashtbl = hashinit(desiredvnodes/2, M_MSDOSFSMNT, &dehash);
|
||||
simple_lock_init(&dehash_slock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -108,28 +110,27 @@ msdosfs_hashget(dev, dirclust, diroff)
|
||||
u_long dirclust;
|
||||
u_long diroff;
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct denode *dep;
|
||||
struct vnode *vp;
|
||||
|
||||
for (;;)
|
||||
for (dep = dehashtbl[DEHASH(dev, dirclust + diroff)];;
|
||||
dep = dep->de_next) {
|
||||
if (dep == NULL)
|
||||
return NULL;
|
||||
if (dirclust != dep->de_dirclust
|
||||
|| diroff != dep->de_diroffset
|
||||
|| dev != dep->de_dev
|
||||
|| dep->de_refcnt == 0)
|
||||
continue;
|
||||
if (dep->de_flag & DE_LOCKED) {
|
||||
dep->de_flag |= DE_WANTED;
|
||||
(void) tsleep((caddr_t)dep, PINOD, "msdhgt", 0);
|
||||
break;
|
||||
}
|
||||
if (!vget(DETOV(dep), LK_EXCLUSIVE | LK_INTERLOCK, curproc))
|
||||
return dep;
|
||||
break;
|
||||
loop:
|
||||
simple_lock(&dehash_slock);
|
||||
for (dep = DEHASH(dev, dirclust + diroff); dep; dep = dep->de_next) {
|
||||
if (dirclust == dep->de_dirclust
|
||||
&& diroff == dep->de_diroffset
|
||||
&& dev == dep->de_dev
|
||||
&& dep->de_refcnt != 0) {
|
||||
vp = DETOV(dep);
|
||||
simple_lock(&vp->v_interlock);
|
||||
simple_unlock(&dehash_slock);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
|
||||
goto loop;
|
||||
return (dep);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
simple_unlock(&dehash_slock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -138,13 +139,15 @@ msdosfs_hashins(dep)
|
||||
{
|
||||
struct denode **depp, *deq;
|
||||
|
||||
depp = &dehashtbl[DEHASH(dep->de_dev, dep->de_dirclust + dep->de_diroffset)];
|
||||
simple_lock(&dehash_slock);
|
||||
depp = &DEHASH(dep->de_dev, dep->de_dirclust + dep->de_diroffset);
|
||||
deq = *depp;
|
||||
if (deq)
|
||||
deq->de_prev = &dep->de_next;
|
||||
dep->de_next = deq;
|
||||
dep->de_prev = depp;
|
||||
*depp = dep;
|
||||
simple_unlock(&dehash_slock);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -152,6 +155,8 @@ msdosfs_hashrem(dep)
|
||||
struct denode *dep;
|
||||
{
|
||||
struct denode *deq;
|
||||
|
||||
simple_lock(&dehash_slock);
|
||||
deq = dep->de_next;
|
||||
if (deq)
|
||||
deq->de_prev = dep->de_prev;
|
||||
@ -160,6 +165,7 @@ msdosfs_hashrem(dep)
|
||||
dep->de_next = NULL;
|
||||
dep->de_prev = NULL;
|
||||
#endif
|
||||
simple_unlock(&dehash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -190,6 +196,7 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
|
||||
struct denode *ldep;
|
||||
struct vnode *nvp;
|
||||
struct buf *bp;
|
||||
struct proc *p = curproc; /* XXX */
|
||||
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("deget(pmp %p, dirclust %ld, diroffset %x, direntptr %p, depp %p)\n",
|
||||
@ -245,6 +252,7 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
|
||||
return error;
|
||||
}
|
||||
bzero((caddr_t)ldep, sizeof *ldep);
|
||||
lockinit(&ldep->de_lock, PINOD, "denode", 0, 0);
|
||||
nvp->v_data = ldep;
|
||||
ldep->de_vnode = nvp;
|
||||
ldep->de_flag = 0;
|
||||
@ -256,11 +264,17 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
|
||||
fc_purge(ldep, 0); /* init the fat cache for this denode */
|
||||
|
||||
/*
|
||||
* Insert the denode into the hash queue and lock the denode so it
|
||||
* can't be accessed until we've read it in and have done what we
|
||||
* need to it.
|
||||
* Lock the denode so that it can't be accessed until we've read
|
||||
* it in and have done what we need to it. Do this here instead
|
||||
* of at the start of msdosfs_hashins() so that reinsert() can
|
||||
* call msdosfs_hashins() with a locked denode.
|
||||
*/
|
||||
if (lockmgr(&ldep->de_lock, LK_EXCLUSIVE, (struct simplelock *)0, p))
|
||||
panic("deget: unexpected lock failure");
|
||||
|
||||
/*
|
||||
* Insert the denode into the hash queue.
|
||||
*/
|
||||
vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
msdosfs_hashins(ldep);
|
||||
|
||||
/*
|
||||
@ -684,10 +698,12 @@ int
|
||||
msdosfs_inactive(ap)
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(vp);
|
||||
struct proc *p = ap->a_p;
|
||||
int error = 0;
|
||||
struct timespec ts;
|
||||
|
||||
@ -699,14 +715,10 @@ msdosfs_inactive(ap)
|
||||
vprint("msdosfs_inactive(): pushing active", vp);
|
||||
|
||||
/*
|
||||
* Get rid of denodes related to stale file handles. Hmmm, what
|
||||
* does this really do?
|
||||
* Ignore inodes related to stale file handles.
|
||||
*/
|
||||
if (dep->de_Name[0] == SLOT_DELETED) {
|
||||
if ((vp->v_flag & VXLOCK) == 0)
|
||||
vgone(vp);
|
||||
return 0;
|
||||
}
|
||||
if (dep->de_Name[0] == SLOT_DELETED)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If the file has been deleted and it is on a read/write
|
||||
@ -717,9 +729,8 @@ msdosfs_inactive(ap)
|
||||
printf("msdosfs_inactive(): dep %p, refcnt %ld, mntflag %x, MNT_RDONLY %x\n",
|
||||
dep, dep->de_refcnt, vp->v_mount->mnt_flag, MNT_RDONLY);
|
||||
#endif
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
if (dep->de_refcnt <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
|
||||
error = detrunc(dep, (u_long) 0, 0, NOCRED, NULL);
|
||||
error = detrunc(dep, (u_long) 0, 0, NOCRED, p);
|
||||
dep->de_flag |= DE_UPDATE;
|
||||
dep->de_Name[0] = SLOT_DELETED;
|
||||
}
|
||||
@ -727,7 +738,8 @@ msdosfs_inactive(ap)
|
||||
TIMEVAL_TO_TIMESPEC(&time, &ts);
|
||||
deupdat(dep, &ts, 0);
|
||||
}
|
||||
VOP_UNLOCK(vp, 0, curproc);
|
||||
out:
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
dep->de_flag = 0;
|
||||
|
||||
/*
|
||||
@ -738,7 +750,7 @@ msdosfs_inactive(ap)
|
||||
printf("msdosfs_inactive(): v_usecount %d, de_Name[0] %x\n", vp->v_usecount,
|
||||
dep->de_Name[0]);
|
||||
#endif
|
||||
if (vp->v_usecount == 0 && dep->de_Name[0] == SLOT_DELETED)
|
||||
vgone(vp);
|
||||
if (dep->de_Name[0] == SLOT_DELETED)
|
||||
vrecycle(vp, (struct simplelock *)0, p);
|
||||
return error;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: msdosfs_lookup.c,v 1.10 1997/02/22 09:40:47 peter Exp $ */
|
||||
/* $NetBSD: msdosfs_lookup.c,v 1.14 1994/08/21 18:44:07 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -117,6 +117,7 @@ msdosfs_lookup(ap)
|
||||
u_char dosfilename[12];
|
||||
int flags = cnp->cn_flags;
|
||||
int nameiop = cnp->cn_nameiop;
|
||||
struct proc *p = cnp->cn_proc;
|
||||
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): looking for %s\n", cnp->cn_nameptr);
|
||||
@ -157,14 +158,14 @@ msdosfs_lookup(ap)
|
||||
VREF(vdp);
|
||||
error = 0;
|
||||
} else if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
error = vget(vdp, LK_EXCLUSIVE | LK_INTERLOCK, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
error = vget(vdp, LK_EXCLUSIVE, p);
|
||||
if (!error && lockparent && (flags & ISLASTCN))
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE, p);
|
||||
} else {
|
||||
error = vget(vdp, LK_EXCLUSIVE | LK_INTERLOCK, curproc);
|
||||
error = vget(vdp, LK_EXCLUSIVE, p);
|
||||
if (!lockparent || error || !(flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
@ -184,9 +185,9 @@ msdosfs_lookup(ap)
|
||||
}
|
||||
vput(vdp);
|
||||
if (lockparent && pdp != vdp && (flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
}
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE, p);
|
||||
if (error)
|
||||
return error;
|
||||
vdp = pdp;
|
||||
@ -346,7 +347,7 @@ notfound:;
|
||||
/* dp->de_flag |= DE_UPDATE; never update dos directories */
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
if (!lockparent)/* leave searched dir locked? */
|
||||
VOP_UNLOCK(vdp, 0, curproc);
|
||||
VOP_UNLOCK(vdp, 0, p);
|
||||
return EJUSTRETURN;
|
||||
}
|
||||
/*
|
||||
@ -399,7 +400,7 @@ foundroot:;
|
||||
}
|
||||
*vpp = DETOV(tdp);
|
||||
if (!lockparent)
|
||||
VOP_UNLOCK(vdp, 0, curproc);
|
||||
VOP_UNLOCK(vdp, 0, p);
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
return 0;
|
||||
@ -429,7 +430,7 @@ foundroot:;
|
||||
*vpp = DETOV(tdp);
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
if (!lockparent)
|
||||
VOP_UNLOCK(vdp, 0, curproc);
|
||||
VOP_UNLOCK(vdp, 0, p);
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
return 0;
|
||||
@ -440,16 +441,16 @@ foundroot:;
|
||||
*/
|
||||
pdp = vdp;
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
error = deget(pmp, cluster, diroff, dep, &tdp);
|
||||
if (error) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
return error;
|
||||
}
|
||||
if (lockparent && (flags & ISLASTCN)
|
||||
&& (error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
|
||||
&& (error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
|
||||
vput(DETOV(tdp));
|
||||
return error;
|
||||
}
|
||||
@ -465,7 +466,7 @@ foundroot:;
|
||||
return error;
|
||||
}
|
||||
if (!lockparent || !(flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
*vpp = DETOV(tdp);
|
||||
}
|
||||
if (bp)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: msdosfs_vfsops.c,v 1.16 1997/02/22 09:40:48 peter Exp $ */
|
||||
/* $NetBSD: msdosfs_vfsops.c,v 1.19 1994/08/21 18:44:10 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -67,8 +67,6 @@
|
||||
#include <msdosfs/msdosfsmount.h>
|
||||
#include <msdosfs/fat.h>
|
||||
|
||||
static int msdosfsdoforce = 1; /* 1 = force unmount */
|
||||
|
||||
static int mountmsdosfs __P((struct vnode *devvp, struct mount *mp,
|
||||
struct proc *p));
|
||||
static int msdosfs_fhtovp __P((struct mount *, struct fid *,
|
||||
@ -130,17 +128,14 @@ msdosfs_mount(mp, path, data, ndp, p)
|
||||
flags = WRITECLOSE;
|
||||
if (mp->mnt_flag & MNT_FORCE)
|
||||
flags |= FORCECLOSE;
|
||||
if (vfs_busy(mp, LK_NOWAIT, 0, p))
|
||||
return EBUSY;
|
||||
error = vflush(mp, NULLVP, flags);
|
||||
vfs_unbusy(mp, p);
|
||||
}
|
||||
if (!error && (mp->mnt_flag & MNT_RELOAD))
|
||||
/* not yet implemented */
|
||||
error = EINVAL;
|
||||
if (error)
|
||||
return error;
|
||||
if (pmp->pm_ronly && (mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
if (pmp->pm_ronly && (mp->mnt_flag & MNT_WANTRDWR))
|
||||
pmp->pm_ronly = 0;
|
||||
if (args.fspec == 0) {
|
||||
/*
|
||||
@ -531,9 +526,8 @@ mountmsdosfs(devvp, mp, p)
|
||||
if (ronly == 0)
|
||||
pmp->pm_fmod = 1;
|
||||
mp->mnt_data = (qaddr_t) pmp;
|
||||
mp->mnt_stat.f_fsid.val[0] = (long)dev;
|
||||
mp->mnt_stat.f_fsid.val[1] = MOUNT_MSDOS;
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
mp->mnt_stat.f_fsid.val[0] = (long)dev;
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
devvp->v_specflags |= SI_MOUNTEDON;
|
||||
|
||||
return 0;
|
||||
@ -581,8 +575,6 @@ msdosfs_unmount(mp, mntflags, p)
|
||||
return error;
|
||||
|
||||
if (mntflags & MNT_FORCE) {
|
||||
if (!msdosfsdoforce)
|
||||
return EINVAL;
|
||||
flags |= FORCECLOSE;
|
||||
}
|
||||
error = vflush(mp, NULLVP, flags);
|
||||
@ -595,7 +587,6 @@ msdosfs_unmount(mp, mntflags, p)
|
||||
free((caddr_t) pmp->pm_inusemap, M_MSDOSFSFAT);
|
||||
free((caddr_t) pmp, M_MSDOSFSMNT);
|
||||
mp->mnt_data = (qaddr_t) 0;
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -640,7 +631,6 @@ msdosfs_statfs(mp, sbp, p)
|
||||
/*
|
||||
* Fill in the stat block.
|
||||
*/
|
||||
sbp->f_type = MOUNT_MSDOS;
|
||||
sbp->f_bsize = pmp->pm_bpcluster;
|
||||
sbp->f_iosize = pmp->pm_bpcluster;
|
||||
sbp->f_blocks = pmp->pm_nmbrofclusters;
|
||||
@ -654,6 +644,7 @@ msdosfs_statfs(mp, sbp, p)
|
||||
* stat block, if it is not the one in the mount structure.
|
||||
*/
|
||||
if (sbp != &mp->mnt_stat) {
|
||||
sbp->f_type = mp->mnt_vfc->vfc_typenum;
|
||||
bcopy((caddr_t) mp->mnt_stat.f_mntonname,
|
||||
(caddr_t) & sbp->f_mntonname[0], MNAMELEN);
|
||||
bcopy((caddr_t) mp->mnt_stat.f_mntfromname,
|
||||
@ -696,24 +687,35 @@ msdosfs_sync(mp, waitfor, cred, p)
|
||||
* Go thru in memory denodes and write them out along with
|
||||
* unwritten file blocks.
|
||||
*/
|
||||
simple_lock(&mntvnode_slock);
|
||||
loop:
|
||||
for (vp = mp->mnt_vnodelist.lh_first; vp;
|
||||
vp = vp->v_mntvnodes.le_next) {
|
||||
if (vp->v_mount != mp) /* not ours anymore */
|
||||
goto loop;
|
||||
if (VOP_ISLOCKED(vp)) /* file is busy */
|
||||
continue;
|
||||
simple_lock(&vp->v_interlock);
|
||||
dep = VTODE(vp);
|
||||
if ((dep->de_flag & (DE_MODIFIED | DE_UPDATE)) == 0 &&
|
||||
vp->v_dirtyblkhd.lh_first == NULL)
|
||||
vp->v_dirtyblkhd.lh_first == NULL) {
|
||||
simple_unlock(&vp->v_interlock);
|
||||
continue;
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) /* not there anymore? */
|
||||
goto loop;
|
||||
}
|
||||
simple_unlock(&mntvnode_slock);
|
||||
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p);
|
||||
if (error) {
|
||||
simple_lock(&mntvnode_slock);
|
||||
if (error == ENOENT)
|
||||
goto loop;
|
||||
continue;
|
||||
}
|
||||
error = VOP_FSYNC(vp, cred, waitfor, p);
|
||||
if (error)
|
||||
allerror = error;
|
||||
vput(vp); /* done with this one */
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
vrele(vp); /* done with this one */
|
||||
simple_lock(&mntvnode_slock);
|
||||
}
|
||||
simple_unlock(&mntvnode_slock);
|
||||
|
||||
/*
|
||||
* Flush filesystem control info.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: msdosfs_vnops.c,v 1.39 1997/02/22 09:40:48 peter Exp $ */
|
||||
/* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -238,8 +238,10 @@ msdosfs_close(ap)
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(vp);
|
||||
|
||||
if (vp->v_usecount > 1 && !(dep->de_flag & DE_LOCKED))
|
||||
simple_lock(&vp->v_interlock);
|
||||
if (vp->v_usecount > 1)
|
||||
DE_TIMES(dep, &time);
|
||||
simple_unlock(&vp->v_interlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1045,6 +1047,8 @@ msdosfs_rename(ap)
|
||||
u_long cn;
|
||||
daddr_t bn;
|
||||
struct vnode *tvp = ap->a_tvp;
|
||||
struct componentname *fcnp = ap->a_fcnp;
|
||||
struct proc *p = fcnp->cn_proc;
|
||||
struct denode *fddep; /* from file's parent directory */
|
||||
struct denode *fdep; /* from file or directory */
|
||||
struct denode *tddep; /* to file's parent directory */
|
||||
@ -1172,17 +1176,17 @@ msdosfs_rename(ap)
|
||||
*/
|
||||
if (newparent == 0) {
|
||||
/* tddep and fddep point to the same denode here */
|
||||
vn_lock(ap->a_fvp, LK_EXCLUSIVE | LK_RETRY, curproc); /* ap->a_fdvp is already locked */
|
||||
vn_lock(ap->a_fvp, LK_EXCLUSIVE, p); /* ap->a_fdvp is already locked */
|
||||
error = readep(fddep->de_pmp, fdep->de_dirclust,
|
||||
fdep->de_diroffset, &bp, &ep);
|
||||
if (error) {
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
bcopy(toname, ep->deName, 11);
|
||||
error = bwrite(bp);
|
||||
if (error) {
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
bcopy(toname, fdep->de_Name, 11); /* update denode */
|
||||
@ -1204,7 +1208,7 @@ msdosfs_rename(ap)
|
||||
* will also insure that the directory entry on disk has a
|
||||
* filesize of zero.
|
||||
*/
|
||||
vn_lock(ap->a_fvp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
vn_lock(ap->a_fvp, LK_EXCLUSIVE, p);
|
||||
bcopy(toname, fdep->de_Name, 11); /* update denode */
|
||||
if (fdep->de_Attributes & ATTR_DIRECTORY) {
|
||||
dirsize = fdep->de_FileSize;
|
||||
@ -1216,22 +1220,22 @@ msdosfs_rename(ap)
|
||||
}
|
||||
if (error) {
|
||||
/* should put back filename */
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
vn_lock(ap->a_fdvp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
vn_lock(ap->a_fdvp, LK_EXCLUSIVE, p);
|
||||
error = readep(fddep->de_pmp, fddep->de_fndclust,
|
||||
fddep->de_fndoffset, &bp, &ep);
|
||||
if (error) {
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
ep->deName[0] = SLOT_DELETED;
|
||||
error = bwrite(bp);
|
||||
if (error) {
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
if (!sourceisadirectory) {
|
||||
@ -1239,7 +1243,7 @@ msdosfs_rename(ap)
|
||||
fdep->de_diroffset = tddep->de_fndoffset;
|
||||
reinsert(fdep);
|
||||
}
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, p);
|
||||
}
|
||||
/* fdep is still locked here */
|
||||
|
||||
@ -1259,19 +1263,19 @@ msdosfs_rename(ap)
|
||||
NOCRED, &bp);
|
||||
if (error) {
|
||||
/* should really panic here, fs is corrupt */
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
dotdotp = (struct direntry *) bp->b_data + 1;
|
||||
putushort(dotdotp->deStartCluster, tddep->de_StartCluster);
|
||||
error = bwrite(bp);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
if (error) {
|
||||
/* should really panic here, fs is corrupt */
|
||||
goto bad;
|
||||
}
|
||||
} else
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
bad: ;
|
||||
vrele(DETOV(fdep));
|
||||
vrele(DETOV(fddep));
|
||||
@ -1807,49 +1811,38 @@ static int
|
||||
msdosfs_lock(ap)
|
||||
struct vop_lock_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_flags;
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
while (dep->de_flag & DE_LOCKED) {
|
||||
dep->de_flag |= DE_WANTED;
|
||||
if (dep->de_lockholder == curproc->p_pid)
|
||||
panic("msdosfs_lock: locking against myself");
|
||||
dep->de_lockwaiter = curproc->p_pid;
|
||||
(void) tsleep((caddr_t) dep, PINOD, "msdlck", 0);
|
||||
}
|
||||
dep->de_lockwaiter = 0;
|
||||
dep->de_lockholder = curproc->p_pid;
|
||||
dep->de_flag |= DE_LOCKED;
|
||||
return 0;
|
||||
return (lockmgr(&VTODE(vp)->de_lock, ap->a_flags, &vp->v_interlock,
|
||||
ap->a_p));
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
msdosfs_unlock(ap)
|
||||
struct vop_unlock_args /* {
|
||||
struct vnode *vp;
|
||||
struct vnode *a_vp;
|
||||
int a_flags;
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
if (!(dep->de_flag & DE_LOCKED))
|
||||
panic("msdosfs_unlock: denode not locked");
|
||||
dep->de_lockholder = 0;
|
||||
dep->de_flag &= ~DE_LOCKED;
|
||||
if (dep->de_flag & DE_WANTED) {
|
||||
dep->de_flag &= ~DE_WANTED;
|
||||
wakeup((caddr_t) dep);
|
||||
}
|
||||
return 0;
|
||||
return (lockmgr(&VTODE(vp)->de_lock, ap->a_flags | LK_RELEASE,
|
||||
&vp->v_interlock, ap->a_p));
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
msdosfs_islocked(ap)
|
||||
struct vop_islocked_args /* {
|
||||
struct vnode *a_vp;
|
||||
} */ *ap;
|
||||
{
|
||||
return VTODE(ap->a_vp)->de_flag & DE_LOCKED ? 1 : 0;
|
||||
|
||||
return (lockstatus(&VTODE(ap->a_vp)->de_lock));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1952,15 +1945,9 @@ msdosfs_print(ap)
|
||||
printf(
|
||||
"tag VT_MSDOSFS, startcluster %d, dircluster %ld, diroffset %ld ",
|
||||
dep->de_StartCluster, dep->de_dirclust, dep->de_diroffset);
|
||||
printf(" dev %d, %d, %s\n",
|
||||
major(dep->de_dev), minor(dep->de_dev),
|
||||
dep->de_flag & DE_LOCKED ? "(LOCKED)" : "");
|
||||
if (dep->de_lockholder) {
|
||||
printf(" owner pid %d", (int)dep->de_lockholder);
|
||||
if (dep->de_lockwaiter)
|
||||
printf(" waiting pid %d", (int)dep->de_lockwaiter);
|
||||
printf("\n");
|
||||
}
|
||||
printf(" dev %d, %d", major(dep->de_dev), minor(dep->de_dev));
|
||||
lockmgr_printinfo(&dep->de_lock);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: denode.h,v 1.11 1997/02/22 09:40:44 peter Exp $ */
|
||||
/* $NetBSD: denode.h,v 1.8 1994/08/21 18:43:49 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -148,8 +148,7 @@ struct denode {
|
||||
long de_refcnt; /* reference count */
|
||||
struct msdosfsmount *de_pmp; /* addr of our mount struct */
|
||||
struct lockf *de_lockf; /* byte level lock list */
|
||||
pid_t de_lockholder; /* current lock holder */
|
||||
pid_t de_lockwaiter; /* lock wanter */
|
||||
struct lock de_lock; /* denode lock */
|
||||
/* the next two fields must be contiguous in memory... */
|
||||
u_char de_Name[8]; /* name, from directory entry */
|
||||
u_char de_Extension[3]; /* extension, from directory entry */
|
||||
@ -165,8 +164,6 @@ struct denode {
|
||||
/*
|
||||
* Values for the de_flag field of the denode.
|
||||
*/
|
||||
#define DE_LOCKED 0x0001 /* directory entry is locked */
|
||||
#define DE_WANTED 0x0002 /* someone wants this de */
|
||||
#define DE_UPDATE 0x0004 /* modification time update request */
|
||||
#define DE_MODIFIED 0x0080 /* denode has been modified, but DE_UPDATE
|
||||
* isn't set */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: msdosfs_denode.c,v 1.22 1997/02/22 09:40:46 peter Exp $ */
|
||||
/* $NetBSD: msdosfs_denode.c,v 1.9 1994/08/21 18:44:00 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -70,7 +70,8 @@
|
||||
|
||||
struct denode **dehashtbl;
|
||||
u_long dehash; /* size of hash table - 1 */
|
||||
#define DEHASH(dev, deno) (((dev) + (deno)) & dehash)
|
||||
#define DEHASH(dev, deno) (dehashtbl[((dev) + (deno)) & dehash])
|
||||
static struct simplelock dehash_slock;
|
||||
|
||||
union _qcvt {
|
||||
quad_t qcvt;
|
||||
@ -99,6 +100,7 @@ int msdosfs_init(vfsp)
|
||||
struct vfsconf *vfsp;
|
||||
{
|
||||
dehashtbl = hashinit(desiredvnodes/2, M_MSDOSFSMNT, &dehash);
|
||||
simple_lock_init(&dehash_slock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -108,28 +110,27 @@ msdosfs_hashget(dev, dirclust, diroff)
|
||||
u_long dirclust;
|
||||
u_long diroff;
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct denode *dep;
|
||||
struct vnode *vp;
|
||||
|
||||
for (;;)
|
||||
for (dep = dehashtbl[DEHASH(dev, dirclust + diroff)];;
|
||||
dep = dep->de_next) {
|
||||
if (dep == NULL)
|
||||
return NULL;
|
||||
if (dirclust != dep->de_dirclust
|
||||
|| diroff != dep->de_diroffset
|
||||
|| dev != dep->de_dev
|
||||
|| dep->de_refcnt == 0)
|
||||
continue;
|
||||
if (dep->de_flag & DE_LOCKED) {
|
||||
dep->de_flag |= DE_WANTED;
|
||||
(void) tsleep((caddr_t)dep, PINOD, "msdhgt", 0);
|
||||
break;
|
||||
}
|
||||
if (!vget(DETOV(dep), LK_EXCLUSIVE | LK_INTERLOCK, curproc))
|
||||
return dep;
|
||||
break;
|
||||
loop:
|
||||
simple_lock(&dehash_slock);
|
||||
for (dep = DEHASH(dev, dirclust + diroff); dep; dep = dep->de_next) {
|
||||
if (dirclust == dep->de_dirclust
|
||||
&& diroff == dep->de_diroffset
|
||||
&& dev == dep->de_dev
|
||||
&& dep->de_refcnt != 0) {
|
||||
vp = DETOV(dep);
|
||||
simple_lock(&vp->v_interlock);
|
||||
simple_unlock(&dehash_slock);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
|
||||
goto loop;
|
||||
return (dep);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
simple_unlock(&dehash_slock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -138,13 +139,15 @@ msdosfs_hashins(dep)
|
||||
{
|
||||
struct denode **depp, *deq;
|
||||
|
||||
depp = &dehashtbl[DEHASH(dep->de_dev, dep->de_dirclust + dep->de_diroffset)];
|
||||
simple_lock(&dehash_slock);
|
||||
depp = &DEHASH(dep->de_dev, dep->de_dirclust + dep->de_diroffset);
|
||||
deq = *depp;
|
||||
if (deq)
|
||||
deq->de_prev = &dep->de_next;
|
||||
dep->de_next = deq;
|
||||
dep->de_prev = depp;
|
||||
*depp = dep;
|
||||
simple_unlock(&dehash_slock);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -152,6 +155,8 @@ msdosfs_hashrem(dep)
|
||||
struct denode *dep;
|
||||
{
|
||||
struct denode *deq;
|
||||
|
||||
simple_lock(&dehash_slock);
|
||||
deq = dep->de_next;
|
||||
if (deq)
|
||||
deq->de_prev = dep->de_prev;
|
||||
@ -160,6 +165,7 @@ msdosfs_hashrem(dep)
|
||||
dep->de_next = NULL;
|
||||
dep->de_prev = NULL;
|
||||
#endif
|
||||
simple_unlock(&dehash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -190,6 +196,7 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
|
||||
struct denode *ldep;
|
||||
struct vnode *nvp;
|
||||
struct buf *bp;
|
||||
struct proc *p = curproc; /* XXX */
|
||||
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("deget(pmp %p, dirclust %ld, diroffset %x, direntptr %p, depp %p)\n",
|
||||
@ -245,6 +252,7 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
|
||||
return error;
|
||||
}
|
||||
bzero((caddr_t)ldep, sizeof *ldep);
|
||||
lockinit(&ldep->de_lock, PINOD, "denode", 0, 0);
|
||||
nvp->v_data = ldep;
|
||||
ldep->de_vnode = nvp;
|
||||
ldep->de_flag = 0;
|
||||
@ -256,11 +264,17 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
|
||||
fc_purge(ldep, 0); /* init the fat cache for this denode */
|
||||
|
||||
/*
|
||||
* Insert the denode into the hash queue and lock the denode so it
|
||||
* can't be accessed until we've read it in and have done what we
|
||||
* need to it.
|
||||
* Lock the denode so that it can't be accessed until we've read
|
||||
* it in and have done what we need to it. Do this here instead
|
||||
* of at the start of msdosfs_hashins() so that reinsert() can
|
||||
* call msdosfs_hashins() with a locked denode.
|
||||
*/
|
||||
if (lockmgr(&ldep->de_lock, LK_EXCLUSIVE, (struct simplelock *)0, p))
|
||||
panic("deget: unexpected lock failure");
|
||||
|
||||
/*
|
||||
* Insert the denode into the hash queue.
|
||||
*/
|
||||
vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
msdosfs_hashins(ldep);
|
||||
|
||||
/*
|
||||
@ -684,10 +698,12 @@ int
|
||||
msdosfs_inactive(ap)
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(vp);
|
||||
struct proc *p = ap->a_p;
|
||||
int error = 0;
|
||||
struct timespec ts;
|
||||
|
||||
@ -699,14 +715,10 @@ msdosfs_inactive(ap)
|
||||
vprint("msdosfs_inactive(): pushing active", vp);
|
||||
|
||||
/*
|
||||
* Get rid of denodes related to stale file handles. Hmmm, what
|
||||
* does this really do?
|
||||
* Ignore inodes related to stale file handles.
|
||||
*/
|
||||
if (dep->de_Name[0] == SLOT_DELETED) {
|
||||
if ((vp->v_flag & VXLOCK) == 0)
|
||||
vgone(vp);
|
||||
return 0;
|
||||
}
|
||||
if (dep->de_Name[0] == SLOT_DELETED)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If the file has been deleted and it is on a read/write
|
||||
@ -717,9 +729,8 @@ msdosfs_inactive(ap)
|
||||
printf("msdosfs_inactive(): dep %p, refcnt %ld, mntflag %x, MNT_RDONLY %x\n",
|
||||
dep, dep->de_refcnt, vp->v_mount->mnt_flag, MNT_RDONLY);
|
||||
#endif
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
if (dep->de_refcnt <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
|
||||
error = detrunc(dep, (u_long) 0, 0, NOCRED, NULL);
|
||||
error = detrunc(dep, (u_long) 0, 0, NOCRED, p);
|
||||
dep->de_flag |= DE_UPDATE;
|
||||
dep->de_Name[0] = SLOT_DELETED;
|
||||
}
|
||||
@ -727,7 +738,8 @@ msdosfs_inactive(ap)
|
||||
TIMEVAL_TO_TIMESPEC(&time, &ts);
|
||||
deupdat(dep, &ts, 0);
|
||||
}
|
||||
VOP_UNLOCK(vp, 0, curproc);
|
||||
out:
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
dep->de_flag = 0;
|
||||
|
||||
/*
|
||||
@ -738,7 +750,7 @@ msdosfs_inactive(ap)
|
||||
printf("msdosfs_inactive(): v_usecount %d, de_Name[0] %x\n", vp->v_usecount,
|
||||
dep->de_Name[0]);
|
||||
#endif
|
||||
if (vp->v_usecount == 0 && dep->de_Name[0] == SLOT_DELETED)
|
||||
vgone(vp);
|
||||
if (dep->de_Name[0] == SLOT_DELETED)
|
||||
vrecycle(vp, (struct simplelock *)0, p);
|
||||
return error;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: msdosfs_lookup.c,v 1.10 1997/02/22 09:40:47 peter Exp $ */
|
||||
/* $NetBSD: msdosfs_lookup.c,v 1.14 1994/08/21 18:44:07 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -117,6 +117,7 @@ msdosfs_lookup(ap)
|
||||
u_char dosfilename[12];
|
||||
int flags = cnp->cn_flags;
|
||||
int nameiop = cnp->cn_nameiop;
|
||||
struct proc *p = cnp->cn_proc;
|
||||
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): looking for %s\n", cnp->cn_nameptr);
|
||||
@ -157,14 +158,14 @@ msdosfs_lookup(ap)
|
||||
VREF(vdp);
|
||||
error = 0;
|
||||
} else if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
error = vget(vdp, LK_EXCLUSIVE | LK_INTERLOCK, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
error = vget(vdp, LK_EXCLUSIVE, p);
|
||||
if (!error && lockparent && (flags & ISLASTCN))
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE, p);
|
||||
} else {
|
||||
error = vget(vdp, LK_EXCLUSIVE | LK_INTERLOCK, curproc);
|
||||
error = vget(vdp, LK_EXCLUSIVE, p);
|
||||
if (!lockparent || error || !(flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
@ -184,9 +185,9 @@ msdosfs_lookup(ap)
|
||||
}
|
||||
vput(vdp);
|
||||
if (lockparent && pdp != vdp && (flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
}
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE, p);
|
||||
if (error)
|
||||
return error;
|
||||
vdp = pdp;
|
||||
@ -346,7 +347,7 @@ notfound:;
|
||||
/* dp->de_flag |= DE_UPDATE; never update dos directories */
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
if (!lockparent)/* leave searched dir locked? */
|
||||
VOP_UNLOCK(vdp, 0, curproc);
|
||||
VOP_UNLOCK(vdp, 0, p);
|
||||
return EJUSTRETURN;
|
||||
}
|
||||
/*
|
||||
@ -399,7 +400,7 @@ foundroot:;
|
||||
}
|
||||
*vpp = DETOV(tdp);
|
||||
if (!lockparent)
|
||||
VOP_UNLOCK(vdp, 0, curproc);
|
||||
VOP_UNLOCK(vdp, 0, p);
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
return 0;
|
||||
@ -429,7 +430,7 @@ foundroot:;
|
||||
*vpp = DETOV(tdp);
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
if (!lockparent)
|
||||
VOP_UNLOCK(vdp, 0, curproc);
|
||||
VOP_UNLOCK(vdp, 0, p);
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
return 0;
|
||||
@ -440,16 +441,16 @@ foundroot:;
|
||||
*/
|
||||
pdp = vdp;
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
error = deget(pmp, cluster, diroff, dep, &tdp);
|
||||
if (error) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
return error;
|
||||
}
|
||||
if (lockparent && (flags & ISLASTCN)
|
||||
&& (error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
|
||||
&& (error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
|
||||
vput(DETOV(tdp));
|
||||
return error;
|
||||
}
|
||||
@ -465,7 +466,7 @@ foundroot:;
|
||||
return error;
|
||||
}
|
||||
if (!lockparent || !(flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0, curproc);
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
*vpp = DETOV(tdp);
|
||||
}
|
||||
if (bp)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: msdosfs_vfsops.c,v 1.16 1997/02/22 09:40:48 peter Exp $ */
|
||||
/* $NetBSD: msdosfs_vfsops.c,v 1.19 1994/08/21 18:44:10 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -67,8 +67,6 @@
|
||||
#include <msdosfs/msdosfsmount.h>
|
||||
#include <msdosfs/fat.h>
|
||||
|
||||
static int msdosfsdoforce = 1; /* 1 = force unmount */
|
||||
|
||||
static int mountmsdosfs __P((struct vnode *devvp, struct mount *mp,
|
||||
struct proc *p));
|
||||
static int msdosfs_fhtovp __P((struct mount *, struct fid *,
|
||||
@ -130,17 +128,14 @@ msdosfs_mount(mp, path, data, ndp, p)
|
||||
flags = WRITECLOSE;
|
||||
if (mp->mnt_flag & MNT_FORCE)
|
||||
flags |= FORCECLOSE;
|
||||
if (vfs_busy(mp, LK_NOWAIT, 0, p))
|
||||
return EBUSY;
|
||||
error = vflush(mp, NULLVP, flags);
|
||||
vfs_unbusy(mp, p);
|
||||
}
|
||||
if (!error && (mp->mnt_flag & MNT_RELOAD))
|
||||
/* not yet implemented */
|
||||
error = EINVAL;
|
||||
if (error)
|
||||
return error;
|
||||
if (pmp->pm_ronly && (mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
if (pmp->pm_ronly && (mp->mnt_flag & MNT_WANTRDWR))
|
||||
pmp->pm_ronly = 0;
|
||||
if (args.fspec == 0) {
|
||||
/*
|
||||
@ -531,9 +526,8 @@ mountmsdosfs(devvp, mp, p)
|
||||
if (ronly == 0)
|
||||
pmp->pm_fmod = 1;
|
||||
mp->mnt_data = (qaddr_t) pmp;
|
||||
mp->mnt_stat.f_fsid.val[0] = (long)dev;
|
||||
mp->mnt_stat.f_fsid.val[1] = MOUNT_MSDOS;
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
mp->mnt_stat.f_fsid.val[0] = (long)dev;
|
||||
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
|
||||
devvp->v_specflags |= SI_MOUNTEDON;
|
||||
|
||||
return 0;
|
||||
@ -581,8 +575,6 @@ msdosfs_unmount(mp, mntflags, p)
|
||||
return error;
|
||||
|
||||
if (mntflags & MNT_FORCE) {
|
||||
if (!msdosfsdoforce)
|
||||
return EINVAL;
|
||||
flags |= FORCECLOSE;
|
||||
}
|
||||
error = vflush(mp, NULLVP, flags);
|
||||
@ -595,7 +587,6 @@ msdosfs_unmount(mp, mntflags, p)
|
||||
free((caddr_t) pmp->pm_inusemap, M_MSDOSFSFAT);
|
||||
free((caddr_t) pmp, M_MSDOSFSMNT);
|
||||
mp->mnt_data = (qaddr_t) 0;
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -640,7 +631,6 @@ msdosfs_statfs(mp, sbp, p)
|
||||
/*
|
||||
* Fill in the stat block.
|
||||
*/
|
||||
sbp->f_type = MOUNT_MSDOS;
|
||||
sbp->f_bsize = pmp->pm_bpcluster;
|
||||
sbp->f_iosize = pmp->pm_bpcluster;
|
||||
sbp->f_blocks = pmp->pm_nmbrofclusters;
|
||||
@ -654,6 +644,7 @@ msdosfs_statfs(mp, sbp, p)
|
||||
* stat block, if it is not the one in the mount structure.
|
||||
*/
|
||||
if (sbp != &mp->mnt_stat) {
|
||||
sbp->f_type = mp->mnt_vfc->vfc_typenum;
|
||||
bcopy((caddr_t) mp->mnt_stat.f_mntonname,
|
||||
(caddr_t) & sbp->f_mntonname[0], MNAMELEN);
|
||||
bcopy((caddr_t) mp->mnt_stat.f_mntfromname,
|
||||
@ -696,24 +687,35 @@ msdosfs_sync(mp, waitfor, cred, p)
|
||||
* Go thru in memory denodes and write them out along with
|
||||
* unwritten file blocks.
|
||||
*/
|
||||
simple_lock(&mntvnode_slock);
|
||||
loop:
|
||||
for (vp = mp->mnt_vnodelist.lh_first; vp;
|
||||
vp = vp->v_mntvnodes.le_next) {
|
||||
if (vp->v_mount != mp) /* not ours anymore */
|
||||
goto loop;
|
||||
if (VOP_ISLOCKED(vp)) /* file is busy */
|
||||
continue;
|
||||
simple_lock(&vp->v_interlock);
|
||||
dep = VTODE(vp);
|
||||
if ((dep->de_flag & (DE_MODIFIED | DE_UPDATE)) == 0 &&
|
||||
vp->v_dirtyblkhd.lh_first == NULL)
|
||||
vp->v_dirtyblkhd.lh_first == NULL) {
|
||||
simple_unlock(&vp->v_interlock);
|
||||
continue;
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) /* not there anymore? */
|
||||
goto loop;
|
||||
}
|
||||
simple_unlock(&mntvnode_slock);
|
||||
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p);
|
||||
if (error) {
|
||||
simple_lock(&mntvnode_slock);
|
||||
if (error == ENOENT)
|
||||
goto loop;
|
||||
continue;
|
||||
}
|
||||
error = VOP_FSYNC(vp, cred, waitfor, p);
|
||||
if (error)
|
||||
allerror = error;
|
||||
vput(vp); /* done with this one */
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
vrele(vp); /* done with this one */
|
||||
simple_lock(&mntvnode_slock);
|
||||
}
|
||||
simple_unlock(&mntvnode_slock);
|
||||
|
||||
/*
|
||||
* Flush filesystem control info.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id$ */
|
||||
/* $Id: msdosfs_vnops.c,v 1.39 1997/02/22 09:40:48 peter Exp $ */
|
||||
/* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -238,8 +238,10 @@ msdosfs_close(ap)
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(vp);
|
||||
|
||||
if (vp->v_usecount > 1 && !(dep->de_flag & DE_LOCKED))
|
||||
simple_lock(&vp->v_interlock);
|
||||
if (vp->v_usecount > 1)
|
||||
DE_TIMES(dep, &time);
|
||||
simple_unlock(&vp->v_interlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1045,6 +1047,8 @@ msdosfs_rename(ap)
|
||||
u_long cn;
|
||||
daddr_t bn;
|
||||
struct vnode *tvp = ap->a_tvp;
|
||||
struct componentname *fcnp = ap->a_fcnp;
|
||||
struct proc *p = fcnp->cn_proc;
|
||||
struct denode *fddep; /* from file's parent directory */
|
||||
struct denode *fdep; /* from file or directory */
|
||||
struct denode *tddep; /* to file's parent directory */
|
||||
@ -1172,17 +1176,17 @@ msdosfs_rename(ap)
|
||||
*/
|
||||
if (newparent == 0) {
|
||||
/* tddep and fddep point to the same denode here */
|
||||
vn_lock(ap->a_fvp, LK_EXCLUSIVE | LK_RETRY, curproc); /* ap->a_fdvp is already locked */
|
||||
vn_lock(ap->a_fvp, LK_EXCLUSIVE, p); /* ap->a_fdvp is already locked */
|
||||
error = readep(fddep->de_pmp, fdep->de_dirclust,
|
||||
fdep->de_diroffset, &bp, &ep);
|
||||
if (error) {
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
bcopy(toname, ep->deName, 11);
|
||||
error = bwrite(bp);
|
||||
if (error) {
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
bcopy(toname, fdep->de_Name, 11); /* update denode */
|
||||
@ -1204,7 +1208,7 @@ msdosfs_rename(ap)
|
||||
* will also insure that the directory entry on disk has a
|
||||
* filesize of zero.
|
||||
*/
|
||||
vn_lock(ap->a_fvp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
vn_lock(ap->a_fvp, LK_EXCLUSIVE, p);
|
||||
bcopy(toname, fdep->de_Name, 11); /* update denode */
|
||||
if (fdep->de_Attributes & ATTR_DIRECTORY) {
|
||||
dirsize = fdep->de_FileSize;
|
||||
@ -1216,22 +1220,22 @@ msdosfs_rename(ap)
|
||||
}
|
||||
if (error) {
|
||||
/* should put back filename */
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
vn_lock(ap->a_fdvp, LK_EXCLUSIVE | LK_RETRY, curproc);
|
||||
vn_lock(ap->a_fdvp, LK_EXCLUSIVE, p);
|
||||
error = readep(fddep->de_pmp, fddep->de_fndclust,
|
||||
fddep->de_fndoffset, &bp, &ep);
|
||||
if (error) {
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
ep->deName[0] = SLOT_DELETED;
|
||||
error = bwrite(bp);
|
||||
if (error) {
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
if (!sourceisadirectory) {
|
||||
@ -1239,7 +1243,7 @@ msdosfs_rename(ap)
|
||||
fdep->de_diroffset = tddep->de_fndoffset;
|
||||
reinsert(fdep);
|
||||
}
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fdvp, 0, p);
|
||||
}
|
||||
/* fdep is still locked here */
|
||||
|
||||
@ -1259,19 +1263,19 @@ msdosfs_rename(ap)
|
||||
NOCRED, &bp);
|
||||
if (error) {
|
||||
/* should really panic here, fs is corrupt */
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
goto bad;
|
||||
}
|
||||
dotdotp = (struct direntry *) bp->b_data + 1;
|
||||
putushort(dotdotp->deStartCluster, tddep->de_StartCluster);
|
||||
error = bwrite(bp);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
if (error) {
|
||||
/* should really panic here, fs is corrupt */
|
||||
goto bad;
|
||||
}
|
||||
} else
|
||||
VOP_UNLOCK(ap->a_fvp, 0, curproc);
|
||||
VOP_UNLOCK(ap->a_fvp, 0, p);
|
||||
bad: ;
|
||||
vrele(DETOV(fdep));
|
||||
vrele(DETOV(fddep));
|
||||
@ -1807,49 +1811,38 @@ static int
|
||||
msdosfs_lock(ap)
|
||||
struct vop_lock_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_flags;
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
while (dep->de_flag & DE_LOCKED) {
|
||||
dep->de_flag |= DE_WANTED;
|
||||
if (dep->de_lockholder == curproc->p_pid)
|
||||
panic("msdosfs_lock: locking against myself");
|
||||
dep->de_lockwaiter = curproc->p_pid;
|
||||
(void) tsleep((caddr_t) dep, PINOD, "msdlck", 0);
|
||||
}
|
||||
dep->de_lockwaiter = 0;
|
||||
dep->de_lockholder = curproc->p_pid;
|
||||
dep->de_flag |= DE_LOCKED;
|
||||
return 0;
|
||||
return (lockmgr(&VTODE(vp)->de_lock, ap->a_flags, &vp->v_interlock,
|
||||
ap->a_p));
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
msdosfs_unlock(ap)
|
||||
struct vop_unlock_args /* {
|
||||
struct vnode *vp;
|
||||
struct vnode *a_vp;
|
||||
int a_flags;
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
if (!(dep->de_flag & DE_LOCKED))
|
||||
panic("msdosfs_unlock: denode not locked");
|
||||
dep->de_lockholder = 0;
|
||||
dep->de_flag &= ~DE_LOCKED;
|
||||
if (dep->de_flag & DE_WANTED) {
|
||||
dep->de_flag &= ~DE_WANTED;
|
||||
wakeup((caddr_t) dep);
|
||||
}
|
||||
return 0;
|
||||
return (lockmgr(&VTODE(vp)->de_lock, ap->a_flags | LK_RELEASE,
|
||||
&vp->v_interlock, ap->a_p));
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
msdosfs_islocked(ap)
|
||||
struct vop_islocked_args /* {
|
||||
struct vnode *a_vp;
|
||||
} */ *ap;
|
||||
{
|
||||
return VTODE(ap->a_vp)->de_flag & DE_LOCKED ? 1 : 0;
|
||||
|
||||
return (lockstatus(&VTODE(ap->a_vp)->de_lock));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1952,15 +1945,9 @@ msdosfs_print(ap)
|
||||
printf(
|
||||
"tag VT_MSDOSFS, startcluster %d, dircluster %ld, diroffset %ld ",
|
||||
dep->de_StartCluster, dep->de_dirclust, dep->de_diroffset);
|
||||
printf(" dev %d, %d, %s\n",
|
||||
major(dep->de_dev), minor(dep->de_dev),
|
||||
dep->de_flag & DE_LOCKED ? "(LOCKED)" : "");
|
||||
if (dep->de_lockholder) {
|
||||
printf(" owner pid %d", (int)dep->de_lockholder);
|
||||
if (dep->de_lockwaiter)
|
||||
printf(" waiting pid %d", (int)dep->de_lockwaiter);
|
||||
printf("\n");
|
||||
}
|
||||
printf(" dev %d, %d", major(dep->de_dev), minor(dep->de_dev));
|
||||
lockmgr_printinfo(&dep->de_lock);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user