On 06/07/18(Fri) 12:49, Alexander Bluhm wrote:
> On Mon, May 07, 2018 at 05:21:19PM +0200, Alexander Bluhm wrote:
> > panic: vinvalbuf: dirty bufs
>
> At least I know what is going on here.
>
> vinvalbuf() calls ffs_fsync() to write all dirty buffers of the
> mount point to disk.
>
> if ((error = VOP_FSYNC(vp, cred, MNT_WAIT, p)) != 0)
> return (error);
>
> ffs_fsync() does this successfully and verifies that there are no
> dirty blocks left.
>
> if (!LIST_EMPTY(&vp->v_dirtyblkhd)) {
>
> But then it calls ufs_update() to write the inode to disk. It waits
> until the disk operation has finished.
>
> return (UFS_UPDATE(VTOI(vp), ap->a_waitfor == MNT_WAIT));
>
> My test is still running a cp -r and rm -rf operating on the file
> system. While bread() or bwrite() sleeps in the unmount process,
> the rm process inserts a new dirty block into the vnode's list.
So we might need a barrier or a delayed free to fix this problem.
It would be nice to know where are the 'cp' and 'rm' process blocking
when the 'unmount' process goes to sleep. You could put a break before
UFS_UPDATE() and use 'ps /up 0t$PID' to get this information.
Another interesting piece of information is if at least one of the two
processes already have a reference to `i_devvp'.