diff options
author | Darrick J. Wong <djwong@kernel.org> | 2022-07-28 11:45:14 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2022-10-14 14:16:50 -0700 |
commit | 53e4f929abcec6f199aa67539c4aa1799320b657 (patch) | |
tree | 175ab053ac06c0d426a7b9b9d7fd032cb21ce024 /fs | |
parent | 021348feb8f7d8793a3316d5596d6534698c69be (diff) |
xfs: parameterize all the incompat log feature helpers
We're about to define a new XFS_SB_FEAT_INCOMPAT_LOG_ bit, which means
that callers will soon require the ability to toggle on and off
different log incompat feature bits. Parameterize the
xlog_{use,drop}_incompat_feat and xfs_sb_remove_incompat_log_features
functions so that callers can specify which feature they're trying to
use and so that we can clear individual log incompat bits as needed.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/libxfs/xfs_format.h | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 34 | ||||
-rw-r--r-- | fs/xfs/xfs_log.h | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_log_priv.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_xattr.c | 6 |
8 files changed, 46 insertions, 26 deletions
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index fb775597b48c..dd3f7a0f6999 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -404,9 +404,10 @@ xfs_sb_has_incompat_log_feature( static inline void xfs_sb_remove_incompat_log_features( - struct xfs_sb *sbp) + struct xfs_sb *sbp, + uint32_t feature) { - sbp->sb_features_log_incompat &= ~XFS_SB_FEAT_INCOMPAT_LOG_ALL; + sbp->sb_features_log_incompat &= ~feature; } static inline void diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 267bfe002e8a..525367567feb 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1063,7 +1063,7 @@ xfs_log_quiesce( * failures, though it's not fatal to have a higher log feature * protection level than the log contents actually require. */ - if (xfs_clear_incompat_log_features(mp)) { + if (xfs_clear_incompat_log_features(mp, XFS_SB_FEAT_INCOMPAT_LOG_ALL)) { int error; error = xfs_sync_sb(mp, false); @@ -1462,6 +1462,7 @@ xlog_clear_incompat( struct xlog *log) { struct xfs_mount *mp = log->l_mp; + uint32_t incompat_mask = 0; if (!xfs_sb_has_incompat_log_feature(&mp->m_sb, XFS_SB_FEAT_INCOMPAT_LOG_ALL)) @@ -1470,11 +1471,16 @@ xlog_clear_incompat( if (log->l_covered_state != XLOG_STATE_COVER_DONE2) return; - if (!down_write_trylock(&log->l_incompat_users)) + if (down_write_trylock(&log->l_incompat_xattrs)) + incompat_mask |= XFS_SB_FEAT_INCOMPAT_LOG_XATTRS; + + if (!incompat_mask) return; - xfs_clear_incompat_log_features(mp); - up_write(&log->l_incompat_users); + xfs_clear_incompat_log_features(mp, incompat_mask); + + if (incompat_mask & XFS_SB_FEAT_INCOMPAT_LOG_XATTRS) + up_write(&log->l_incompat_xattrs); } /* @@ -1591,7 +1597,7 @@ xlog_alloc_log( } log->l_sectBBsize = 1 << log2_size; - init_rwsem(&log->l_incompat_users); + init_rwsem(&log->l_incompat_xattrs); xlog_get_iclog_buffer_size(mp, log); @@ -3893,15 +3899,25 @@ xfs_log_check_lsn( */ void xlog_use_incompat_feat( - struct xlog *log) + struct xlog *log, + enum xlog_incompat_feat what) { - down_read(&log->l_incompat_users); + switch (what) { + case XLOG_INCOMPAT_FEAT_XATTRS: + down_read(&log->l_incompat_xattrs); + break; + } } /* Notify the log that we've finished using log incompat features. */ void xlog_drop_incompat_feat( - struct xlog *log) + struct xlog *log, + enum xlog_incompat_feat what) { - up_read(&log->l_incompat_users); + switch (what) { + case XLOG_INCOMPAT_FEAT_XATTRS: + up_read(&log->l_incompat_xattrs); + break; + } } diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 2728886c2963..d187f6445909 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h @@ -159,8 +159,11 @@ bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t); xfs_lsn_t xlog_grant_push_threshold(struct xlog *log, int need_bytes); bool xlog_force_shutdown(struct xlog *log, uint32_t shutdown_flags); -void xlog_use_incompat_feat(struct xlog *log); -void xlog_drop_incompat_feat(struct xlog *log); -int xfs_attr_use_log_assist(struct xfs_mount *mp); +enum xlog_incompat_feat { + XLOG_INCOMPAT_FEAT_XATTRS = XFS_SB_FEAT_INCOMPAT_LOG_XATTRS, +}; + +void xlog_use_incompat_feat(struct xlog *log, enum xlog_incompat_feat what); +void xlog_drop_incompat_feat(struct xlog *log, enum xlog_incompat_feat what); #endif /* __XFS_LOG_H__ */ diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 1bd2963e8fbd..a13b5b6b744d 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -447,7 +447,7 @@ struct xlog { uint32_t l_iclog_roundoff;/* padding roundoff */ /* Users of log incompat features should take a read lock. */ - struct rw_semaphore l_incompat_users; + struct rw_semaphore l_incompat_xattrs; }; /* diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 6b1f37bc3e95..81ce08c23306 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3473,7 +3473,8 @@ xlog_recover_finish( * longer anything to protect. We rely on the AIL push to write out the * updated superblock after everything else. */ - if (xfs_clear_incompat_log_features(log->l_mp)) { + if (xfs_clear_incompat_log_features(log->l_mp, + XFS_SB_FEAT_INCOMPAT_LOG_ALL)) { error = xfs_sync_sb(log->l_mp, false); if (error < 0) { xfs_alert(log->l_mp, diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index eff72f0ff0a2..dea83d7f1eb1 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1340,13 +1340,13 @@ rele: */ bool xfs_clear_incompat_log_features( - struct xfs_mount *mp) + struct xfs_mount *mp, + uint32_t features) { bool ret = false; if (!xfs_has_crc(mp) || - !xfs_sb_has_incompat_log_feature(&mp->m_sb, - XFS_SB_FEAT_INCOMPAT_LOG_ALL) || + !xfs_sb_has_incompat_log_feature(&mp->m_sb, features) || xfs_is_shutdown(mp)) return false; @@ -1358,9 +1358,8 @@ xfs_clear_incompat_log_features( xfs_buf_lock(mp->m_sb_bp); xfs_buf_hold(mp->m_sb_bp); - if (xfs_sb_has_incompat_log_feature(&mp->m_sb, - XFS_SB_FEAT_INCOMPAT_LOG_ALL)) { - xfs_sb_remove_incompat_log_features(&mp->m_sb); + if (xfs_sb_has_incompat_log_feature(&mp->m_sb, features)) { + xfs_sb_remove_incompat_log_features(&mp->m_sb, features); ret = true; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 07b357bcf9f3..72180636072f 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -674,7 +674,7 @@ struct xfs_error_cfg * xfs_error_get_cfg(struct xfs_mount *mp, int error_class, int error); void xfs_force_summary_recalc(struct xfs_mount *mp); int xfs_add_incompat_log_feature(struct xfs_mount *mp, uint32_t feature); -bool xfs_clear_incompat_log_features(struct xfs_mount *mp); +bool xfs_clear_incompat_log_features(struct xfs_mount *mp, uint32_t feature); void xfs_mod_delalloc(struct xfs_mount *mp, int64_t delta); #endif /* __XFS_MOUNT_H__ */ diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c325a28b89a8..3694b88cfe31 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -37,7 +37,7 @@ xfs_attr_grab_log_assist( * Protect ourselves from an idle log clearing the logged xattrs log * incompat feature bit. */ - xlog_use_incompat_feat(mp->m_log); + xlog_use_incompat_feat(mp->m_log, XLOG_INCOMPAT_FEAT_XATTRS); /* * If log-assisted xattrs are already enabled, the caller can use the @@ -57,7 +57,7 @@ xfs_attr_grab_log_assist( return 0; drop_incompat: - xlog_drop_incompat_feat(mp->m_log); + xlog_drop_incompat_feat(mp->m_log, XLOG_INCOMPAT_FEAT_XATTRS); return error; } @@ -65,7 +65,7 @@ static inline void xfs_attr_rele_log_assist( struct xfs_mount *mp) { - xlog_drop_incompat_feat(mp->m_log); + xlog_drop_incompat_feat(mp->m_log, XLOG_INCOMPAT_FEAT_XATTRS); } static inline bool |