Subject: Re: uvm_fp2 deadlock in 1.6B4
To: tld <tld@tld.digitalcurse.com>
From: Jaromir Dolecek <jdolecek@netbsd.org>
List: current-users
Date: 08/07/2002 20:09:13
--ELM72957166-1291-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII
tld wrote:
> So far it happened 3 times (out of 3 tries to backup the drives), and
> only on ext2fs partitions. Similar problems did not arise with ffs
> (softdep off) when doing the very same things.
Cool. This is important - it's likely a ext2fs bug then.
> As for the DDB, I can compile that, find a keyboard and a monitor (I
> can't do that via network, can I?).
> I don't know about "provide kernel traceback of gzip process". If given
> appropriate instructions I will gladly follow them and provide with
> anything you might need.
Hmm, let's try something a simple change first.
I noted some difference between ext2fs_balloc_range() and
ufs_balloc_range(). There doesn't seem to be particular reason for
this difference, and basically doesn't seem to be particular reason
for ext2fs-specific function at all.
Can you try appended patch, which makes ext2fs code to use the
ufs_balloc_range() function, rather than it's own, slightly incorrect,
copy? The patch should be applied in sys/ufs/ext2fs/ directory.
Note this patch isn't really tested, so be careful (and keep old
kernel around ;)
Jaromir
--
Jaromir Dolecek <jdolecek@NetBSD.org> http://www.NetBSD.org/
-=- We should be mindful of the potential goal, but as the tantric -=-
-=- Buddhist masters say, ``You may notice during meditation that you -=-
-=- sometimes levitate or glow. Do not let this distract you.'' -=-
--ELM72957166-1291-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=ISO-8859-2
Content-Disposition: attachment; filename=e2fix.diff
? e2fix.diff
Index: ext2fs_balloc.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ext2fs/ext2fs_balloc.c,v
retrieving revision 1.17
diff -u -p -r1.17 ext2fs_balloc.c
--- ext2fs_balloc.c 2002/05/05 17:01:41 1.17
+++ ext2fs_balloc.c 2002/08/07 18:03:05
@@ -368,97 +368,3 @@ ext2fs_gop_alloc(struct vnode *vp, off_t
}
return 0;
}
-
-/*
- * allocate a range of blocks in a file.
- * after this function returns, any page entirely contained within the range
- * will map to invalid data and thus must be overwritten before it is made
- * accessible to others.
- */
-
-int
-ext2fs_balloc_range(vp, off, len, cred, flags)
- struct vnode *vp;
- off_t off, len;
- struct ucred *cred;
- int flags;
-{
- off_t oldeof, eof, pagestart;
- struct genfs_node *gp = VTOG(vp);
- int i, delta, error, npages;
- int bshift = vp->v_mount->mnt_fs_bshift;
- int bsize = 1 << bshift;
- int ppb = max(bsize >> PAGE_SHIFT, 1);
- struct vm_page *pgs[ppb];
- UVMHIST_FUNC("ext2fs_balloc_range"); UVMHIST_CALLED(ubchist);
- UVMHIST_LOG(ubchist, "vp %p off 0x%x len 0x%x u_size 0x%x",
- vp, off, len, vp->v_size);
-
- oldeof = vp->v_size;
- eof = MAX(oldeof, off + len);
- UVMHIST_LOG(ubchist, "new eof 0x%x", eof,0,0,0);
- pgs[0] = NULL;
-
- /*
- * cache the new range of the file. this will create zeroed pages
- * where the new block will be and keep them locked until the
- * new block is allocated, so there will be no window where
- * the old contents of the new block is visible to racing threads.
- */
-
- pagestart = trunc_page(off) & ~(bsize - 1);
- npages = MIN(ppb, (round_page(eof) - pagestart) >> PAGE_SHIFT);
- memset(pgs, 0, npages * sizeof(struct vm_page *));
- simple_lock(&vp->v_interlock);
- error = VOP_GETPAGES(vp, pagestart, pgs, &npages, 0,
- VM_PROT_READ, 0, PGO_SYNCIO | PGO_PASTEOF);
- if (error) {
- return error;
- }
- for (i = 0; i < npages; i++) {
- UVMHIST_LOG(ubchist, "got pgs[%d] %p", i, pgs[i],0,0);
- KASSERT((pgs[i]->flags & PG_RELEASED) == 0);
- pgs[i]->flags &= ~PG_CLEAN;
- uvm_pageactivate(pgs[i]);
- }
-
- /*
- * adjust off to be block-aligned.
- */
-
- delta = off & (bsize - 1);
- off -= delta;
- len += delta;
-
- /*
- * now allocate the range.
- */
-
- lockmgr(&gp->g_glock, LK_EXCLUSIVE, NULL);
- error = GOP_ALLOC(vp, off, len, flags, cred);
- UVMHIST_LOG(ubchist, "alloc %d", error,0,0,0);
- lockmgr(&gp->g_glock, LK_RELEASE, NULL);
-
- /*
- * clear PG_RDONLY on any pages we are holding
- * (since they now have backing store) and unbusy them.
- * if we got an error, free any pages we created past the old eob.
- */
-
- simple_lock(&vp->v_interlock);
- for (i = 0; i < npages; i++) {
- pgs[i]->flags &= ~PG_RDONLY;
- if (error) {
- pgs[i]->flags |= PG_RELEASED;
- }
- }
- if (error) {
- uvm_lock_pageq();
- uvm_page_unbusy(pgs, npages);
- uvm_unlock_pageq();
- } else {
- uvm_page_unbusy(pgs, npages);
- }
- simple_unlock(&vp->v_interlock);
- return (error);
-}
Index: ext2fs_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ext2fs/ext2fs_extern.h,v
retrieving revision 1.11
diff -u -p -r1.11 ext2fs_extern.h
--- ext2fs_extern.h 2001/09/15 20:36:41 1.11
+++ ext2fs_extern.h 2002/08/07 18:03:05
@@ -72,8 +72,6 @@ int ext2fs_vfree __P((void *));
int ext2fs_balloc __P((struct inode *, ufs_daddr_t, int, struct ucred *,
struct buf **, int));
int ext2fs_gop_alloc __P((struct vnode *, off_t, off_t, int, struct ucred *));
-int ext2fs_balloc_range __P((struct vnode *, off_t, off_t, struct ucred *,
- int));
/* ext2fs_bmap.c */
int ext2fs_bmap __P((void *));
Index: ext2fs_inode.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ext2fs/ext2fs_inode.c,v
retrieving revision 1.27
diff -u -p -r1.27 ext2fs_inode.c
--- ext2fs_inode.c 2001/11/08 02:39:07 1.27
+++ ext2fs_inode.c 2002/08/07 18:03:05
@@ -236,7 +236,7 @@ ext2fs_truncate(v)
if (length > fs->fs_maxfilesize)
return (EFBIG);
#endif
- ext2fs_balloc_range(ovp, length - 1, 1, ap->a_cred,
+ ufs_balloc_range(ovp, length - 1, 1, ap->a_cred,
ap->a_flags & IO_SYNC ? B_SYNC : 0);
oip->i_flag |= IN_CHANGE | IN_UPDATE;
return (VOP_UPDATE(ovp, NULL, NULL, 1));
Index: ext2fs_readwrite.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ext2fs/ext2fs_readwrite.c,v
retrieving revision 1.24
diff -u -p -r1.24 ext2fs_readwrite.c
--- ext2fs_readwrite.c 2002/03/25 02:23:55 1.24
+++ ext2fs_readwrite.c 2002/08/07 18:03:05
@@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: ext2fs_readw
#include <sys/signalvar.h>
#include <ufs/ufs/inode.h>
+#include <ufs/ufs/ufs_extern.h>
#include <ufs/ext2fs/ext2fs.h>
#include <ufs/ext2fs/ext2fs_extern.h>
@@ -272,7 +273,7 @@ ext2fs_write(v)
bytelen = MIN(fs->e2fs_bsize - blkoffset,
uio->uio_resid);
- error = ext2fs_balloc_range(vp, uio->uio_offset,
+ error = ufs_balloc_range(vp, uio->uio_offset,
bytelen, ap->a_cred, 0);
if (error) {
break;
--ELM72957166-1291-0_--