aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_alloc.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 5673bcfda2f0..71596e57283a 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -175,6 +175,7 @@ xfs_alloc_compute_diff(
175 xfs_agblock_t wantbno, /* target starting block */ 175 xfs_agblock_t wantbno, /* target starting block */
176 xfs_extlen_t wantlen, /* target length */ 176 xfs_extlen_t wantlen, /* target length */
177 xfs_extlen_t alignment, /* target alignment */ 177 xfs_extlen_t alignment, /* target alignment */
178 char userdata, /* are we allocating data? */
178 xfs_agblock_t freebno, /* freespace's starting block */ 179 xfs_agblock_t freebno, /* freespace's starting block */
179 xfs_extlen_t freelen, /* freespace's length */ 180 xfs_extlen_t freelen, /* freespace's length */
180 xfs_agblock_t *newbnop) /* result: best start block from free */ 181 xfs_agblock_t *newbnop) /* result: best start block from free */
@@ -189,7 +190,14 @@ xfs_alloc_compute_diff(
189 ASSERT(freelen >= wantlen); 190 ASSERT(freelen >= wantlen);
190 freeend = freebno + freelen; 191 freeend = freebno + freelen;
191 wantend = wantbno + wantlen; 192 wantend = wantbno + wantlen;
192 if (freebno >= wantbno) { 193 /*
194 * We want to allocate from the start of a free extent if it is past
195 * the desired block or if we are allocating user data and the free
196 * extent is before desired block. The second case is there to allow
197 * for contiguous allocation from the remaining free space if the file
198 * grows in the short term.
199 */
200 if (freebno >= wantbno || (userdata && freeend < wantend)) {
193 if ((newbno1 = roundup(freebno, alignment)) >= freeend) 201 if ((newbno1 = roundup(freebno, alignment)) >= freeend)
194 newbno1 = NULLAGBLOCK; 202 newbno1 = NULLAGBLOCK;
195 } else if (freeend >= wantend && alignment > 1) { 203 } else if (freeend >= wantend && alignment > 1) {
@@ -805,7 +813,8 @@ xfs_alloc_find_best_extent(
805 xfs_alloc_fix_len(args); 813 xfs_alloc_fix_len(args);
806 814
807 sdiff = xfs_alloc_compute_diff(args->agbno, args->len, 815 sdiff = xfs_alloc_compute_diff(args->agbno, args->len,
808 args->alignment, *sbnoa, 816 args->alignment,
817 args->userdata, *sbnoa,
809 *slena, &new); 818 *slena, &new);
810 819
811 /* 820 /*
@@ -976,7 +985,8 @@ restart:
976 if (args->len < blen) 985 if (args->len < blen)
977 continue; 986 continue;
978 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, 987 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
979 args->alignment, ltbnoa, ltlena, &ltnew); 988 args->alignment, args->userdata, ltbnoa,
989 ltlena, &ltnew);
980 if (ltnew != NULLAGBLOCK && 990 if (ltnew != NULLAGBLOCK &&
981 (args->len > blen || ltdiff < bdiff)) { 991 (args->len > blen || ltdiff < bdiff)) {
982 bdiff = ltdiff; 992 bdiff = ltdiff;
@@ -1128,7 +1138,8 @@ restart:
1128 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 1138 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1129 xfs_alloc_fix_len(args); 1139 xfs_alloc_fix_len(args);
1130 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, 1140 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
1131 args->alignment, ltbnoa, ltlena, &ltnew); 1141 args->alignment, args->userdata, ltbnoa,
1142 ltlena, &ltnew);
1132 1143
1133 error = xfs_alloc_find_best_extent(args, 1144 error = xfs_alloc_find_best_extent(args,
1134 &bno_cur_lt, &bno_cur_gt, 1145 &bno_cur_lt, &bno_cur_gt,
@@ -1144,7 +1155,8 @@ restart:
1144 args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen); 1155 args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
1145 xfs_alloc_fix_len(args); 1156 xfs_alloc_fix_len(args);
1146 gtdiff = xfs_alloc_compute_diff(args->agbno, args->len, 1157 gtdiff = xfs_alloc_compute_diff(args->agbno, args->len,
1147 args->alignment, gtbnoa, gtlena, &gtnew); 1158 args->alignment, args->userdata, gtbnoa,
1159 gtlena, &gtnew);
1148 1160
1149 error = xfs_alloc_find_best_extent(args, 1161 error = xfs_alloc_find_best_extent(args,
1150 &bno_cur_gt, &bno_cur_lt, 1162 &bno_cur_gt, &bno_cur_lt,
@@ -1203,7 +1215,7 @@ restart:
1203 } 1215 }
1204 rlen = args->len; 1216 rlen = args->len;
1205 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, 1217 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
1206 ltbnoa, ltlena, &ltnew); 1218 args->userdata, ltbnoa, ltlena, &ltnew);
1207 ASSERT(ltnew >= ltbno); 1219 ASSERT(ltnew >= ltbno);
1208 ASSERT(ltnew + rlen <= ltbnoa + ltlena); 1220 ASSERT(ltnew + rlen <= ltbnoa + ltlena);
1209 ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); 1221 ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));