From 12552882b1247475adcdec7dc48a8a9258978720 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 13 Nov 2012 15:56:59 -0800 Subject: [PATCH] 3.6-stable patches added patches: xfs-fix-buffer-shudown-reference-count-mismatch.patch xfs-fix-reading-of-wrapped-log-data.patch --- queue-3.6/series | 2 + ...fer-shudown-reference-count-mismatch.patch | 71 +++++++++++++++++++ .../xfs-fix-reading-of-wrapped-log-data.patch | 39 ++++++++++ 3 files changed, 112 insertions(+) create mode 100644 queue-3.6/xfs-fix-buffer-shudown-reference-count-mismatch.patch create mode 100644 queue-3.6/xfs-fix-reading-of-wrapped-log-data.patch diff --git a/queue-3.6/series b/queue-3.6/series index e875195f5ec..5849c87a62b 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -63,3 +63,5 @@ drm-vmwgfx-fix-a-case-where-the-code-would-bug-when-trying-to-pin-gmr-memory.pat drm-radeon-cayman-add-some-missing-regs-to-the-vm-reg-checker.patch drm-radeon-si-add-some-missing-regs-to-the-vm-reg-checker.patch gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch +xfs-fix-reading-of-wrapped-log-data.patch +xfs-fix-buffer-shudown-reference-count-mismatch.patch diff --git a/queue-3.6/xfs-fix-buffer-shudown-reference-count-mismatch.patch b/queue-3.6/xfs-fix-buffer-shudown-reference-count-mismatch.patch new file mode 100644 index 00000000000..8d8346799c1 --- /dev/null +++ b/queue-3.6/xfs-fix-buffer-shudown-reference-count-mismatch.patch @@ -0,0 +1,71 @@ +From 03b1293edad462ad1ad62bcc5160c76758e450d5 Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Fri, 2 Nov 2012 14:23:12 +1100 +Subject: xfs: fix buffer shudown reference count mismatch + +From: Dave Chinner + +commit 03b1293edad462ad1ad62bcc5160c76758e450d5 upstream. + +When we shut down the filesystem, we have to unpin and free all the +buffers currently active in the CIL. To do this we unpin and remove +them in one operation as a result of a failed iclogbuf write. For +buffers, we do this removal via a simultated IO completion of after +marking the buffer stale. + +At the time we do this, we have two references to the buffer - the +active LRU reference and the buf log item. The LRU reference is +removed by marking the buffer stale, and the active CIL reference is +by the xfs_buf_iodone() callback that is run by +xfs_buf_do_callbacks() during ioend processing (via the bp->b_iodone +callback). + +However, ioend processing requires one more reference - that of the +IO that it is completing. We don't have this reference, so we free +the buffer prematurely and use it after it is freed. For buffers +marked with XBF_ASYNC, this leads to assert failures in +xfs_buf_rele() on debug kernels because the b_hold count is zero. + +Fix this by making sure we take the necessary IO reference before +starting IO completion processing on the stale buffer, and set the +XBF_ASYNC flag to ensure that IO completion processing removes all +the active references from the buffer to ensure it is fully torn +down. + +Signed-off-by: Dave Chinner +Reviewed-by: Mark Tinguely +Signed-off-by: Ben Myers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_buf_item.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/fs/xfs/xfs_buf_item.c ++++ b/fs/xfs/xfs_buf_item.c +@@ -526,7 +526,25 @@ xfs_buf_item_unpin( + } + xfs_buf_relse(bp); + } else if (freed && remove) { ++ /* ++ * There are currently two references to the buffer - the active ++ * LRU reference and the buf log item. What we are about to do ++ * here - simulate a failed IO completion - requires 3 ++ * references. ++ * ++ * The LRU reference is removed by the xfs_buf_stale() call. The ++ * buf item reference is removed by the xfs_buf_iodone() ++ * callback that is run by xfs_buf_do_callbacks() during ioend ++ * processing (via the bp->b_iodone callback), and then finally ++ * the ioend processing will drop the IO reference if the buffer ++ * is marked XBF_ASYNC. ++ * ++ * Hence we need to take an additional reference here so that IO ++ * completion processing doesn't free the buffer prematurely. ++ */ + xfs_buf_lock(bp); ++ xfs_buf_hold(bp); ++ bp->b_flags |= XBF_ASYNC; + xfs_buf_ioerror(bp, EIO); + XFS_BUF_UNDONE(bp); + xfs_buf_stale(bp); diff --git a/queue-3.6/xfs-fix-reading-of-wrapped-log-data.patch b/queue-3.6/xfs-fix-reading-of-wrapped-log-data.patch new file mode 100644 index 00000000000..a31d8f30d91 --- /dev/null +++ b/queue-3.6/xfs-fix-reading-of-wrapped-log-data.patch @@ -0,0 +1,39 @@ +From 6ce377afd1755eae5c93410ca9a1121dfead7b87 Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Fri, 2 Nov 2012 11:38:44 +1100 +Subject: xfs: fix reading of wrapped log data + +From: Dave Chinner + +commit 6ce377afd1755eae5c93410ca9a1121dfead7b87 upstream. + +Commit 4439647 ("xfs: reset buffer pointers before freeing them") in +3.0-rc1 introduced a regression when recovering log buffers that +wrapped around the end of log. The second part of the log buffer at +the start of the physical log was being read into the header buffer +rather than the data buffer, and hence recovery was seeing garbage +in the data buffer when it got to the region of the log buffer that +was incorrectly read. + +Reported-by: Torsten Kaiser +Signed-off-by: Dave Chinner +Reviewed-by: Christoph Hellwig +Reviewed-by: Mark Tinguely +Signed-off-by: Ben Myers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_log_recover.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -3541,7 +3541,7 @@ xlog_do_recovery_pass( + * - order is important. + */ + error = xlog_bread_offset(log, 0, +- bblks - split_bblks, hbp, ++ bblks - split_bblks, dbp, + offset + BBTOB(split_bblks)); + if (error) + goto bread_err2; -- 2.47.3