Hi,

we sometimes see a panic "unmount: dangling vnode" when rebooting a 6.1
system with softdep.

I have hacked some diagnostic panics until I got these traces from the
reboot and update process.

Reboot:
sleep_finish() at sleep_finish+0xb1
tsleep() at tsleep+0x154
biowait() at biowait+0x46
bwrite() at bwrite+0x10d
ffs_update() at ffs_update+0x2bd
VOP_FSYNC() at VOP_FSYNC+0x3c
ffs_flushfiles() at ffs_flushfiles+0xb9
softdep_flushfiles() at softdep_flushfiles+0x4e
ffs_unmount() at ffs_unmount+0x49
dounmount_leaf() at dounmount_leaf+0x8b
dounmount() at dounmount+0xb2
vfs_unmountall() at vfs_unmountall+0x72
vfs_shutdown() at vfs_shutdown+0x79
boot() at boot+0x144
reboot() at reboot+0x30
sys_reboot() at sys_reboot+0x5e
syscall() at syscall+0x21f

Update:
*115878  74431      0     0x14000      0x200    0  update
Debugger() at Debugger+0x9
panic() at panic+0xfe
insmntque() at insmntque+0x86
getnewvnode() at getnewvnode+0x192
ffs_vget() at ffs_vget+0x8b
handle_workitem_remove() at handle_workitem_remove+0x4c
process_worklist_item() at process_worklist_item+0xf5
softdep_process_worklist() at softdep_process_worklist+0x169
sched_sync() at sched_sync+0xfb

At reboot all vnodes are flushed, but when it sleeps, the update
process has a chance to create new dirty vnodes.  Resolving soft
dependencies adds vnodes to the dirty list.

In softdep_flushfiles() vnodes and softdep are flushed in a loop.
But if they sleep, it is not guaranteed that all vnodes have been
flushed when the softdep worklist flush reports that nothing has
been done.

My solution is to do a final vnode flush after the softdep worklist
has been flushed.  Then the dirty list is empty and the final check in
dounmount_leaf() does not panic.

ok?

bluhm

Index: ufs/ffs/ffs_softdep.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/ufs/ffs/ffs_softdep.c,v
retrieving revision 1.135
diff -u -p -r1.135 ffs_softdep.c
--- ufs/ffs/ffs_softdep.c       7 Nov 2016 00:26:33 -0000       1.135
+++ ufs/ffs/ffs_softdep.c       9 Oct 2017 22:19:39 -0000
@@ -904,6 +904,14 @@ softdep_flushfiles(struct mount *oldmnt,
                        break;
        }
        /*
+        * If the reboot process sleeps during the loop, the update
+        * process may call softdep_process_worklist() and create
+        * new dirty vnodes at the mount point.  Call ffs_flushfiles()
+        * again after the loop has flushed all soft dependencies.
+        */
+       if (error == 0)
+               error = ffs_flushfiles(oldmnt, flags, p);
+       /*
         * If we are unmounting then it is an error to fail. If we
         * are simply trying to downgrade to read-only, then filesystem
         * activity can keep us busy forever, so we just fail with EBUSY.

Reply via email to