@@ -1944,10 +1944,14 @@ init(
inodata[c] = xcalloc(inodata_hash_size, sizeof(**inodata));
}
if (rt) {
+ unsigned long long words;
+
dbmap[c] = xcalloc(mp->m_sb.sb_rblocks, sizeof(**dbmap));
inomap[c] = xcalloc(mp->m_sb.sb_rblocks, sizeof(**inomap));
- sumfile = xcalloc(mp->m_rsumsize, 1);
- sumcompute = xcalloc(mp->m_rsumsize, 1);
+ words = libxfs_rtsummary_wordcount(mp, mp->m_rsumlevels,
+ mp->m_sb.sb_rbmblocks);
+ sumfile = xcalloc(words, sizeof(xfs_suminfo_t));
+ sumcompute = xcalloc(words, sizeof(xfs_suminfo_t));
}
nflag = sflag = tflag = verbose = optind = 0;
while ((c = getopt(argc, argv, "b:i:npstv")) != EOF) {
@@ -440,6 +440,7 @@ rtmount_init(
{
struct xfs_buf *bp; /* buffer for last block of subvolume */
xfs_daddr_t d; /* address of last block of subvolume */
+ unsigned int rsumblocks;
int error;
if (mp->m_sb.sb_rblocks == 0)
@@ -465,10 +466,9 @@ rtmount_init(
return -1;
}
mp->m_rsumlevels = mp->m_sb.sb_rextslog + 1;
- mp->m_rsumsize =
- (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels *
- mp->m_sb.sb_rbmblocks;
- mp->m_rsumsize = roundup(mp->m_rsumsize, mp->m_sb.sb_blocksize);
+ rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels,
+ mp->m_sb.sb_rbmblocks);
+ mp->m_rsumsize = XFS_FSB_TO_B(mp, rsumblocks);
mp->m_rbmip = mp->m_rsumip = NULL;
/*
@@ -231,6 +231,8 @@
#define xfs_rtbitmap_setword libxfs_rtbitmap_setword
#define xfs_rtbitmap_wordcount libxfs_rtbitmap_wordcount
+#define xfs_rtsummary_wordcount libxfs_rtsummary_wordcount
+
#define xfs_rtfree_extent libxfs_rtfree_extent
#define xfs_sb_from_disk libxfs_sb_from_disk
#define xfs_sb_quota_from_disk libxfs_sb_quota_from_disk
@@ -1203,3 +1203,32 @@ xfs_rtbitmap_wordcount(
blocks = xfs_rtbitmap_blockcount(mp, rtextents);
return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
}
+
+/* Compute the number of rtsummary blocks needed to track the given rt space. */
+xfs_filblks_t
+xfs_rtsummary_blockcount(
+ struct xfs_mount *mp,
+ unsigned int rsumlevels,
+ xfs_extlen_t rbmblocks)
+{
+ unsigned long long rsumwords;
+
+ rsumwords = (unsigned long long)rsumlevels * rbmblocks;
+ return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
+}
+
+/*
+ * Compute the number of rtsummary info words needed to populate every block of
+ * a summary file that is large enough to track the given rt space.
+ */
+unsigned long long
+xfs_rtsummary_wordcount(
+ struct xfs_mount *mp,
+ unsigned int rsumlevels,
+ xfs_extlen_t rbmblocks)
+{
+ xfs_filblks_t blocks;
+
+ blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks);
+ return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
+}
@@ -270,6 +270,11 @@ xfs_rtword_t xfs_rtbitmap_getword(struct xfs_mount *mp,
union xfs_rtword_ondisk *wordptr);
void xfs_rtbitmap_setword(struct xfs_mount *mp,
union xfs_rtword_ondisk *wordptr, xfs_rtword_t incore);
+
+xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
+ unsigned int rsumlevels, xfs_extlen_t rbmblocks);
+unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp,
+ unsigned int rsumlevels, xfs_extlen_t rbmblocks);
#else /* CONFIG_XFS_RT */
# define xfs_rtfree_extent(t,b,l) (-ENOSYS)
# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS)
@@ -284,6 +289,8 @@ xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
return 0;
}
# define xfs_rtbitmap_wordcount(mp, r) (0)
+# define xfs_rtsummary_blockcount(mp, l, b) (0)
+# define xfs_rtsummary_wordcount(mp, l, b) (0)
#endif /* CONFIG_XFS_RT */
#endif /* __XFS_RTBITMAP_H__ */
@@ -34,7 +34,10 @@ rtinit(xfs_mount_t *mp)
do_error(
_("couldn't allocate memory for incore realtime bitmap.\n"));
- if ((sumcompute = calloc(mp->m_rsumsize, 1)) == NULL)
+ wordcnt = libxfs_rtsummary_wordcount(mp, mp->m_rsumlevels,
+ mp->m_sb.sb_rbmblocks);
+ sumcompute = calloc(wordcnt, sizeof(xfs_suminfo_t));
+ if (!sumcompute)
do_error(
_("couldn't allocate memory for incore realtime summary info.\n"));
}