panic ffs_truncate3 (maybe fuse being evil)

Konstantin Belousov kostikbel at gmail.com
Sat Jan 16 19:11:24 UTC 2016


On Fri, Jan 15, 2016 at 09:00:05PM -0500, Rick Macklem wrote:
> --- ufs/ffs/ffs_inode.c.sav	2016-01-10 20:11:46.406682000 -0500
> +++ ufs/ffs/ffs_inode.c	2016-01-15 17:22:58.465991000 -0500
> @@ -544,7 +544,12 @@ done:
>  	BO_LOCK(bo);
>  	if (length == 0 &&
>  	    (fs->fs_magic != FS_UFS2_MAGIC || ip->i_din2->di_extsize == 0) &&
> -	    (bo->bo_dirty.bv_cnt > 0 || bo->bo_clean.bv_cnt > 0))
> +	    ((bo->bo_dirty.bv_cnt > 0 && (TAILQ_EMPTY(&bo->bo_dirty.bv_hd) ||
> +	     TAILQ_FIRST(&bo->bo_dirty.bv_hd)->b_lblkno >= 0 ||
> +	     TAILQ_FIRST(&bo->bo_dirty.bv_hd)->b_lblkno < -2)) ||
> +	     (bo->bo_clean.bv_cnt > 0 && (TAILQ_EMPTY(&bo->bo_clean.bv_hd) ||
> +	     TAILQ_FIRST(&bo->bo_clean.bv_hd)->b_lblkno >= 0 ||
> +	     TAILQ_FIRST(&bo->bo_clean.bv_hd)->b_lblkno < -2))))
>  		panic("ffs_truncate3");
>  	BO_UNLOCK(bo);
>  #endif /* INVARIANTS */

So I tried to rewrite the assert to be more readable, and noted a thing
which I should have noted much earlier.

The ip->i_din2->di_extsize == 0 test ensures that both extattr blocks
are deallocated.  In other words, even with the new information about
lba of the leaked buffers, the assert is still correct, it catched
stray buffer which should not be there.

Was IO_EXT flag passed to the ffs_truncate() invocation where the
assert ffs_truncate3 fired ?


More information about the freebsd-fs mailing list