@@ -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
@@ -1082,7 +1082,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);
@@ -1489,6 +1489,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))
@@ -1497,11 +1498,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);
}
/*
@@ -1618,7 +1624,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);
@@ -3909,15 +3915,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;
+ }
}
@@ -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__ */
@@ -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;
};
/*
@@ -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,
@@ -1357,13 +1357,13 @@ xfs_add_incompat_log_feature(
*/
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;
@@ -1375,9 +1375,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;
}
@@ -546,7 +546,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__ */
@@ -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