On Tue, Jun 02, 2015 at 11:30:22PM -0700, Darrick J. Wong wrote: > 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? Aha, they're in the later patches, which my mailer helpfully ... delivered later. I think I need sleep. Disregard most of this email. :) I'll move the reflink fields so they don't conflict, and read these patches more closely tomorrow. Sorry for the noise. --D > > <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 > > _______________________________________________ > xfs mailing list > xfs@xxxxxxxxxxx > http://oss.sgi.com/mailman/listinfo/xfs _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs