diff options
author | bde <bde@FreeBSD.org> | 1997-02-26 14:23:16 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1997-02-26 14:23:16 +0000 |
commit | 26d93ee7e17fd7b6270c426b888f5157872b7c62 (patch) | |
tree | b44ac98051213280c764930c4afc6f1b7e6c50d4 | |
parent | c2cd7345306e1e316a03ce0920d27ac5292cc05a (diff) | |
download | FreeBSD-src-26d93ee7e17fd7b6270c426b888f5157872b7c62.zip FreeBSD-src-26d93ee7e17fd7b6270c426b888f5157872b7c62.tar.gz |
Updated msdosfs to use Lite2 vfs configuration and Lite2 locking. It
should now work as (un)well as before the Lite2 merge.
-rw-r--r-- | sys/fs/msdosfs/denode.h | 7 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_denode.c | 90 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_lookup.c | 31 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_vfsops.c | 42 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_vnops.c | 89 | ||||
-rw-r--r-- | sys/msdosfs/denode.h | 7 | ||||
-rw-r--r-- | sys/msdosfs/msdosfs_denode.c | 90 | ||||
-rw-r--r-- | sys/msdosfs/msdosfs_lookup.c | 31 | ||||
-rw-r--r-- | sys/msdosfs/msdosfs_vfsops.c | 42 | ||||
-rw-r--r-- | sys/msdosfs/msdosfs_vnops.c | 89 |
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; } |