diff options
Diffstat (limited to 'fs/xfs/xfs_rtalloc.c')
| -rw-r--r-- | fs/xfs/xfs_rtalloc.c | 44 | 
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 | ||
| 864 | static void | ||
| 865 | xfs_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 | ||
