From e1ef4c29a34eea3c1e8f026d0310924fa8b57d0b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 8 Oct 2020 22:41:02 +0000 Subject: [PATCH] Do not leak B_BARRIER. Normally when a buffer with B_BARRIER is written, the flag is cleared by g_vfs_strategy() when creating bio. But in some cases FFS buffer might not reach g_vfs_strategy(), for instance when copy-on-write reports an error like ENOSPC. In this case buffer is returned to dirty queue and might be written later by other means. Among then bdwrite() reasonably asserts that B_BARRIER is not set. In fact, the only current use of B_BARRIER is for lazy inode block initialization, where write of the new inode block is fenced against cylinder group write to mark inode as used. The situation could be seen that we break dependency by updating cg without written out inode. Practically since CoW was not able to find space for a copy of inode block, for the same reason cg group block write should fail. Reported by: pho Discussed with: chs, imp, mckusick Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D26511 --- sys/ufs/ffs/ffs_vfsops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 5718eabf1c8..2a997c2a390 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -2582,6 +2582,7 @@ ffs_geom_strategy(struct bufobj *bo, struct buf *bp) error != EOPNOTSUPP) { bp->b_error = error; bp->b_ioflags |= BIO_ERROR; + bp->b_flags &= ~B_BARRIER; bufdone(bp); return; } @@ -2594,6 +2595,7 @@ ffs_geom_strategy(struct bufobj *bo, struct buf *bp) if (error != 0 && error != EOPNOTSUPP) { bp->b_error = error; bp->b_ioflags |= BIO_ERROR; + bp->b_flags &= ~B_BARRIER; bufdone(bp); return; }