+From: Dave Chinner <dchinner@redhat.com>\r
+\r
+If inode_item_done() fails to flush an inode after we've grabbed a\r
+reference to the underlying buffer during a transaction commit, we\r
+fail to put the buffer and hence leak it. We then deadlock on the\r
+next lookup ofthe inode buffer as it is still locked and no-one owns\r
+it.\r
+\r
+To fix it, put the buffer on error so that it gets unlocked and\r
+can be recovered appropriately in a later phase of repair.\r
+\r
+Reported-by: Arkadiusz Miskiewicz <arekm@maven.pl>\r
+Fixes: d15188a1ec14 ("xfs: rework the inline directory verifiers")\r
+Signed-off-by: Dave Chinner <dchinner@redhat.com>\r
+---\r
+ libxfs/trans.c | 17 +++++++++++++----\r
+ 1 file changed, 13 insertions(+), 4 deletions(-)\r
+\r
+diff --git a/libxfs/trans.c b/libxfs/trans.c\r
+index 46ff8b4ae798..10a35dd47b01 100644\r
+--- a/libxfs/trans.c\r
++++ b/libxfs/trans.c\r
+@@ -824,8 +824,10 @@ _("Transaction block reservation exceeded! %u > %u\n"),\r
+ \r
+ /*\r
+ * Transaction commital code follows (i.e. write to disk in libxfs)\r
++ *\r
++ * XXX (dgc): should failure to flush the inode (e.g. due to uncorrected\r
++ * corruption) result in transaction commit failure w/ EFSCORRUPTED?\r
+ */\r
+-\r
+ static void\r
+ inode_item_done(\r
+ xfs_inode_log_item_t *iip)\r
+@@ -856,17 +858,24 @@ inode_item_done(\r
+ return;\r
+ }\r
+ \r
++ /*\r
++ * Flush the inode and disassociate it from the transaction regardless\r
++ * of whether the flush succeed or not. If we fail the flush, make sure\r
++ * we still release the buffer reference we currently hold.\r
++ */\r
+ bp->b_log_item = iip;\r
+ error = libxfs_iflush_int(ip, bp);\r
++ ip->i_transp = NULL; /* disassociate from transaction */\r
++ bp->b_log_item = NULL; /* remove log item */\r
++ bp->b_transp = NULL; /* remove xact ptr */\r
++\r
+ if (error) {\r
+ fprintf(stderr, _("%s: warning - iflush_int failed (%d)\n"),\r
+ progname, error);\r
++ libxfs_putbuf(bp);\r
+ return;\r
+ }\r
+ \r
+- ip->i_transp = NULL; /* disassociate from transaction */\r
+- bp->b_log_item = NULL; /* remove log item */\r
+- bp->b_transp = NULL; /* remove xact ptr */\r
+ libxfs_writebuf(bp, 0);\r
+ #ifdef XACT_DEBUG\r
+ fprintf(stderr, "flushing dirty inode %llu, buffer %p\n",\r
+-- \r
+2.20.1\r
+\r