Index: kern/kern_lock.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_lock.c,v retrieving revision 1.31 diff -u -r1.31 kern_lock.c --- kern_lock.c 1999/12/11 16:12:52 1.31 +++ kern_lock.c 1999/12/11 16:21:22 @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -144,7 +145,14 @@ lkp->lk_flags |= LK_WAIT_NONZERO; lkp->lk_waitcount++; simple_unlock(&lkp->lk_interlock); +#ifdef INVARIANTS + error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo ? lkp->lk_timo : 100*hz); + if (error == EWOULDBLOCK && lkp->lk_timo == 0) + Debugger("Timed out at 100s"); +#else + error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo); +#endif simple_lock(&lkp->lk_interlock); if (lkp->lk_waitcount == 1) { lkp->lk_flags &= ~LK_WAIT_NONZERO; @@ -216,6 +224,16 @@ * lock requests or upgrade requests ( but not the exclusive * lock itself ). */ + /* + * XXX Adrian's comment + * + * Why in gods name do you want to create a shared lock + * when a good exclusive lock exists for this object? + * If we get this problem, *panic*. You should be upgrading / + * downgrading the locks the proper way. + */ + if (lkp->lk_lockholder == pid && (lkp->lk_flags & LK_EXCLUSIVE)) +panic("lockmgr: trying to LK_SHARED on a LK_EXCLUSIVEd lock"); if (lkp->lk_lockholder != pid) { if (p && (p->p_flag & P_DEADLKTREAT)) { error = acquire( @@ -472,8 +490,15 @@ while (lkp->lk_flags & LK_ALL) { lkp->lk_flags |= LK_WAITDRAIN; simple_unlock(&lkp->lk_interlock); +#ifdef INVARIANTS + error = tsleep(&lkp->lk_flags, lkp->lk_prio, + lkp->lk_wmesg, lkp->lk_timo ? lkp->lk_timo : 100*hz); + if (error == EWOULDBLOCK && lkp->lk_timo == 0) + Debugger("Timed out after 100 sec"); +#else error = tsleep(&lkp->lk_flags, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo); +#endif simple_lock(&lkp->lk_interlock); if (error) return error; Index: kern/vfs_bio.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v retrieving revision 1.237 diff -u -r1.237 vfs_bio.c --- vfs_bio.c 1999/12/01 02:09:29 1.237 +++ vfs_bio.c 1999/12/07 19:29:35 @@ -27,6 +27,16 @@ * see man buf(9) for more info. */ +/* + * XXX I'd like this here, but it'd involve making everything that + * deals with bio talk locking correctly, and I'm not up to that + * stage just yet. -- Adrian Chadd + */ + +#ifdef DEBUG_VFS_LOCKS +#undef DEBUG_VFS_LOCKS +#endif + #include #include #include @@ -489,7 +499,9 @@ struct buf ** bpp) { struct buf *bp; + int waslocked; + /* ASSERT_VOP_LOCKED(vp, "bread"); */ bp = getblk(vp, blkno, size, 0, 0); *bpp = bp; @@ -602,9 +614,17 @@ panic("bwrite: buffer is not busy???"); #endif s = splbio(); + bundirty(bp); bp->b_flags &= ~(B_READ | B_DONE | B_ERROR); + /* + * I stuck in a B_WRITE here because VOP_STRATEGY needs it. + * It wasn't set in the bp we were passed. I'm not sure whether + * its meant to be setup in the routine calling bwrite(), however + * in bread() a =| B_READ is done to flags, so I'm GUESSING + * that this is ok. Guessing, that is. :-) + */ bp->b_flags |= B_WRITEINPROG | B_CACHE; bp->b_vp->v_numoutput++; @@ -614,6 +634,7 @@ splx(s); if (oldflags & B_ASYNC) BUF_KERNPROC(bp); + bp->b_flags |= B_WRITE; VOP_STRATEGY(bp->b_vp, bp); if ((oldflags & B_ASYNC) == 0) { @@ -633,6 +654,10 @@ * set B_CACHE. In fact, we have to set B_CACHE here rather then in * biodone() in order to prevent getblk from writing the buffer * out synchronously. + * + * Note that the vnode you are using *MUST* be locked, but right now, + * I'm going to try and do an exclusive lock right now if its not + * exclusive locked, and if its share locked, panic. */ void bdwrite(struct buf * bp) @@ -642,8 +667,17 @@ panic("bdwrite: buffer is not busy"); #endif + /* + * XXX I'd like this here, but it'd involve making everything that + * deals with bio talk locking correctly, and I'm not up to that + * stage just yet. -- Adrian Chadd + */ + + /* ASSERT_VOP_LOCKED(bp->b_vp, "bdwrite"); */ + if (bp->b_flags & B_INVAL) { brelse(bp); + VOP_UNLOCK(bp->b_vp, 0, curproc); return; } bdirty(bp); @@ -664,7 +698,13 @@ * the bmap then... So, this is important to do. */ if (bp->b_lblkno == bp->b_blkno) { + /* + * I'm asserting that we should have the vnode exclusive locked + * on entry right now, so there's no point locking it here.. + */ + /* vn_lock(bp->b_vp, LK_EXCLUSIVE | LK_RETRY, curproc); */ VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL); + /* VOP_UNLOCK(bp->b_vp, 0, curproc); */ } /* @@ -782,8 +822,8 @@ int bowrite(struct buf * bp) { - bp->b_flags |= B_ORDERED | B_ASYNC; - return (VOP_BWRITE(bp->b_vp, bp)); + bp->b_flags |= B_ORDERED | B_ASYNC | B_WRITE; + return(VOP_BWRITE(bp->b_vp, bp)); } /* @@ -1240,6 +1280,7 @@ int maxcl; s = splbio(); + /* * right now we support clustered writing only to regular files. If * we find a clusterable block we could be in the middle of a cluster @@ -2580,9 +2621,11 @@ obj = vp->v_object; #if defined(VFS_BIO_DEBUG) + /* if (vp->v_usecount == 0) { panic("biodone: zero vnode ref count"); } + */ if (vp->v_object == NULL) { panic("biodone: missing VM object"); Index: kern/vfs_default.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_default.c,v retrieving revision 1.25 diff -u -r1.25 vfs_default.c --- vfs_default.c 1999/12/11 16:12:52 1.25 +++ vfs_default.c 1999/12/11 16:21:26 @@ -71,7 +71,7 @@ { &vop_ioctl_desc, (vop_t *) vop_enotty }, { &vop_islocked_desc, (vop_t *) vop_noislocked }, { &vop_lease_desc, (vop_t *) vop_null }, - { &vop_lock_desc, (vop_t *) vop_nolock }, + { &vop_lock_desc, (vop_t *) vop_sharedlock }, { &vop_mmap_desc, (vop_t *) vop_einval }, { &vop_open_desc, (vop_t *) vop_null }, { &vop_pathconf_desc, (vop_t *) vop_einval }, Index: kern/vfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_vnops.c,v retrieving revision 1.84 diff -u -r1.84 vfs_vnops.c --- vfs_vnops.c 1999/11/18 08:14:20 1.84 +++ vfs_vnops.c 1999/12/07 19:29:36 @@ -595,14 +595,16 @@ tsleep((caddr_t)vp, PINOD, "vn_lock", 0); error = ENOENT; } else { + error = VOP_LOCK(vp, + flags | LK_NOPAUSE | LK_INTERLOCK, p); #ifdef DEBUG_LOCKS vp->filename = filename; vp->line = line; #endif - error = VOP_LOCK(vp, - flags | LK_NOPAUSE | LK_INTERLOCK, p); - if (error == 0) + if (error == 0) { + ASSERT_VOP_LOCKED(vp, "vn_lock"); return (error); + } } flags &= ~LK_INTERLOCK; } while (flags & LK_RETRY); Index: kern/vnode_if.sh =================================================================== RCS file: /home/ncvs/src/sys/kern/vnode_if.sh,v retrieving revision 1.20 diff -u -r1.20 vnode_if.sh --- vnode_if.sh 1999/09/26 18:31:51 1.20 +++ vnode_if.sh 1999/12/07 21:33:15 @@ -229,17 +229,22 @@ } if (exists($lockdata{$name}) && exists($lockdata{$name}->{$args{$c2}})) { - if ($ENV{'DEBUG_ALL_VFS_LOCKS'} =~ /yes/i) { - # Add assertions for locking - if ($lockdata{$name}->{$args{$c2}}->{Entry} eq "L") { - print HEADER - "\tASSERT_VOP_LOCKED($args{$c2}, \"$uname\");\n"; - } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "U") { - print HEADER - "\tASSERT_VOP_UNLOCKED($args{$c2}, \"$uname\");\n"; - } elsif (0) { - # XXX More checks! - } + # Add assertions for locking + if ($lockdata{$name}->{$args{$c2}}->{Entry} eq "L") { + print HEADER "\tASSERT_VOP_LOCKED($args{$c2}, \"$uname\");\n"; + } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "A") { + print HEADER "\tASSERT_VOP_LOCKED($args{$c2}, \"$uname\");\n"; + } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "U") { + print HEADER "\tASSERT_VOP_UNLOCKED($args{$c2}, \"$uname\");\n"; + } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "E") { + print HEADER "\tASSERT_VOP_ELOCKED($args{$c2}, \"$uname\");\n"; + } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "S") { + print HEADER "\tASSERT_VOP_SLOCKED($args{$c2}, \"$uname\");\n"; + } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "O") { + print HEADER + "\tASSERT_VOP_ELOCKED_OTHER($args{$c2}, \"$uname\");\n"; + } elsif (0) { + # XXX More checks? } } } Index: kern/vnode_if.src =================================================================== RCS file: /home/ncvs/src/sys/kern/vnode_if.src,v retrieving revision 1.26 diff -u -r1.26 vnode_if.src --- vnode_if.src 1999/12/11 16:12:53 1.26 +++ vnode_if.src 1999/12/11 16:21:27 @@ -270,10 +270,10 @@ }; # -#% rename fdvp U U U -#% rename fvp U U U -#% rename tdvp L U U -#% rename tvp X U U +#% rename fdvp = = = +#% rename fvp = = = +#% rename tdvp L L L +#% rename tvp L L L # vop_rename { IN WILLRELE struct vnode *fdvp; @@ -339,7 +339,7 @@ }; # -#% abortop dvp = = = +#% abortop dvp L L L # vop_abortop { IN struct vnode *dvp; @@ -363,7 +363,7 @@ }; # -#% lock vp U L U +#% lock vp ? L U # vop_lock { IN struct vnode *vp; Index: sys/buf.h =================================================================== RCS file: /home/ncvs/src/sys/sys/buf.h,v retrieving revision 1.85 diff -u -r1.85 buf.h --- buf.h 1999/12/12 06:09:57 1.85 +++ buf.h 1999/12/12 14:04:23 @@ -214,7 +214,7 @@ #define B_DIRTY 0x00200000 /* Needs writing later. */ #define B_RELBUF 0x00400000 /* Release VMIO buffer. */ #define B_WANT 0x00800000 /* Used by vm_pager.c */ -#define B_WRITE 0x00000000 /* Write buffer (pseudo flag). */ +#define B_WRITE 0x02000000 /* Write buffer (pseudo flag). */ #define B_WRITEINPROG 0x01000000 /* Write in progress. */ #define B_XXX 0x02000000 /* Debugging flag. */ #define B_PAGING 0x04000000 /* volatile paging I/O -- bypass VMIO */ Index: sys/vnode.h =================================================================== RCS file: /home/ncvs/src/sys/sys/vnode.h,v retrieving revision 1.105 diff -u -r1.105 vnode.h --- vnode.h 1999/12/11 16:13:01 1.105 +++ vnode.h 1999/12/12 14:32:10 @@ -409,7 +409,8 @@ * filesystem using a single-threaded test. I find that 'cvs co src' * is a pretty good test. */ - +#include +#include /* * [dfr] Kludge until I get around to fixing all the vfs locking. */ Index: ufs/ffs/ffs_alloc.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_alloc.c,v retrieving revision 1.62 diff -u -r1.62 ffs_alloc.c --- ffs_alloc.c 1999/12/01 19:33:12 1.62 +++ ffs_alloc.c 1999/12/07 19:30:27 @@ -598,6 +598,7 @@ if (ino == 0) goto noinodes; error = VFS_VGET(pvp->v_mount, ino, vpp); + /* At this stage, vpp is locked and ref'ed */ if (error) { UFS_VFREE(pvp, ino, mode); return (error); @@ -619,6 +620,7 @@ */ if (ip->i_gen == 0 || ++ip->i_gen == 0) ip->i_gen = random() / 2 + 1; + /* At this stage, we're returning with a locked vnode */ return (0); noinodes: ffs_fserr(fs, cred->cr_uid, "out of inodes"); @@ -889,14 +891,17 @@ int allocsiz, error, frags; fs = ip->i_fs; + /* Check to see whether we have any blocks free in this cylinder group */ if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize) return (0); + /* Read in the cylinder group */ error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, NOCRED, &bp); if (error) { brelse(bp); return (0); } + /* Check magic */ cgp = (struct cg *)bp->b_data; if (!cg_chkmagic(cgp) || (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) { Index: ufs/ffs/ffs_inode.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_inode.c,v retrieving revision 1.56 diff -u -r1.56 ffs_inode.c --- ffs_inode.c 1999/08/28 00:52:21 1.56 +++ ffs_inode.c 1999/12/07 18:51:53 @@ -95,10 +95,12 @@ ip->i_din.di_ouid = ip->i_uid; /* XXX */ ip->i_din.di_ogid = ip->i_gid; /* XXX */ } /* XXX */ + (void) vn_lock(ip->i_devvp, LK_EXCLUSIVE | LK_RETRY, curproc); error = bread(ip->i_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), (int)fs->fs_bsize, NOCRED, &bp); if (error) { brelse(bp); + (void) VOP_UNLOCK(ip->i_devvp, 0, curproc); return (error); } if (DOINGSOFTDEP(vp)) @@ -108,11 +110,14 @@ *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ip->i_number)) = ip->i_din; if (waitfor && !DOINGASYNC(vp)) { - return (bwrite(bp)); + error = bwrite(bp); + (void) VOP_UNLOCK(ip->i_devvp, 0, curproc); + return (error); } else { if (bp->b_bufsize == fs->fs_bsize) bp->b_flags |= B_CLUSTEROK; bdwrite(bp); + (void) VOP_UNLOCK(ip->i_devvp, 0, curproc); return (0); } } Index: ufs/ffs/ffs_subr.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_subr.c,v retrieving revision 1.24 diff -u -r1.24 ffs_subr.c --- ffs_subr.c 1999/08/28 00:52:22 1.24 +++ ffs_subr.c 1999/12/07 18:51:53 @@ -60,6 +60,8 @@ * Return buffer with the contents of block "offset" from the beginning of * directory "ip". If "res" is non-zero, fill it in with a pointer to the * remaining space in the directory. + * + * vnode 'vp' should be locked on entry. */ int ffs_blkatoff(vp, offset, res, bpp) @@ -80,6 +82,7 @@ bsize = blksize(fs, ip, lbn); *bpp = NULL; + ASSERT_VOP_LOCKED(vp, "ffs_blkatoff"); error = bread(vp, lbn, bsize, NOCRED, &bp); if (error) { brelse(bp); Index: ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.112 diff -u -r1.112 ffs_vfsops.c --- ffs_vfsops.c 1999/11/22 10:33:53 1.112 +++ ffs_vfsops.c 1999/12/07 19:30:28 @@ -123,6 +123,31 @@ * system call will fail with EFAULT in copyinstr in * namei() if it is a genuine NULL from the user. */ +static char * +vnflag(int f) +{ + f &= LK_TYPE_MASK; + switch (f) { + case LK_SHARED: + return "LK_SHARED"; + case LK_EXCLUSIVE: + return "LK_EXCLUSIVE"; + case LK_UPGRADE: + return "LK_UPGRADE"; + case LK_EXCLUPGRADE: + return "LK_EXCLUPGRADE"; + case LK_DOWNGRADE: + return "LK_DOWNGRADE"; + case LK_RELEASE: + return "LK_DOWNGRADE"; + case LK_DRAIN: + return "LK_DRAIN"; + default: + return "UNKNOWN"; + } + /* not reached */ +} + static int ffs_mount( mp, path, data, ndp, p) struct mount *mp; /* mount struct pointer*/ @@ -450,12 +475,24 @@ size = DEV_BSIZE; else size = dpart.disklab->d_secsize; - if ((error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, NOCRED,&bp)) != 0) + /* XXX Adrian - lock the vnode for the duration of the block dev access */ + /* + * (I still don't like the race conditions that might happen, but VOP_IOCTL + * doesn't want a locked vnode, hrm. If we did it, then we could guarantee + * things being atomic a little better, but then there could be an spl or + * vfs_busy on this mountpoint stopping things.. I'm clueless atm :-) + */ + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); + error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, NOCRED,&bp); + if (error != 0) { + VOP_UNLOCK(devvp, 0, p); return (error); + } newfs = (struct fs *)bp->b_data; if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE || newfs->fs_bsize < sizeof(struct fs)) { brelse(bp); + VOP_UNLOCK(devvp, 0, p); return (EIO); /* XXX needs translation */ } fs = VFSTOUFS(mp)->um_fs; @@ -484,8 +521,10 @@ size = (blks - i) * fs->fs_fsize; error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, NOCRED, &bp); - if (error) + if (error) { + VOP_UNLOCK(devvp, 0, p); return (error); + } bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size); brelse(bp); } @@ -530,6 +569,7 @@ (int)fs->fs_bsize, NOCRED, &bp); if (error) { vput(vp); + VOP_UNLOCK(devvp, 0, p); return (error); } ip->i_din = *((struct dinode *)bp->b_data + @@ -540,6 +580,7 @@ simple_lock(&mntvnode_slock); } simple_unlock(&mntvnode_slock); + VOP_UNLOCK(devvp, 0, p); return (0); } @@ -618,6 +659,7 @@ bp = NULL; ump = NULL; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); if ((error = bread(devvp, SBLOCK, SBSIZE, cred, &bp)) != 0) goto out; fs = (struct fs *)bp->b_data; @@ -744,11 +786,13 @@ fs->fs_clean = 0; (void) ffs_sbupdate(ump, MNT_WAIT); } + VOP_UNLOCK(devvp, 0, p); return (0); out: devvp->v_specmountpoint = NULL; if (bp) brelse(bp); + VOP_UNLOCK(devvp, 0, p); (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p); if (ump) { free(ump->um_fs, M_UFSMNT); @@ -966,6 +1010,20 @@ } if (vp->v_type != VCHR) { simple_unlock(&mntvnode_slock); + /* + * Adrian's note: Here we are getting a vnode from the free list + * to sync. We're getting panics when doing file operations and + * syncer kicks in, because the vnode is being operated on by + * another process. + * + * The bit that gets me is that we're panicing due to a locking + * violation - vget() calls VOP_LOCK(), which finds out the vnode + * is locked, and panics. Inspection shows that the vnode is actually + * rather used :) - I'm taking a wild stab here and concluding that + * we either shouldn't be calling vget() here if the vnode is actually + * referenced, or that the vget() man page/description needs to be + * updated ever so slightly. I'm still vnode-clueless at this stage :( + */ error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p); if (error) { @@ -1031,6 +1089,7 @@ struct vnode *vp; dev_t dev; int error; + struct proc *p = curproc; /* XXX */ ump = VFSTOUFS(mp); dev = ump->um_dev; @@ -1100,8 +1159,16 @@ ffs_inode_hash_lock = 0; /* Read in the disk contents for the inode, copy into the inode. */ + /* + * Ok, at this stage, ffs_vget has stopped other processes calling + * ffs_vget() through the spinlock on ffs_inode_hash_lock. So that + * stops us getting trampled here, but it doesn't stop someone fscking + * with the backing store at a later date, i think. Feh... + */ + vn_lock(ump->um_devvp, LK_SHARED | LK_RETRY, p); error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), (int)fs->fs_bsize, NOCRED, &bp); + VOP_UNLOCK(ump->um_devvp, 0, p); if (error) { /* * The inode does not contain anything useful, so it would @@ -1155,6 +1222,7 @@ } /* XXX */ *vpp = vp; + ASSERT_VOP_LOCKED(vp, "ffs_vget"); return (0); } Index: ufs/ufs/ufs_lookup.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_lookup.c,v retrieving revision 1.31 diff -u -r1.31 ufs_lookup.c --- ufs_lookup.c 1999/10/30 00:51:14 1.31 +++ ufs_lookup.c 1999/12/07 18:51:53 @@ -984,6 +984,8 @@ int error, count, namlen; #define MINDIRSIZ (sizeof (struct dirtemplate) / 2) + ASSERT_VOP_LOCKED(ITOV(ip), "ufs_dirempty"); + for (off = 0; off < ip->i_size; off += dp->d_reclen) { error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ, off, UIO_SYSSPACE, IO_NODELOCKED, cred, &count, (struct proc *)0); Index: ufs/ufs/ufs_readwrite.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_readwrite.c,v retrieving revision 1.65 diff -u -r1.65 ufs_readwrite.c --- ufs_readwrite.c 1999/09/20 23:27:58 1.65 +++ ufs_readwrite.c 1999/12/07 18:51:53 @@ -658,8 +658,10 @@ IDX_TO_OFF(ap->a_m[firstpage]->pindex); physoffset -= foff; + (void)vn_lock(dp, LK_SHARED | LK_RETRY, curproc); rtval = VOP_GETPAGES(dp, &ap->a_m[firstpage], size, (ap->a_reqpage - firstpage), physoffset); + (void)VOP_UNLOCK(dp, 0, curproc); return (rtval); } Index: ufs/ufs/ufs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.127 diff -u -r1.127 ufs_vnops.c --- ufs_vnops.c 1999/11/13 20:58:17 1.127 +++ ufs_vnops.c 1999/12/07 19:30:29 @@ -1788,8 +1788,38 @@ } vp = ip->i_devvp; bp->b_dev = vp->v_rdev; - VOP_STRATEGY(vp, bp); - return (0); + KASSERT(bp->b_flags & (B_READ|B_WRITE), + ("B_READ|B_WRITE not set in VOP_STRATEGY")); + /* + * XXX Ok, things are going funny here, and causing panics .. + * up until now, vp has been the passed vnode, not the struct buf. + * however, we've just made vp = ip->i_devvp, and THIS is causing + * something rather bad to blow up because its not LK_EXCLUSIVEd. + * Hrm. I can gather that vp at this point is not the file vnode, + * rather its the device vnode, which we're passing to *its* + * strategy routine to do the converting, but my question is this: + * why is the device node opened shared here? :-) + */ +/* + if (bp->b_flags & B_READ) { + waslocked = VOP_ISLOCKED(vp); + if (!waslocked) + (void)vn_lock(vp, LK_SHARED | LK_RETRY, curproc); + } else { + waslocked = VOP_ISLOCKED(vp); + if (waslocked && waslocked != LK_EXCLUSIVE) + panic("ufs_strategy: vnode isn't LK_EXCLUSIVEd!"); + + if (!waslocked) + (void)vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); + } +*/ + error = VOP_STRATEGY(vp, bp); +/* + if (!waslocked) + (void)VOP_UNLOCK(vp, 0, curproc); +*/ + return (error); } /*