[PATCH 3/3] xfs: log is not writable if we have unknown rocompat features

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

 



From: Darrick J. Wong <djwong@xxxxxxxxxx>

Ever since commit 9e037cb7972f, the superblock write verifier will trip
if someone tries to write a superblock with unknown rocompat features.
However, we allow ro mounts of a filesystem with unknown rocompat
features if the log is clean, except that has been broken for years
because the end of an ro mount cleans the log, which logs and writes the
superblock.

Therefore, don't allow log writes to happen if there are unknown
rocompat features set.

Fixes: 9e037cb7972f ("xfs: check for unknown v5 feature bits in superblock write verifier")
Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx>
---
 fs/xfs/xfs_log.c         |    6 ++++++
 fs/xfs/xfs_log_priv.h    |    7 +++++++
 fs/xfs/xfs_log_recover.c |    7 +++++++
 3 files changed, 20 insertions(+)


diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 51c100c86177..c1bbc8040bcb 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -391,6 +391,8 @@ xfs_log_writable(
 		return false;
 	if (xlog_is_shutdown(mp->m_log))
 		return false;
+	if (xlog_is_readonly(mp->m_log))
+		return false;
 	return true;
 }
 
@@ -408,6 +410,8 @@ xfs_log_regrant(
 
 	if (xlog_is_shutdown(log))
 		return -EIO;
+	if (xlog_is_readonly(log))
+		return -EROFS;
 
 	XFS_STATS_INC(mp, xs_try_logspace);
 
@@ -471,6 +475,8 @@ xfs_log_reserve(
 
 	if (xlog_is_shutdown(log))
 		return -EIO;
+	if (xlog_is_readonly(log))
+		return -EROFS;
 
 	XFS_STATS_INC(mp, xs_try_logspace);
 
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index af87648331d5..14892e01de38 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -461,6 +461,7 @@ struct xlog {
 #define XLOG_IO_ERROR		2	/* log hit an I/O error, and being
 				   shutdown */
 #define XLOG_TAIL_WARN		3	/* log tail verify warning issued */
+#define XLOG_READONLY		4	/* cannot write to the log */
 
 static inline bool
 xlog_recovery_needed(struct xlog *log)
@@ -480,6 +481,12 @@ xlog_is_shutdown(struct xlog *log)
 	return test_bit(XLOG_IO_ERROR, &log->l_opstate);
 }
 
+static inline bool
+xlog_is_readonly(struct xlog *log)
+{
+	return test_bit(XLOG_READONLY, &log->l_opstate);
+}
+
 /*
  * Wait until the xlog_force_shutdown() has marked the log as shut down
  * so xlog_is_shutdown() will always return true.
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index b4458b7fd6f7..f8f13d5f79cd 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3450,6 +3450,13 @@ xlog_recover(
 
 		error = xlog_do_recover(log, head_blk, tail_blk);
 		set_bit(XLOG_RECOVERY_NEEDED, &log->l_opstate);
+	} else if (unknown_rocompat) {
+		/*
+		 * Log recovery wasn't needed, but if the superblock has
+		 * unknown rocompat features, don't allow log writes at all
+		 * because the sb write verifier will trip.
+		 */
+		set_bit(XLOG_READONLY, &log->l_opstate);
 	}
 	return error;
 }




[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