On Wed, Jun 03, 2015 at 04:04:42PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@xxxxxxxxxx>
>
> Add new per-ag rmap btree definitions to the per-ag structures. The
> rmap btree will sit inthe empty slots on disk after the free space
> btrees, and hence form a part of the array of space management
> btrees. This requires the definition of the btree to be contiguous
> with the free space btrees.
>
> Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
> ---
> fs/xfs/libxfs/xfs_alloc.c | 6 ++++++
> fs/xfs/libxfs/xfs_btree.c | 4 ++--
> fs/xfs/libxfs/xfs_btree.h | 3 +++
> fs/xfs/libxfs/xfs_format.h | 22 +++++++++++++++++-----
> fs/xfs/libxfs/xfs_types.h | 4 ++--
> 5 files changed, 30 insertions(+), 9 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index d4aa844..c7206b5 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -2267,6 +2267,10 @@ xfs_agf_verify(
> be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS)
> return false;
>
> + if (xfs_sb_version_hasrmapbt(&mp->m_sb) &&
> + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS)
> + return false;
> +
> /*
> * during growfs operations, the perag is not fully initialised,
> * so we can't use it for any useful checking. growfs ensures we can't
> @@ -2397,6 +2401,8 @@ xfs_alloc_read_agf(
> be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
> pag->pagf_levels[XFS_BTNUM_CNTi] =
> be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
> + pag->pagf_levels[XFS_BTNUM_RMAPi] =
> + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
> spin_lock_init(&pag->pagb_lock);
> pag->pagb_count = 0;
> pag->pagb_tree = RB_ROOT;
> diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
> index c72283d..0426152 100644
> --- a/fs/xfs/libxfs/xfs_btree.c
> +++ b/fs/xfs/libxfs/xfs_btree.c
> @@ -42,9 +42,9 @@ kmem_zone_t *xfs_btree_cur_zone;
> * Btree magic numbers.
> */
> static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = {
> - { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC,
> + { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, 0, XFS_BMAP_MAGIC, XFS_IBT_MAGIC,
> XFS_FIBT_MAGIC },
> - { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC,
> + { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, XFS_RMAP_CRC_MAGIC,
> XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC }
> };
> #define xfs_btree_magic(cur) \
> diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h
> index 8f18bab..ace1995 100644
> --- a/fs/xfs/libxfs/xfs_btree.h
> +++ b/fs/xfs/libxfs/xfs_btree.h
> @@ -63,6 +63,7 @@ union xfs_btree_rec {
> #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi)
> #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi)
> #define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi)
> +#define XFS_BTNUM_RMAP ((xfs_btnum_t)XFS_BTNUM_RMAPi)
>
> /*
> * For logging record fields.
> @@ -94,6 +95,7 @@ do { \
> case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \
> case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \
> case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \
> + case XFS_BTNUM_RMAP: break; \
Hmm, so we don't have to provide stats for all the btrees?
<shrug> Actually, I thought it was rather clever that one could grep
/proc/fs/xfs/stat for 'rlbt' to find out if the running xfs driver supports
reflink.
(Not that I want someone to think this is some kind of ABI...)
> case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
> } \
> } while (0)
> @@ -108,6 +110,7 @@ do { \
> case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \
> case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \
> case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \
> + case XFS_BTNUM_RMAP: break; \
> case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
> } \
> } while (0)
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index a0ae572..d120af4 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -445,6 +445,7 @@ xfs_sb_has_compat_feature(
> }
>
> #define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode
> btree */
> +#define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map
> btree */
> #define XFS_SB_FEAT_RO_COMPAT_ALL \
> (XFS_SB_FEAT_RO_COMPAT_FINOBT)
... | XFS_SB_FEAT_RO_COMPAT_RMAPBT) ?
(/me shifts the reflink feature flag to (1 << 2))
> #define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL
> @@ -514,6 +515,12 @@ static inline bool xfs_sb_version_hassparseinodes(struct
> xfs_sb *sbp)
> xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_SPINODES);
> }
>
> +static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp)
> +{
> + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
> + (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT);
> +}
> +
> /*
> * end of superblock version macros
> */
> @@ -574,10 +581,10 @@ xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
> #define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION)
>
> /*
> - * Btree number 0 is bno, 1 is cnt. This value gives the size of the
> + * Btree number 0 is bno, 1 is cnt, 2 is rmap. This value gives the size of
> the
> * arrays below.
> */
> -#define XFS_BTNUM_AGF ((int)XFS_BTNUM_CNTi + 1)
> +#define XFS_BTNUM_AGF ((int)XFS_BTNUM_RMAPi + 1)
>
> /*
> * The second word of agf_levels in the first a.g. overlaps the EFS
> @@ -594,12 +601,10 @@ typedef struct xfs_agf {
> __be32 agf_seqno; /* sequence # starting from 0 */
> __be32 agf_length; /* size in blocks of a.g. */
> /*
> - * Freespace information
> + * Freespace and rmap information
> */
> __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */
> - __be32 agf_spare0; /* spare field */
> __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */
> - __be32 agf_spare1; /* spare field */
Doh, field collision! :)
Guess I'll use up one of the agf_spare64's.
--D
>
> __be32 agf_flfirst; /* first freelist block's index */
> __be32 agf_fllast; /* last freelist block's index */
> @@ -1277,6 +1282,13 @@ typedef __be32 xfs_inobt_ptr_t;
> #define XFS_FIBT_BLOCK(mp)
> ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1))
>
> /*
> + * Reverse mapping btree format definitions
> + *
> + * There is a btree for the reverse map per allocation group
> + */
> +#define XFS_RMAP_CRC_MAGIC 0x524d4233 /* 'RMB3' */
> +
> +/*
> * The first data block of an AG depends on whether the filesystem was
> formatted
> * with the finobt feature. If so, account for the finobt reserved root btree
> * block.
> diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
> index b79dc66..3d50364 100644
> --- a/fs/xfs/libxfs/xfs_types.h
> +++ b/fs/xfs/libxfs/xfs_types.h
> @@ -108,8 +108,8 @@ typedef enum {
> } xfs_lookup_t;
>
> typedef enum {
> - XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi,
> - XFS_BTNUM_FINOi, XFS_BTNUM_MAX
> + XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_RMAPi, XFS_BTNUM_BMAPi,
> + XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_MAX
> } xfs_btnum_t;
>
> struct xfs_name {
> --
> 2.0.0
>
> _______________________________________________
> xfs mailing list
> xfs@xxxxxxxxxxx
> http://oss.sgi.com/mailman/listinfo/xfs
|