Alexander Bluhm <[email protected]> wrote:

> Quite often I see "panic: unmount: dangling vnode".  My test
> regress/sys/kern/mount triggers it, but it also happens when rebooting
> virtual machines.
> 
> The problem is, when dirty buffers are flushed to disk, the unmount
> process sleeps.  If the file system is busy, other processes can
> create new dirty buffers by writing files.
> 
> First I tired to block these writes.  But this is very complex.  A
> much simpler solution is to flush a few times.  With this diff I
> could not trigger the problem anymore.
> 
> Is that fix good enough?

Hmm.  In Feb 2018 I added a mechanism so that suspend & hibernate
can do a better job syncronizing filesystems.

Look at vfs_stall(), can it be somewhat repurposed for reboots?
Hmm... I think I tried, but hit some problems.

> Index: kern/vfs_subr.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/kern/vfs_subr.c,v
> retrieving revision 1.293
> diff -u -p -r1.293 vfs_subr.c
> --- kern/vfs_subr.c   26 Aug 2019 18:56:29 -0000      1.293
> +++ kern/vfs_subr.c   20 Nov 2019 20:50:31 -0000
> @@ -962,14 +962,20 @@ int
>  vflush(struct mount *mp, struct vnode *skipvp, int flags)
>  {
>       struct vflush_args va;
> +     int loopcnt;
>       va.skipvp = skipvp;
>       va.busy = 0;
>       va.flags = flags;
> 
> -     vfs_mount_foreach_vnode(mp, vflush_vnode, &va);
> -
> -     if (va.busy)
> -             return (EBUSY);
> +     for (loopcnt = 10; loopcnt > 0; loopcnt--) {
> +             vfs_mount_foreach_vnode(mp, vflush_vnode, &va);
> +             if (va.busy)
> +                     return (EBUSY);
> +             if ((flags & FORCECLOSE) == 0)
> +                     break;
> +             if (LIST_EMPTY(&mp->mnt_vnodelist))
> +                     break;
> +     }
>       return (0);
>  }
> 

Reply via email to