DragonFlyBSD Kernel Audit
DF-2644 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/hammer2/hammer2_flush.c	
+++ b/sys/vfs/hammer2/hammer2_flush.c	
@@ -1328,10 +1328,19 @@
 			 */
 			if (chain->parent)
 				hammer2_chain_setflush(chain->parent);
-			hammer2_flush(chain, xflags);
+			flush_error |= hammer2_flush(chain, xflags);
 
 			/* XXX cluster */
-			if (ip == pmp->iroot && pmp != hmp->spmp) {
+			/*
+			 * DF-2644: an error'd chain has chain->data == NULL
+			 * (the data load failed inside the RESOLVE_ALWAYS
+			 * lock taken by hammer2_inode_chain()).  Do not
+			 * dereference chain->data here; flush_core() has
+			 * already reported the error, so propagate it and
+			 * keep the (stale) cached blockset.
+			 */
+			if (ip == pmp->iroot && pmp != hmp->spmp &&
+			    chain->error == 0 && chain->data != NULL) {
 				hammer2_spin_ex(&pmp->blockset_spin);
 				pmp->pfs_iroot_blocksets[clindex] =
 					chain->data->ipdata.u.blockset;