aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_rtalloc.c
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2018-12-21 21:45:18 -0500
committerDarrick J. Wong <darrick.wong@oracle.com>2018-12-21 21:45:18 -0500
commit65eed012d1f2d0f0bf0ffc036826d58147de77b8 (patch)
treebe3a4f61c0399d64281e776b06778e3a74f28442 /fs/xfs/xfs_rtalloc.c
parent86d163dbfe2ac0b30fbb6e256301abbfa9e4549e (diff)
xfs: reallocate realtime summary cache on growfs
At mount time, we allocate m_rsum_cache with the number of realtime bitmap blocks. However, xfs_growfs_rt() can increase the number of realtime bitmap blocks. Using the cache after this happens may access out of the bounds of the cache. Fix it by reallocating the cache in this case. Fixes: 355e3532132b ("xfs: cache minimum realtime summary level") Signed-off-by: Omar Sandoval <osandov@fb.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/xfs_rtalloc.c')
-rw-r--r--fs/xfs/xfs_rtalloc.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index afe4d29f7ab4..ac0fcdad0c4e 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -861,6 +861,21 @@ out_trans_cancel:
861 return error; 861 return error;
862} 862}
863 863
864static void
865xfs_alloc_rsum_cache(
866 xfs_mount_t *mp, /* file system mount structure */
867 xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */
868{
869 /*
870 * The rsum cache is initialized to all zeroes, which is trivially a
871 * lower bound on the minimum level with any free extents. We can
872 * continue without the cache if it couldn't be allocated.
873 */
874 mp->m_rsum_cache = kmem_zalloc_large(rbmblocks, KM_SLEEP);
875 if (!mp->m_rsum_cache)
876 xfs_warn(mp, "could not allocate realtime summary cache");
877}
878
864/* 879/*
865 * Visible (exported) functions. 880 * Visible (exported) functions.
866 */ 881 */
@@ -889,6 +904,7 @@ xfs_growfs_rt(
889 xfs_extlen_t rsumblocks; /* current number of rt summary blks */ 904 xfs_extlen_t rsumblocks; /* current number of rt summary blks */
890 xfs_sb_t *sbp; /* old superblock */ 905 xfs_sb_t *sbp; /* old superblock */
891 xfs_fsblock_t sumbno; /* summary block number */ 906 xfs_fsblock_t sumbno; /* summary block number */
907 uint8_t *rsum_cache; /* old summary cache */
892 908
893 sbp = &mp->m_sb; 909 sbp = &mp->m_sb;
894 /* 910 /*
@@ -945,6 +961,11 @@ xfs_growfs_rt(
945 error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip); 961 error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip);
946 if (error) 962 if (error)
947 return error; 963 return error;
964
965 rsum_cache = mp->m_rsum_cache;
966 if (nrbmblocks != sbp->sb_rbmblocks)
967 xfs_alloc_rsum_cache(mp, nrbmblocks);
968
948 /* 969 /*
949 * Allocate a new (fake) mount/sb. 970 * Allocate a new (fake) mount/sb.
950 */ 971 */
@@ -1070,6 +1091,20 @@ error_cancel:
1070 */ 1091 */
1071 kmem_free(nmp); 1092 kmem_free(nmp);
1072 1093
1094 /*
1095 * If we had to allocate a new rsum_cache, we either need to free the
1096 * old one (if we succeeded) or free the new one and restore the old one
1097 * (if there was an error).
1098 */
1099 if (rsum_cache != mp->m_rsum_cache) {
1100 if (error) {
1101 kmem_free(mp->m_rsum_cache);
1102 mp->m_rsum_cache = rsum_cache;
1103 } else {
1104 kmem_free(rsum_cache);
1105 }
1106 }
1107
1073 return error; 1108 return error;
1074} 1109}
1075 1110
@@ -1217,14 +1252,7 @@ xfs_rtmount_inodes(
1217 return error; 1252 return error;
1218 } 1253 }
1219 ASSERT(mp->m_rsumip != NULL); 1254 ASSERT(mp->m_rsumip != NULL);
1220 /* 1255 xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks);
1221 * The rsum cache is initialized to all zeroes, which is trivially a
1222 * lower bound on the minimum level with any free extents. We can
1223 * continue without the cache if it couldn't be allocated.
1224 */
1225 mp->m_rsum_cache = kmem_zalloc_large(sbp->sb_rbmblocks, KM_SLEEP);
1226 if (!mp->m_rsum_cache)
1227 xfs_warn(mp, "could not allocate realtime summary cache");
1228 return 0; 1256 return 0;
1229} 1257}
1230 1258