@@ -1287,6 +1287,7 @@ static inline bool xfs_dinode_has_large_extent_counts(
* RT bit manipulation macros.
*/
#define XFS_RTBITMAP_MAGIC 0x424D505A /* BMPZ */
+#define XFS_RTSUMMARY_MAGIC 0x53554D59 /* SUMY */
struct xfs_rtbuf_blkinfo {
__be32 rt_magic; /* validity check on block */
@@ -49,7 +49,7 @@ xfs_rtbuf_verify_read(
struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
xfs_failaddr_t fa;
- if (!xfs_has_rtgroups(mp) || bp->b_ops != &xfs_rtbitmap_buf_ops)
+ if (!xfs_has_rtgroups(mp))
return;
if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr->rt_lsn))) {
@@ -80,7 +80,7 @@ xfs_rtbuf_verify_write(
struct xfs_buf_log_item *bip = bp->b_log_item;
xfs_failaddr_t fa;
- if (!xfs_has_rtgroups(mp) || bp->b_ops != &xfs_rtbitmap_buf_ops)
+ if (!xfs_has_rtgroups(mp))
return;
fa = xfs_rtbuf_verify(bp);
@@ -108,6 +108,14 @@ const struct xfs_buf_ops xfs_rtbitmap_buf_ops = {
.verify_struct = xfs_rtbuf_verify,
};
+const struct xfs_buf_ops xfs_rtsummary_buf_ops = {
+ .name = "xfs_rtsummary",
+ .magic = { 0, cpu_to_be32(XFS_RTSUMMARY_MAGIC) },
+ .verify_read = xfs_rtbuf_verify_read,
+ .verify_write = xfs_rtbuf_verify_write,
+ .verify_struct = xfs_rtbuf_verify,
+};
+
/*
* Get a buffer for the bitmap or summary file block specified.
* The buffer is returned read and locked.
@@ -149,7 +157,7 @@ xfs_rtbuf_get(
if (error)
return error;
- if (xfs_has_rtgroups(mp) && !issum) {
+ if (xfs_has_rtgroups(mp)) {
struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
if (hdr->rt_owner != cpu_to_be64(ip->i_ino)) {
@@ -1317,6 +1325,10 @@ xfs_rtsummary_blockcount(
unsigned long long rsumwords;
rsumwords = (unsigned long long)rsumlevels * rbmblocks;
+
+ if (xfs_has_rtgroups(mp))
+ return howmany_64(rsumwords, mp->m_blockwsize);
+
return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
}
@@ -181,6 +181,9 @@ xfs_rtsumoffs_to_block(
struct xfs_mount *mp,
xfs_rtsumoff_t rsumoff)
{
+ if (xfs_has_rtgroups(mp))
+ return rsumoff / mp->m_blockwsize;
+
return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t));
}
@@ -195,16 +198,24 @@ xfs_rtsumoffs_to_infoword(
{
unsigned int mask = mp->m_blockmask >> XFS_SUMINFOLOG;
+ if (xfs_has_rtgroups(mp))
+ return rsumoff % mp->m_blockwsize;
+
return rsumoff & mask;
}
/* Return a pointer to a summary info word within a rt summary block buffer. */
static inline union xfs_suminfo_ondisk *
xfs_rsumbuf_infoptr(
+ struct xfs_mount *mp,
void *buf,
unsigned int infoword)
{
union xfs_suminfo_ondisk *infop = buf;
+ struct xfs_rtbuf_blkinfo *hdr = buf;
+
+ if (xfs_has_rtgroups(mp))
+ infop = (union xfs_suminfo_ondisk *)(hdr + 1);
return &infop[infoword];
}
@@ -215,7 +226,7 @@ xfs_rsumblock_infoptr(
struct xfs_buf *bp,
unsigned int infoword)
{
- return xfs_rsumbuf_infoptr(bp->b_addr, infoword);
+ return xfs_rsumbuf_infoptr(bp->b_mount, bp->b_addr, infoword);
}
static inline const struct xfs_buf_ops *
@@ -223,8 +234,11 @@ xfs_rtblock_ops(
struct xfs_mount *mp,
bool issum)
{
- if (xfs_has_rtgroups(mp) && !issum)
+ if (xfs_has_rtgroups(mp)) {
+ if (issum)
+ return &xfs_rtsummary_buf_ops;
return &xfs_rtbitmap_buf_ops;
+ }
return &xfs_rtbuf_ops;
}
@@ -39,6 +39,7 @@ extern const struct xfs_buf_ops xfs_inode_buf_ra_ops;
extern const struct xfs_buf_ops xfs_refcountbt_buf_ops;
extern const struct xfs_buf_ops xfs_rmapbt_buf_ops;
extern const struct xfs_buf_ops xfs_rtbitmap_buf_ops;
+extern const struct xfs_buf_ops xfs_rtsummary_buf_ops;
extern const struct xfs_buf_ops xfs_rtbuf_ops;
extern const struct xfs_buf_ops xfs_rtsb_buf_ops;
extern const struct xfs_buf_ops xfs_sb_buf_ops;