summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/fs/msdosfs/denode.h7
-rw-r--r--sys/fs/msdosfs/msdosfs_denode.c90
-rw-r--r--sys/fs/msdosfs/msdosfs_lookup.c31
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c42
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c89
-rw-r--r--sys/msdosfs/denode.h7
-rw-r--r--sys/msdosfs/msdosfs_denode.c90
-rw-r--r--sys/msdosfs/msdosfs_lookup.c31
-rw-r--r--sys/msdosfs/msdosfs_vfsops.c42
-rw-r--r--sys/msdosfs/msdosfs_vnops.c89
10 files changed, 258 insertions, 260 deletions
diff --git a/sys/fs/msdosfs/denode.h b/sys/fs/msdosfs/denode.h
index a6ed185..a03c802 100644
--- a/sys/fs/msdosfs/denode.h
+++ b/sys/fs/msdosfs/denode.h
@@ -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 */
diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
index 0f40e18..e1d5610 100644
--- a/sys/fs/msdosfs/msdosfs_denode.c
+++ b/sys/fs/msdosfs/msdosfs_denode.c
@@ -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;
-
- 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;
+ struct vnode *vp;
+
+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;
}
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
index fdd4ec9..9bc576c 100644
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -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)
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index 0f28b44..cd78d84 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -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.
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index 65e8725..1f775a5 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -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;
}
diff --git a/sys/msdosfs/denode.h b/sys/msdosfs/denode.h
index a6ed185..a03c802 100644
--- a/sys/msdosfs/denode.h
+++ b/sys/msdosfs/denode.h
@@ -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 */
diff --git a/sys/msdosfs/msdosfs_denode.c b/sys/msdosfs/msdosfs_denode.c
index 0f40e18..e1d5610 100644
--- a/sys/msdosfs/msdosfs_denode.c
+++ b/sys/msdosfs/msdosfs_denode.c
@@ -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;
-
- 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;
+ struct vnode *vp;
+
+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;
}
diff --git a/sys/msdosfs/msdosfs_lookup.c b/sys/msdosfs/msdosfs_lookup.c
index fdd4ec9..9bc576c 100644
--- a/sys/msdosfs/msdosfs_lookup.c
+++ b/sys/msdosfs/msdosfs_lookup.c
@@ -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)
diff --git a/sys/msdosfs/msdosfs_vfsops.c b/sys/msdosfs/msdosfs_vfsops.c
index 0f28b44..cd78d84 100644
--- a/sys/msdosfs/msdosfs_vfsops.c
+++ b/sys/msdosfs/msdosfs_vfsops.c
@@ -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.
diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c
index 65e8725..1f775a5 100644
--- a/sys/msdosfs/msdosfs_vnops.c
+++ b/sys/msdosfs/msdosfs_vnops.c
@@ -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;
}
OpenPOWER on IntegriCloud