From: Allison Henderson <allison.henderson@oracle.com>
To: "Darrick J. Wong" <djwong@kernel.org>
Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-api@vger.kernel.org
Subject: Re: [PATCH 03/18] xfs: allow setting and clearing of log incompat feature flags
Date: Fri, 2 Apr 2021 16:20:47 -0700 [thread overview]
Message-ID: <496a3d16-f53d-96f9-5fcd-cef5d03b2487@oracle.com> (raw)
In-Reply-To: <161723934343.3149451.16679733325094950568.stgit@magnolia>
On 3/31/21 6:09 PM, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> Log incompat feature flags in the superblock exist for one purpose: to
> protect the contents of a dirty log from replay on a kernel that isn't
> prepared to handle those dirty contents. This means that they can be
> cleared if (a) we know the log is clean and (b) we know that there
> aren't any other threads in the system that might be setting or relying
> upon a log incompat flag.
>
> Therefore, clear the log incompat flags when we've finished recovering
> the log, when we're unmounting cleanly, remounting read-only, or
> freezing; and provide a function so that subsequent patches can start
> using this.
>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Ok, seems reasonable
Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
> ---
> fs/xfs/libxfs/xfs_format.h | 15 ++++++
> fs/xfs/xfs_log.c | 14 ++++++
> fs/xfs/xfs_log_recover.c | 16 ++++++
> fs/xfs/xfs_mount.c | 110 ++++++++++++++++++++++++++++++++++++++++++++
> fs/xfs/xfs_mount.h | 2 +
> 5 files changed, 157 insertions(+)
>
>
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index 9620795a6e08..7e9c964772c9 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -495,6 +495,21 @@ xfs_sb_has_incompat_log_feature(
> return (sbp->sb_features_log_incompat & feature) != 0;
> }
>
> +static inline void
> +xfs_sb_remove_incompat_log_features(
> + struct xfs_sb *sbp)
> +{
> + sbp->sb_features_log_incompat &= ~XFS_SB_FEAT_INCOMPAT_LOG_ALL;
> +}
> +
> +static inline void
> +xfs_sb_add_incompat_log_features(
> + struct xfs_sb *sbp,
> + unsigned int features)
> +{
> + sbp->sb_features_log_incompat |= features;
> +}
> +
> /*
> * V5 superblock specific feature checks
> */
> diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
> index 06041834daa3..cf73bc9f4d18 100644
> --- a/fs/xfs/xfs_log.c
> +++ b/fs/xfs/xfs_log.c
> @@ -945,6 +945,20 @@ int
> xfs_log_quiesce(
> struct xfs_mount *mp)
> {
> + /*
> + * Clear log incompat features since we're quiescing the log. Report
> + * 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)) {
> + int error;
> +
> + error = xfs_sync_sb(mp, false);
> + if (error)
> + xfs_warn(mp,
> + "Failed to clear log incompat features on quiesce");
> + }
> +
> cancel_delayed_work_sync(&mp->m_log->l_work);
> xfs_log_force(mp, XFS_LOG_SYNC);
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index ce1a7928eb2d..fdba9b55822e 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -3480,6 +3480,22 @@ xlog_recover_finish(
> */
> xfs_log_force(log->l_mp, XFS_LOG_SYNC);
>
> + /*
> + * Now that we've recovered the log and all the intents, we can
> + * clear the log incompat feature bits in the superblock
> + * because there's no 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)) {
> + error = xfs_sync_sb(log->l_mp, false);
> + if (error < 0) {
> + xfs_alert(log->l_mp,
> + "Failed to clear log incompat features on recovery");
> + return error;
> + }
> + }
> +
> xlog_recover_process_iunlinks(log);
>
> xlog_recover_check_summary(log);
> diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
> index b7e653180d22..f16036e1986b 100644
> --- a/fs/xfs/xfs_mount.c
> +++ b/fs/xfs/xfs_mount.c
> @@ -1333,6 +1333,116 @@ xfs_force_summary_recalc(
> xfs_fs_mark_checked(mp, XFS_SICK_FS_COUNTERS);
> }
>
> +/*
> + * Enable a log incompat feature flag in the primary superblock. The caller
> + * cannot have any other transactions in progress.
> + */
> +int
> +xfs_add_incompat_log_feature(
> + struct xfs_mount *mp,
> + uint32_t feature)
> +{
> + struct xfs_dsb *dsb;
> + int error;
> +
> + ASSERT(hweight32(feature) == 1);
> + ASSERT(!(feature & XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN));
> +
> + /*
> + * Force the log to disk and kick the background AIL thread to reduce
> + * the chances that the bwrite will stall waiting for the AIL to unpin
> + * the primary superblock buffer. This isn't a data integrity
> + * operation, so we don't need a synchronous push.
> + */
> + error = xfs_log_force(mp, XFS_LOG_SYNC);
> + if (error)
> + return error;
> + xfs_ail_push_all(mp->m_ail);
> +
> + /*
> + * Lock the primary superblock buffer to serialize all callers that
> + * are trying to set feature bits.
> + */
> + xfs_buf_lock(mp->m_sb_bp);
> + xfs_buf_hold(mp->m_sb_bp);
> +
> + if (XFS_FORCED_SHUTDOWN(mp)) {
> + error = -EIO;
> + goto rele;
> + }
> +
> + if (xfs_sb_has_incompat_log_feature(&mp->m_sb, feature))
> + goto rele;
> +
> + /*
> + * Write the primary superblock to disk immediately, because we need
> + * the log_incompat bit to be set in the primary super now to protect
> + * the log items that we're going to commit later.
> + */
> + dsb = mp->m_sb_bp->b_addr;
> + xfs_sb_to_disk(dsb, &mp->m_sb);
> + dsb->sb_features_log_incompat |= cpu_to_be32(feature);
> + error = xfs_bwrite(mp->m_sb_bp);
> + if (error)
> + goto shutdown;
> +
> + /*
> + * Add the feature bits to the incore superblock before we unlock the
> + * buffer.
> + */
> + xfs_sb_add_incompat_log_features(&mp->m_sb, feature);
> + xfs_buf_relse(mp->m_sb_bp);
> +
> + /* Log the superblock to disk. */
> + return xfs_sync_sb(mp, false);
> +shutdown:
> + xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
> +rele:
> + xfs_buf_relse(mp->m_sb_bp);
> + return error;
> +}
> +
> +/*
> + * Clear all the log incompat flags from the superblock.
> + *
> + * The caller cannot be in a transaction, must ensure that the log does not
> + * contain any log items protected by any log incompat bit, and must ensure
> + * that there are no other threads that depend on the state of the log incompat
> + * feature flags in the primary super.
> + *
> + * Returns true if the superblock is dirty.
> + */
> +bool
> +xfs_clear_incompat_log_features(
> + struct xfs_mount *mp)
> +{
> + bool ret = false;
> +
> + if (!xfs_sb_version_hascrc(&mp->m_sb) ||
> + !xfs_sb_has_incompat_log_feature(&mp->m_sb,
> + XFS_SB_FEAT_INCOMPAT_LOG_ALL) ||
> + XFS_FORCED_SHUTDOWN(mp))
> + return false;
> +
> + /*
> + * Update the incore superblock. We synchronize on the primary super
> + * buffer lock to be consistent with the add function, though at least
> + * in theory this shouldn't be necessary.
> + */
> + 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_info(mp, "Clearing log incompat feature flags.");
> + xfs_sb_remove_incompat_log_features(&mp->m_sb);
> + ret = true;
> + }
> +
> + xfs_buf_relse(mp->m_sb_bp);
> + return ret;
> +}
> +
> /*
> * Update the in-core delayed block counter.
> *
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 63d0dc1b798d..eb45684b186a 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -453,6 +453,8 @@ int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb,
> 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);
> void xfs_mod_delalloc(struct xfs_mount *mp, int64_t delta);
>
> void xfs_hook_init(struct xfs_hook_chain *chain);
>
next prev parent reply other threads:[~2021-04-02 23:20 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-01 1:08 [PATCHSET RFC v3 00/18] xfs: atomic file updates Darrick J. Wong
2021-04-01 1:08 ` [PATCH 01/18] vfs: introduce new file range exchange ioctl Darrick J. Wong
2021-04-01 1:44 ` Al Viro
2021-04-01 21:18 ` Darrick J. Wong
2021-04-01 3:32 ` Amir Goldstein
2021-04-02 0:37 ` Darrick J. Wong
2021-04-01 1:08 ` [PATCH 02/18] xfs: support two inodes in the defer capture structure Darrick J. Wong
2021-04-02 23:20 ` Allison Henderson
2021-04-01 1:09 ` [PATCH 03/18] xfs: allow setting and clearing of log incompat feature flags Darrick J. Wong
2021-04-02 23:20 ` Allison Henderson [this message]
2021-04-01 1:09 ` [PATCH 04/18] xfs: clear log incompat feature bits when the log is idle Darrick J. Wong
2021-04-02 23:20 ` Allison Henderson
2021-04-01 1:09 ` [PATCH 05/18] xfs: create a log incompat flag for atomic extent swapping Darrick J. Wong
2021-04-02 23:21 ` Allison Henderson
2021-04-01 1:09 ` [PATCH 06/18] xfs: introduce a swap-extent log intent item Darrick J. Wong
2021-04-05 23:08 ` Allison Henderson
2021-04-01 1:09 ` [PATCH 07/18] xfs: create deferred log items for extent swapping Darrick J. Wong
2021-04-01 1:09 ` [PATCH 08/18] xfs: add a ->xchg_file_range handler Darrick J. Wong
2021-04-01 1:09 ` [PATCH 09/18] xfs: add error injection to test swapext recovery Darrick J. Wong
2021-04-01 1:09 ` [PATCH 10/18] xfs: port xfs_swap_extents_rmap to our new code Darrick J. Wong
2021-04-01 1:09 ` [PATCH 11/18] xfs: consolidate all of the xfs_swap_extent_forks code Darrick J. Wong
2021-04-01 1:09 ` [PATCH 12/18] xfs: refactor reflink flag handling in xfs_swap_extent_forks Darrick J. Wong
2021-04-01 1:09 ` [PATCH 13/18] xfs: allow xfs_swap_range to use older extent swap algorithms Darrick J. Wong
2021-04-01 1:10 ` [PATCH 14/18] xfs: remove old swap extents implementation Darrick J. Wong
2021-04-01 1:10 ` [PATCH 15/18] xfs: condense extended attributes after an atomic swap Darrick J. Wong
2021-04-01 1:10 ` [PATCH 16/18] xfs: condense directories " Darrick J. Wong
2021-04-01 1:10 ` [PATCH 17/18] xfs: make atomic extent swapping support realtime files Darrick J. Wong
2021-04-01 1:10 ` [PATCH 18/18] xfs: enable atomic swapext feature Darrick J. Wong
2021-04-01 3:56 ` [PATCHSET RFC v3 00/18] xfs: atomic file updates Amir Goldstein
2021-04-02 0:22 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=496a3d16-f53d-96f9-5fcd-cef5d03b2487@oracle.com \
--to=allison.henderson@oracle.com \
--cc=djwong@kernel.org \
--cc=linux-api@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).