Handle errors from background write of the cylinder group blocks.
authorkib <kib@FreeBSD.org>
Sat, 27 Jun 2015 09:44:14 +0000 (09:44 +0000)
committerkib <kib@FreeBSD.org>
Sat, 27 Jun 2015 09:44:14 +0000 (09:44 +0000)
commit9f65a2d8d999b24bb5d9e9b9dad30a1c98e3f010
treeb314165eb762cbcca7d9865cb7565966fa428720
parent511fb8f89945627d580acd49ab7064c624ebaa62
Handle errors from background write of the cylinder group blocks.

First, on the write error, bufdone() call from ffs_backgroundwrite()
panics because pbrelvp() cleared bp->b_bufobj, while brelse() would
try to re-dirty the copy of the cg buffer.  Handle this by setting
B_INVAL for the case of BIO_ERROR.

Second, we must re-dirty the real buffer containing the cylinder group
block data when background write failed.  Real cg buffer was already
marked clean in ffs_bufwrite(). After the BV_BKGRDINPROG flag is
cleared on the real cg buffer in ffs_backgroundwrite(), buffer scan
may reuse the buffer at any moment. The result is lost write, and if
the write error was only transient, we get corrupted bitmaps.

We cannot re-dirty the original cg buffer in the
ffs_backgroundwritedone(), since the context is not sleepable,
preventing us from sleeping for origbp' lock.  Add BV_BKGDERR flag
(protected by the buffer object lock), which is converted into delayed
write by brelse(), bqrelse() and buffer scan.

In collaboration with: Conrad Meyer <cse.cem@gmail.com>
Reviewed by: mckusick
Sponsored by: The FreeBSD Foundation (kib),
  EMC/Isilon storage division (Conrad)
MFC after: 2 weeks
sys/kern/vfs_bio.c
sys/sys/buf.h
sys/ufs/ffs/ffs_vfsops.c