NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/47937: mount -o discard,log is broken



>Number:         47937
>Category:       kern
>Synopsis:       mounting ffs with both discard and log triggers lock assertion
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jun 16 18:15:00 +0000 2013
>Originator:     Jeff Rizzo
>Release:        NetBSD 6.99.21
>Organization:
        
>Environment:
        
        
System: NetBSD slash.lan 6.99.21 NetBSD 6.99.21 (DTRACE) #13: Sun Jun 16 
10:18:36 PDT 2013 
riz%slash.lan@localhost:/usr/src/sys/arch/amd64/compile/DTRACE amd64
Architecture: x86_64
Machine: amd64
>Description:
        Mounting a file system with both "discard" and "log" options
        triggers an assert in the WAPBL code the first time
        ffs_discardcb() is called.

        (transcribed by hand):
        panic: kernel diagnostic assertion "rw_lock_held(&wl->wl_rwlock)" 
failed: ../../../../kern/vfs_wapbl.c". line 1725

        backtrace:
        kern_assert()
        wapbl_add_buf()
        bdwrite()
        ffs_blkfree_cg()
        ffs_discardcb()
        workqueue_worker()

        Naively wrapping the call to ffs_blkfree_cb() in ffs_blkfree_td() with
        a WAPBL transaction doesn't help, because the pointers seem to
        be different (as printed by the added debug printfs):

Index: ./ufs/ffs/ffs_alloc.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_alloc.c,v
retrieving revision 1.133
diff -u -r1.133 ffs_alloc.c
--- ./ufs/ffs/ffs_alloc.c       22 Jan 2013 09:39:15 -0000      1.133
+++ ./ufs/ffs/ffs_alloc.c       16 Jun 2013 17:32:51 -0000
@@ -1571,7 +1571,9 @@
        cg = dtog(fs, bno);
        dev = devvp->v_rdev;
        ump = VFSTOUFS(devvp->v_specmountpoint);
+       printf("ffs_blkfree_cg: mountpoint %p\n", ump->um_fs);
        KASSERT(fs == ump->um_fs);
+       UFS_WAPBL_JLOCK_ASSERT(ump->um_mountp);
        cgblkno = fsbtodb(fs, cgtod(fs, cg));
 
        error = bread(devvp, cgblkno, (int)fs->fs_cgsize,
@@ -1613,11 +1615,17 @@
 ffs_blkfree_td(struct fs *fs, struct discardopdata *td)
 {
        long todo;
+       int err;
 
        while (td->size) {
                todo = min(td->size,
                  lfragtosize(fs, (fs->fs_frag - fragnum(fs, td->bno))));
+               printf("mountpoint = %p\n", td->devvp->v_mount);
+               err = UFS_WAPBL_BEGIN(td->devvp->v_mount);
+               KASSERT(err == 0);
                ffs_blkfree_cg(fs, td->devvp, td->bno, todo);
+               if ( err == 0 )
+                   UFS_WAPBL_END(td->devvp->v_mount);
                td->bno += numfrags(fs, todo);
                td->size -= todo;
        }
>How-To-Repeat:
        mount -o log,discard /dev/dk4 /mnt # testing discard on wedges
        rm -f /mnt/*

>Fix:
        none given.

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index