From a6cb16e5f888a25da9c36191874fd73fb891b99e Mon Sep 17 00:00:00 2001 From: beck Date: Wed, 13 Dec 2017 16:38:34 +0000 Subject: [PATCH] Fix a softdep bug exposed by our recent changes to make reboot drop to read-only The deadlock happens when softdep gets the same buffer in the BMSAFEMAP case that it already called getdirtybuf() on and made busy at the top of the loop. when this is the case, skip the BMSAFEMAP case and simply write the buffer out at the bottom of the loop as always. This avoids calling getdirtybuf() a second time on the same buffer we already took for exclusive use ourself and have not yet written out. While I'm in here add a KASSERT for the similar case above, which I don't think can happen but we would deadlock in the same way if it does. testing by and ok bluhm@ --- sys/ufs/ffs/ffs_softdep.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 5da4c6217a2..f98dcd25286 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ffs_softdep.c,v 1.136 2017/10/10 11:59:35 bluhm Exp $ */ +/* $OpenBSD: ffs_softdep.c,v 1.137 2017/12/13 16:38:34 beck Exp $ */ /* * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved. @@ -4850,6 +4850,7 @@ loop: * rather than panic, just flush it. */ nbp = WK_MKDIR(wk)->md_buf; + KASSERT(bp != nbp); gotit = getdirtybuf(nbp, waitfor); if (gotit == 0) break; @@ -4874,6 +4875,8 @@ loop: * rather than panic, just flush it. */ nbp = WK_BMSAFEMAP(wk)->sm_buf; + if (bp == nbp) + break; gotit = getdirtybuf(nbp, waitfor); if (gotit == 0) break; -- 2.20.1