Skip to content

Commit 74ad469

Browse files
author
Darrick J. Wong
committed
xfs: fix log recovery when unknown rocompat bits are set
Log recovery has always run on read only mounts, even where the primary superblock advertises unknown rocompat bits. Due to a misunderstanding between Eric and Darrick back in 2018, we accidentally changed the superblock write verifier to shutdown the fs over that exact scenario. As a result, the log cleaning that occurs at the end of the mounting process fails if there are unknown rocompat bits set. As we now allow writing of the superblock if there are unknown rocompat bits set on a RO mount, we no longer want to turn off RO state to allow log recovery to succeed on a RO mount. Hence we also remove all the (now unnecessary) RO state toggling from the log recovery path. Fixes: 9e037cb ("xfs: check for unknown v5 feature bits in superblock write verifier" Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Dave Chinner <[email protected]>
1 parent 76e5890 commit 74ad469

File tree

2 files changed

+2
-18
lines changed

2 files changed

+2
-18
lines changed

fs/xfs/libxfs/xfs_sb.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ xfs_validate_sb_write(
266266
return -EFSCORRUPTED;
267267
}
268268

269-
if (xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
269+
if (!xfs_is_readonly(mp) &&
270+
xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
270271
xfs_alert(mp,
271272
"Corruption detected in superblock read-only compatible features (0x%x)!",
272273
(sbp->sb_features_ro_compat &

fs/xfs/xfs_log.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -715,15 +715,7 @@ xfs_log_mount(
715715
* just worked.
716716
*/
717717
if (!xfs_has_norecovery(mp)) {
718-
/*
719-
* log recovery ignores readonly state and so we need to clear
720-
* mount-based read only state so it can write to disk.
721-
*/
722-
bool readonly = test_and_clear_bit(XFS_OPSTATE_READONLY,
723-
&mp->m_opstate);
724718
error = xlog_recover(log);
725-
if (readonly)
726-
set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
727719
if (error) {
728720
xfs_warn(mp, "log mount/recovery failed: error %d",
729721
error);
@@ -772,20 +764,13 @@ xfs_log_mount_finish(
772764
struct xfs_mount *mp)
773765
{
774766
struct xlog *log = mp->m_log;
775-
bool readonly;
776767
int error = 0;
777768

778769
if (xfs_has_norecovery(mp)) {
779770
ASSERT(xfs_is_readonly(mp));
780771
return 0;
781772
}
782773

783-
/*
784-
* log recovery ignores readonly state and so we need to clear
785-
* mount-based read only state so it can write to disk.
786-
*/
787-
readonly = test_and_clear_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
788-
789774
/*
790775
* During the second phase of log recovery, we need iget and
791776
* iput to behave like they do for an active filesystem.
@@ -835,8 +820,6 @@ xfs_log_mount_finish(
835820
xfs_buftarg_drain(mp->m_ddev_targp);
836821

837822
clear_bit(XLOG_RECOVERY_NEEDED, &log->l_opstate);
838-
if (readonly)
839-
set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
840823

841824
/* Make sure the log is dead if we're returning failure. */
842825
ASSERT(!error || xlog_is_shutdown(log));

0 commit comments

Comments
 (0)