diff options
Diffstat (limited to 'fs/ubifs/find.c')
-rw-r--r-- | fs/ubifs/find.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 10394c548367..47814cde2407 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c | |||
@@ -211,14 +211,8 @@ static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c, | |||
211 | * dirty index heap, and it falls-back to LPT scanning if the heaps are empty | 211 | * dirty index heap, and it falls-back to LPT scanning if the heaps are empty |
212 | * or do not have an LEB which satisfies the @min_space criteria. | 212 | * or do not have an LEB which satisfies the @min_space criteria. |
213 | * | 213 | * |
214 | * Note: | 214 | * Note, LEBs which have less than dead watermark of free + dirty space are |
215 | * o LEBs which have less than dead watermark of dirty space are never picked | 215 | * never picked by this function. |
216 | * by this function; | ||
217 | * | ||
218 | * Returns zero and the LEB properties of | ||
219 | * found dirty LEB in case of success, %-ENOSPC if no dirty LEB was found and a | ||
220 | * negative error code in case of other failures. The returned LEB is marked as | ||
221 | * "taken". | ||
222 | * | 216 | * |
223 | * The additional @pick_free argument controls if this function has to return a | 217 | * The additional @pick_free argument controls if this function has to return a |
224 | * free or freeable LEB if one is present. For example, GC must to set it to %1, | 218 | * free or freeable LEB if one is present. For example, GC must to set it to %1, |
@@ -231,6 +225,10 @@ static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c, | |||
231 | * | 225 | * |
232 | * In addition @pick_free is set to %2 by the recovery process in order to | 226 | * In addition @pick_free is set to %2 by the recovery process in order to |
233 | * recover gc_lnum in which case an index LEB must not be returned. | 227 | * recover gc_lnum in which case an index LEB must not be returned. |
228 | * | ||
229 | * This function returns zero and the LEB properties of found dirty LEB in case | ||
230 | * of success, %-ENOSPC if no dirty LEB was found and a negative error code in | ||
231 | * case of other failures. The returned LEB is marked as "taken". | ||
234 | */ | 232 | */ |
235 | int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, | 233 | int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, |
236 | int min_space, int pick_free) | 234 | int min_space, int pick_free) |
@@ -245,7 +243,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, | |||
245 | int lebs, rsvd_idx_lebs = 0; | 243 | int lebs, rsvd_idx_lebs = 0; |
246 | 244 | ||
247 | spin_lock(&c->space_lock); | 245 | spin_lock(&c->space_lock); |
248 | lebs = c->lst.empty_lebs; | 246 | lebs = c->lst.empty_lebs + c->idx_gc_cnt; |
249 | lebs += c->freeable_cnt - c->lst.taken_empty_lebs; | 247 | lebs += c->freeable_cnt - c->lst.taken_empty_lebs; |
250 | 248 | ||
251 | /* | 249 | /* |
@@ -290,9 +288,14 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, | |||
290 | idx_lp = idx_heap->arr[0]; | 288 | idx_lp = idx_heap->arr[0]; |
291 | sum = idx_lp->free + idx_lp->dirty; | 289 | sum = idx_lp->free + idx_lp->dirty; |
292 | /* | 290 | /* |
293 | * Since we reserve twice as more space for the index than it | 291 | * Since we reserve thrice as much space for the index than it |
294 | * actually takes, it does not make sense to pick indexing LEBs | 292 | * actually takes, it does not make sense to pick indexing LEBs |
295 | * with less than half LEB of dirty space. | 293 | * with less than, say, half LEB of dirty space. May be half is |
294 | * not the optimal boundary - this should be tested and | ||
295 | * checked. This boundary should determine how much we use | ||
296 | * in-the-gaps to consolidate the index comparing to how much | ||
297 | * we use garbage collector to consolidate it. The "half" | ||
298 | * criteria just feels to be fine. | ||
296 | */ | 299 | */ |
297 | if (sum < min_space || sum < c->half_leb_size) | 300 | if (sum < min_space || sum < c->half_leb_size) |
298 | idx_lp = NULL; | 301 | idx_lp = NULL; |
@@ -312,7 +315,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, | |||
312 | lp = idx_lp; | 315 | lp = idx_lp; |
313 | 316 | ||
314 | if (lp) { | 317 | if (lp) { |
315 | ubifs_assert(lp->dirty >= c->dead_wm); | 318 | ubifs_assert(lp->free + lp->dirty >= c->dead_wm); |
316 | goto found; | 319 | goto found; |
317 | } | 320 | } |
318 | 321 | ||
@@ -504,7 +507,6 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free, | |||
504 | rsvd_idx_lebs = 0; | 507 | rsvd_idx_lebs = 0; |
505 | lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - | 508 | lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - |
506 | c->lst.taken_empty_lebs; | 509 | c->lst.taken_empty_lebs; |
507 | ubifs_assert(lebs + c->lst.idx_lebs >= c->min_idx_lebs); | ||
508 | if (rsvd_idx_lebs < lebs) | 510 | if (rsvd_idx_lebs < lebs) |
509 | /* | 511 | /* |
510 | * OK to allocate an empty LEB, but we still don't want to go | 512 | * OK to allocate an empty LEB, but we still don't want to go |