diff options
Diffstat (limited to 'xfs.patch')
-rw-r--r-- | xfs.patch | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/xfs.patch b/xfs.patch new file mode 100644 index 000000000000..1020cdcb1e53 --- /dev/null +++ b/xfs.patch @@ -0,0 +1,137 @@ +From: Dave Chinner <david@fromorbit.com> +To: linux-xfs@vger.kernel.org +Cc: xfs@oss.sgi.com +Subject: [PATCH] xfs: quiesce the filesystem after recovery on readonly mount +Date: Fri, 23 Sep 2016 10:11:40 +1000 + +From: Dave Chinner <dchinner@redhat.com> + +Recently we've had a number of reports where log recovery on a v5 +filesystem has reported corruptions that looked to be caused by +recovery being re-run over the top of an already-recovered +metadata. This has uncovered a bug in recovery (fixed elsewhere) +but the vector that caused this was largely unknown. + +A kdump test started tripping over this problem - the system +would be crashed, the kdump kernel and environment would boot and +dump the kernel core image, and then the system would reboot. After +reboot, the root filesystem was triggering log recovery and +corruptions were being detected. The metadumps indicated the above +log recovery issue. + +What is happening is that the kdump kernel and environment is +mounting the root device read-only to find the binaries needed to do +it's work. The result of this is that it is running log recovery. +However, because there were unlinked files and EFIs to be processed +by recovery, the completion of phase 1 of log recovery could not +mark the log clean. And because it's a read-only mount, the unmount +process does not write records to the log to mark it clean, either. +Hence on the next mount of the filesystem, log recovery was run +again across all the metadata that had already been recovered and +this is what triggered corruption warnings. + +To avoid this problem, we need to ensure that a read-only mount +always updates the log when it completes the second phase of +recovery. We already handle this sort of issue with rw->ro remount +transitions, so the solution is as simple as quiescing the +filesystem at the appropriate time during the mount process. This +results in the log being marked clean so the mount behaviour +recorded in the logs on repeated RO mounts will change (i.e. log +recovery will no longer be run on every mount until a RW mount is +done). This is a user visible change in behaviour, but it is +harmless. + +Signed-off-by: Dave Chinner <dchinner@redhat.com> +--- + fs/xfs/xfs_mount.c | 14 ++++++++++++++ + fs/xfs/xfs_super.c | 2 +- + fs/xfs/xfs_super.h | 1 + + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c +index faeead6..56e85a6 100644 +--- a/fs/xfs/xfs_mount.c ++++ b/fs/xfs/xfs_mount.c +@@ -934,6 +934,20 @@ xfs_mountfs( + } + + /* ++ * Now the log is fully replayed, we can transition to full read-only ++ * mode for read-only mounts. This will sync all the metadata and clean ++ * the log so that the recovery we just performed does not have to be ++ * replayed again on the next mount. ++ * ++ * We use the same quiesce mechanism as the rw->ro remount, as they are ++ * semantically identical operations. ++ */ ++ if ((mp->m_flags & (XFS_MOUNT_RDONLY|XFS_MOUNT_NORECOVERY)) == ++ XFS_MOUNT_RDONLY) { ++ xfs_quiesce_attr(mp); ++ } ++ ++ /* + * Complete the quota initialisation, post-log-replay component. + */ + if (quotamount) { +diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c +index 3409753..2d092f9 100644 +--- a/fs/xfs/xfs_super.c ++++ b/fs/xfs/xfs_super.c +@@ -1137,7 +1137,7 @@ xfs_restore_resvblks(struct xfs_mount *mp) + * Note: xfs_log_quiesce() stops background log work - the callers must ensure + * it is started again when appropriate. + */ +-static void ++void + xfs_quiesce_attr( + struct xfs_mount *mp) + { +diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h +index 529bce9..b6418ab 100644 +--- a/fs/xfs/xfs_super.h ++++ b/fs/xfs/xfs_super.h +@@ -61,6 +61,7 @@ struct xfs_mount; + struct xfs_buftarg; + struct block_device; + ++extern void xfs_quiesce_attr(struct xfs_mount *mp); + extern void xfs_flush_inodes(struct xfs_mount *mp); + extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); + extern xfs_agnumber_t xfs_set_inode_alloc(struct xfs_mount *, +From: Eryu Guan <eguan@redhat.com> +To: linux-xfs@vger.kernel.org +Cc: xfs@oss.sgi.com, Eryu Guan <eguan@redhat.com> +Subject: [PATCH v2] xfs: undo block reservation correctly in xfs_trans_reserve() +Date: Tue, 6 Sep 2016 20:14:40 +0800 + +"blocks" should be added back to fdblocks at undo time, not taken +away, i.e. the minus sign should not be used. + +This is a regression introduced by commit 0d485ada404b ("xfs: use +generic percpu counters for free block counter"). And it's found by +code inspection, I didn't it in real world, so there's no +reproducer. + +Signed-off-by: Eryu Guan <eguan@redhat.com> +--- +v2: +- Remove "Fixes:" tag and describe relevant commit in commit log +- Update commit log to mention that it's found by code inspection +- Remove outer () from the "int64_t" cast + + fs/xfs/xfs_trans.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c +index 5f3d33d..836eb80 100644 +--- a/fs/xfs/xfs_trans.c ++++ b/fs/xfs/xfs_trans.c +@@ -217,7 +217,7 @@ undo_log: + + undo_blocks: + if (blocks > 0) { +- xfs_mod_fdblocks(tp->t_mountp, -((int64_t)blocks), rsvd); ++ xfs_mod_fdblocks(tp->t_mountp, (int64_t)blocks, rsvd); + tp->t_blk_res = 0; + } + |