[PATCH 2/3] xfs: don't allow log recovery when unknown rocompat bits are set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Darrick J. Wong <djwong@xxxxxxxxxx>

Don't allow log recovery to proceed on a readonly mount if the primary
superblock advertises unknown rocompat bits.  We used to allow this, but
due to a misunderstanding between Dave and Darrick back in 2016, we
cannot do that anymore.  The XFS_SB_FEAT_RO_COMPAT_RMAPBT feature (4.8)
protects RUI log items, and the REFLINK feature (4.9) protects CUI/BUI
log items, which is why we can't allow older kernels to recover them.

Fixes: b87049444ac4 ("xfs: introduce rmap btree definitions")
Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx>
---
 fs/xfs/xfs_log.c         |   17 -----------------
 fs/xfs/xfs_log_recover.c |   25 +++++++++++++++++++++++++
 2 files changed, 25 insertions(+), 17 deletions(-)


diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 79004d193e54..51c100c86177 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -715,15 +715,7 @@ xfs_log_mount(
 	 * just worked.
 	 */
 	if (!xfs_has_norecovery(mp)) {
-		/*
-		 * log recovery ignores readonly state and so we need to clear
-		 * mount-based read only state so it can write to disk.
-		 */
-		bool	readonly = test_and_clear_bit(XFS_OPSTATE_READONLY,
-						&mp->m_opstate);
 		error = xlog_recover(log);
-		if (readonly)
-			set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
 		if (error) {
 			xfs_warn(mp, "log mount/recovery failed: error %d",
 				error);
@@ -772,7 +764,6 @@ xfs_log_mount_finish(
 	struct xfs_mount	*mp)
 {
 	struct xlog		*log = mp->m_log;
-	bool			readonly;
 	int			error = 0;
 
 	if (xfs_has_norecovery(mp)) {
@@ -780,12 +771,6 @@ xfs_log_mount_finish(
 		return 0;
 	}
 
-	/*
-	 * log recovery ignores readonly state and so we need to clear
-	 * mount-based read only state so it can write to disk.
-	 */
-	readonly = test_and_clear_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
-
 	/*
 	 * During the second phase of log recovery, we need iget and
 	 * iput to behave like they do for an active filesystem.
@@ -835,8 +820,6 @@ xfs_log_mount_finish(
 	xfs_buftarg_drain(mp->m_ddev_targp);
 
 	clear_bit(XLOG_RECOVERY_NEEDED, &log->l_opstate);
-	if (readonly)
-		set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
 
 	/* Make sure the log is dead if we're returning failure. */
 	ASSERT(!error || xlog_is_shutdown(log));
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 82c81d20459d..b4458b7fd6f7 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3354,6 +3354,7 @@ xlog_recover(
 	struct xlog	*log)
 {
 	xfs_daddr_t	head_blk, tail_blk;
+	bool		unknown_rocompat = false;
 	int		error;
 
 	/* find the tail of the log */
@@ -3370,6 +3371,12 @@ xlog_recover(
 	    !xfs_log_check_lsn(log->l_mp, log->l_mp->m_sb.sb_lsn))
 		return -EINVAL;
 
+	/* Detect unknown rocompat features in the superblock */
+	if (xfs_has_crc(log->l_mp) &&
+	    xfs_sb_has_ro_compat_feature(&log->l_mp->m_sb,
+					 XFS_SB_FEAT_RO_COMPAT_UNKNOWN))
+		unknown_rocompat = true;
+
 	if (tail_blk != head_blk) {
 		/* There used to be a comment here:
 		 *
@@ -3407,6 +3414,24 @@ xlog_recover(
 			return -EINVAL;
 		}
 
+		/*
+		 * Don't allow log recovery on a ro mount if there are unknown
+		 * ro compat bits set.  We used to allow this, but BUI/CUI log
+		 * items are protected by the REFLINK rocompat bit so now we
+		 * cannot.
+		 */
+		if (xfs_is_readonly(log->l_mp) && unknown_rocompat) {
+			xfs_alert(log->l_mp,
+"Superblock has unknown read-only compatible features (0x%x) enabled.",
+				 (log->l_mp->m_sb.sb_features_ro_compat &
+						XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
+			xfs_warn(log->l_mp,
+"The log can not be fully and/or safely recovered by this kernel.");
+			xfs_warn(log->l_mp,
+"Please recover the log on a kernel that supports the unknown features.");
+			return -EINVAL;
+		}
+
 		/*
 		 * Delay log recovery if the debug hook is set. This is debug
 		 * instrumentation to coordinate simulation of I/O failures with




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux