@@ -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);
@@ -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.
@@ -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;
}