summaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 73c95466c225..2ae55db8c977 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -4795,34 +4795,59 @@ xfs_bmap_split_indlen(
4795 xfs_filblks_t len2 = *indlen2; 4795 xfs_filblks_t len2 = *indlen2;
4796 xfs_filblks_t nres = len1 + len2; /* new total res. */ 4796 xfs_filblks_t nres = len1 + len2; /* new total res. */
4797 xfs_filblks_t stolen = 0; 4797 xfs_filblks_t stolen = 0;
4798 xfs_filblks_t resfactor;
4798 4799
4799 /* 4800 /*
4800 * Steal as many blocks as we can to try and satisfy the worst case 4801 * Steal as many blocks as we can to try and satisfy the worst case
4801 * indlen for both new extents. 4802 * indlen for both new extents.
4802 */ 4803 */
4803 while (nres > ores && avail) { 4804 if (ores < nres && avail)
4804 nres--; 4805 stolen = XFS_FILBLKS_MIN(nres - ores, avail);
4805 avail--; 4806 ores += stolen;
4806 stolen++; 4807
4807 } 4808 /* nothing else to do if we've satisfied the new reservation */
4809 if (ores >= nres)
4810 return stolen;
4811
4812 /*
4813 * We can't meet the total required reservation for the two extents.
4814 * Calculate the percent of the overall shortage between both extents
4815 * and apply this percentage to each of the requested indlen values.
4816 * This distributes the shortage fairly and reduces the chances that one
4817 * of the two extents is left with nothing when extents are repeatedly
4818 * split.
4819 */
4820 resfactor = (ores * 100);
4821 do_div(resfactor, nres);
4822 len1 *= resfactor;
4823 do_div(len1, 100);
4824 len2 *= resfactor;
4825 do_div(len2, 100);
4826 ASSERT(len1 + len2 <= ores);
4827 ASSERT(len1 < *indlen1 && len2 < *indlen2);
4808 4828
4809 /* 4829 /*
4810 * The only blocks available are those reserved for the original 4830 * Hand out the remainder to each extent. If one of the two reservations
4811 * extent and what we can steal from the extent being removed. 4831 * is zero, we want to make sure that one gets a block first. The loop
4812 * If this still isn't enough to satisfy the combined 4832 * below starts with len1, so hand len2 a block right off the bat if it
4813 * requirements for the two new extents, skim blocks off of each 4833 * is zero.
4814 * of the new reservations until they match what is available.
4815 */ 4834 */
4816 while (nres > ores) { 4835 ores -= (len1 + len2);
4817 if (len1) { 4836 ASSERT((*indlen1 - len1) + (*indlen2 - len2) >= ores);
4818 len1--; 4837 if (ores && !len2 && *indlen2) {
4819 nres--; 4838 len2++;
4839 ores--;
4840 }
4841 while (ores) {
4842 if (len1 < *indlen1) {
4843 len1++;
4844 ores--;
4820 } 4845 }
4821 if (nres == ores) 4846 if (!ores)
4822 break; 4847 break;
4823 if (len2) { 4848 if (len2 < *indlen2) {
4824 len2--; 4849 len2++;
4825 nres--; 4850 ores--;
4826 } 4851 }
4827 } 4852 }
4828 4853