@@ -64,6 +64,7 @@
#define xfs_bunmapi libxfs_bunmapi
#define xfs_bwrite libxfs_bwrite
#define xfs_calc_dquots_per_chunk libxfs_calc_dquots_per_chunk
+#define xfs_compute_rextslog libxfs_compute_rextslog
#define xfs_da3_node_hdr_from_disk libxfs_da3_node_hdr_from_disk
#define xfs_da_get_buf libxfs_da_get_buf
#define xfs_da_hashname libxfs_da_hashname
@@ -1128,6 +1128,18 @@ xfs_rtbitmap_blockcount(
return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize);
}
+/*
+ * Compute the maximum level number of the realtime summary file, as defined by
+ * mkfs. The use of highbit32 on a 64-bit quantity is a historic artifact that
+ * prohibits correct use of rt volumes with more than 2^32 extents.
+ */
+uint8_t
+xfs_compute_rextslog(
+ xfs_rtbxlen_t rtextents)
+{
+ return rtextents ? xfs_highbit32(rtextents) : 0;
+}
+
/*
* Compute the number of rtbitmap words needed to populate every block of a
* bitmap that is large enough to track the given number of rt extents.
@@ -351,6 +351,8 @@ xfs_rtfree_extent(
int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
xfs_filblks_t rtlen);
+uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents);
+
xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t
rtextents);
unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp,
@@ -369,6 +371,7 @@ unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp,
# define xfs_rtsummary_read_buf(a,b) (-ENOSYS)
# define xfs_rtbuf_cache_relse(a) (0)
# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS)
+# define xfs_compute_rextslog(rtx) (0)
static inline xfs_filblks_t
xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
{
@@ -23,6 +23,7 @@
#include "xfs_da_format.h"
#include "xfs_health.h"
#include "xfs_ag.h"
+#include "xfs_rtbitmap.h"
/*
* Physical superblock buffer manipulations. Shared with libxfs in userspace.
@@ -507,7 +508,7 @@ xfs_validate_sb_common(
NBBY * sbp->sb_blocksize);
if (sbp->sb_rextents != rexts ||
- sbp->sb_rextslog != xfs_highbit32(sbp->sb_rextents) ||
+ sbp->sb_rextslog != xfs_compute_rextslog(rexts) ||
sbp->sb_rbmblocks != rbmblocks) {
xfs_notice(mp,
"realtime geometry sanity check failed");
@@ -3693,8 +3693,7 @@ finish_superblock_setup(
sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount;
sbp->sb_rbmblocks = cfg->rtbmblocks;
sbp->sb_logblocks = (xfs_extlen_t)cfg->logblocks;
- sbp->sb_rextslog = (uint8_t)(cfg->rtextents ?
- libxfs_highbit32((unsigned int)cfg->rtextents) : 0);
+ sbp->sb_rextslog = libxfs_compute_rextslog(cfg->rtextents);
sbp->sb_inprogress = 1; /* mkfs is in progress */
sbp->sb_imax_pct = cfg->imaxpct;
sbp->sb_icount = 0;
@@ -475,8 +475,7 @@ verify_sb(char *sb_buf, xfs_sb_t *sb, int is_primary_sb)
if (sb->sb_rblocks / sb->sb_rextsize != sb->sb_rextents)
return(XR_BAD_RT_GEO_DATA);
- if (sb->sb_rextslog !=
- libxfs_highbit32((unsigned int)sb->sb_rextents))
+ if (sb->sb_rextslog != libxfs_compute_rextslog(sb->sb_rextents))
return(XR_BAD_RT_GEO_DATA);
if (sb->sb_rbmblocks != (xfs_extlen_t) howmany(sb->sb_rextents,