diff options
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 61 |
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 | ||