Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
find.c
Go to the documentation of this file.
1 /*
2  * This file is part of UBIFS.
3  *
4  * Copyright (C) 2006-2008 Nokia Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by
8  * the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 51
17  * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * Authors: Artem Bityutskiy (Битюцкий Артём)
20  * Adrian Hunter
21  */
22 
23 /*
24  * This file contains functions for finding LEBs for various purposes e.g.
25  * garbage collection. In general, lprops category heaps and lists are used
26  * for fast access, falling back on scanning the LPT as a last resort.
27  */
28 
29 #include <linux/sort.h>
30 #include "ubifs.h"
31 
39 struct scan_data {
40  int min_space;
41  int pick_free;
42  int lnum;
44 };
45 
54 static int valuable(struct ubifs_info *c, const struct ubifs_lprops *lprops)
55 {
56  int n, cat = lprops->flags & LPROPS_CAT_MASK;
57  struct ubifs_lpt_heap *heap;
58 
59  switch (cat) {
60  case LPROPS_DIRTY:
61  case LPROPS_DIRTY_IDX:
62  case LPROPS_FREE:
63  heap = &c->lpt_heap[cat - 1];
64  if (heap->cnt < heap->max_cnt)
65  return 1;
66  if (lprops->free + lprops->dirty >= c->dark_wm)
67  return 1;
68  return 0;
69  case LPROPS_EMPTY:
70  n = c->lst.empty_lebs + c->freeable_cnt -
71  c->lst.taken_empty_lebs;
72  if (n < c->lsave_cnt)
73  return 1;
74  return 0;
75  case LPROPS_FREEABLE:
76  return 1;
77  case LPROPS_FRDI_IDX:
78  return 1;
79  }
80  return 0;
81 }
82 
95 static int scan_for_dirty_cb(struct ubifs_info *c,
96  const struct ubifs_lprops *lprops, int in_tree,
97  struct scan_data *data)
98 {
99  int ret = LPT_SCAN_CONTINUE;
100 
101  /* Exclude LEBs that are currently in use */
102  if (lprops->flags & LPROPS_TAKEN)
103  return LPT_SCAN_CONTINUE;
104  /* Determine whether to add these LEB properties to the tree */
105  if (!in_tree && valuable(c, lprops))
106  ret |= LPT_SCAN_ADD;
107  /* Exclude LEBs with too little space */
108  if (lprops->free + lprops->dirty < data->min_space)
109  return ret;
110  /* If specified, exclude index LEBs */
111  if (data->exclude_index && lprops->flags & LPROPS_INDEX)
112  return ret;
113  /* If specified, exclude empty or freeable LEBs */
114  if (lprops->free + lprops->dirty == c->leb_size) {
115  if (!data->pick_free)
116  return ret;
117  /* Exclude LEBs with too little dirty space (unless it is empty) */
118  } else if (lprops->dirty < c->dead_wm)
119  return ret;
120  /* Finally we found space */
121  data->lnum = lprops->lnum;
122  return LPT_SCAN_ADD | LPT_SCAN_STOP;
123 }
124 
136 static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c,
137  int min_space, int pick_free,
138  int exclude_index)
139 {
140  const struct ubifs_lprops *lprops;
141  struct ubifs_lpt_heap *heap;
142  struct scan_data data;
143  int err, i;
144 
145  /* There may be an LEB with enough dirty space on the free heap */
146  heap = &c->lpt_heap[LPROPS_FREE - 1];
147  for (i = 0; i < heap->cnt; i++) {
148  lprops = heap->arr[i];
149  if (lprops->free + lprops->dirty < min_space)
150  continue;
151  if (lprops->dirty < c->dead_wm)
152  continue;
153  return lprops;
154  }
155  /*
156  * A LEB may have fallen off of the bottom of the dirty heap, and ended
157  * up as uncategorized even though it has enough dirty space for us now,
158  * so check the uncategorized list. N.B. neither empty nor freeable LEBs
159  * can end up as uncategorized because they are kept on lists not
160  * finite-sized heaps.
161  */
162  list_for_each_entry(lprops, &c->uncat_list, list) {
163  if (lprops->flags & LPROPS_TAKEN)
164  continue;
165  if (lprops->free + lprops->dirty < min_space)
166  continue;
167  if (exclude_index && (lprops->flags & LPROPS_INDEX))
168  continue;
169  if (lprops->dirty < c->dead_wm)
170  continue;
171  return lprops;
172  }
173  /* We have looked everywhere in main memory, now scan the flash */
174  if (c->pnodes_have >= c->pnode_cnt)
175  /* All pnodes are in memory, so skip scan */
176  return ERR_PTR(-ENOSPC);
177  data.min_space = min_space;
178  data.pick_free = pick_free;
179  data.lnum = -1;
181  err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum,
182  (ubifs_lpt_scan_callback)scan_for_dirty_cb,
183  &data);
184  if (err)
185  return ERR_PTR(err);
186  ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt);
187  c->lscan_lnum = data.lnum;
188  lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
189  if (IS_ERR(lprops))
190  return lprops;
191  ubifs_assert(lprops->lnum == data.lnum);
192  ubifs_assert(lprops->free + lprops->dirty >= min_space);
193  ubifs_assert(lprops->dirty >= c->dead_wm ||
194  (pick_free &&
195  lprops->free + lprops->dirty == c->leb_size));
196  ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
197  ubifs_assert(!exclude_index || !(lprops->flags & LPROPS_INDEX));
198  return lprops;
199 }
200 
233 int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
234  int min_space, int pick_free)
235 {
236  int err = 0, sum, exclude_index = pick_free == 2 ? 1 : 0;
237  const struct ubifs_lprops *lp = NULL, *idx_lp = NULL;
238  struct ubifs_lpt_heap *heap, *idx_heap;
239 
240  ubifs_get_lprops(c);
241 
242  if (pick_free) {
243  int lebs, rsvd_idx_lebs = 0;
244 
245  spin_lock(&c->space_lock);
246  lebs = c->lst.empty_lebs + c->idx_gc_cnt;
247  lebs += c->freeable_cnt - c->lst.taken_empty_lebs;
248 
249  /*
250  * Note, the index may consume more LEBs than have been reserved
251  * for it. It is OK because it might be consolidated by GC.
252  * But if the index takes fewer LEBs than it is reserved for it,
253  * this function must avoid picking those reserved LEBs.
254  */
255  if (c->bi.min_idx_lebs >= c->lst.idx_lebs) {
256  rsvd_idx_lebs = c->bi.min_idx_lebs - c->lst.idx_lebs;
257  exclude_index = 1;
258  }
259  spin_unlock(&c->space_lock);
260 
261  /* Check if there are enough free LEBs for the index */
262  if (rsvd_idx_lebs < lebs) {
263  /* OK, try to find an empty LEB */
264  lp = ubifs_fast_find_empty(c);
265  if (lp)
266  goto found;
267 
268  /* Or a freeable LEB */
269  lp = ubifs_fast_find_freeable(c);
270  if (lp)
271  goto found;
272  } else
273  /*
274  * We cannot pick free/freeable LEBs in the below code.
275  */
276  pick_free = 0;
277  } else {
278  spin_lock(&c->space_lock);
279  exclude_index = (c->bi.min_idx_lebs >= c->lst.idx_lebs);
280  spin_unlock(&c->space_lock);
281  }
282 
283  /* Look on the dirty and dirty index heaps */
284  heap = &c->lpt_heap[LPROPS_DIRTY - 1];
285  idx_heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1];
286 
287  if (idx_heap->cnt && !exclude_index) {
288  idx_lp = idx_heap->arr[0];
289  sum = idx_lp->free + idx_lp->dirty;
290  /*
291  * Since we reserve thrice as much space for the index than it
292  * actually takes, it does not make sense to pick indexing LEBs
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.
299  */
300  if (sum < min_space || sum < c->half_leb_size)
301  idx_lp = NULL;
302  }
303 
304  if (heap->cnt) {
305  lp = heap->arr[0];
306  if (lp->dirty + lp->free < min_space)
307  lp = NULL;
308  }
309 
310  /* Pick the LEB with most space */
311  if (idx_lp && lp) {
312  if (idx_lp->free + idx_lp->dirty >= lp->free + lp->dirty)
313  lp = idx_lp;
314  } else if (idx_lp && !lp)
315  lp = idx_lp;
316 
317  if (lp) {
318  ubifs_assert(lp->free + lp->dirty >= c->dead_wm);
319  goto found;
320  }
321 
322  /* Did not find a dirty LEB on the dirty heaps, have to scan */
323  dbg_find("scanning LPT for a dirty LEB");
324  lp = scan_for_dirty(c, min_space, pick_free, exclude_index);
325  if (IS_ERR(lp)) {
326  err = PTR_ERR(lp);
327  goto out;
328  }
329  ubifs_assert(lp->dirty >= c->dead_wm ||
330  (pick_free && lp->free + lp->dirty == c->leb_size));
331 
332 found:
333  dbg_find("found LEB %d, free %d, dirty %d, flags %#x",
334  lp->lnum, lp->free, lp->dirty, lp->flags);
335 
336  lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC,
337  lp->flags | LPROPS_TAKEN, 0);
338  if (IS_ERR(lp)) {
339  err = PTR_ERR(lp);
340  goto out;
341  }
342 
343  memcpy(ret_lp, lp, sizeof(struct ubifs_lprops));
344 
345 out:
346  ubifs_release_lprops(c);
347  return err;
348 }
349 
362 static int scan_for_free_cb(struct ubifs_info *c,
363  const struct ubifs_lprops *lprops, int in_tree,
364  struct scan_data *data)
365 {
366  int ret = LPT_SCAN_CONTINUE;
367 
368  /* Exclude LEBs that are currently in use */
369  if (lprops->flags & LPROPS_TAKEN)
370  return LPT_SCAN_CONTINUE;
371  /* Determine whether to add these LEB properties to the tree */
372  if (!in_tree && valuable(c, lprops))
373  ret |= LPT_SCAN_ADD;
374  /* Exclude index LEBs */
375  if (lprops->flags & LPROPS_INDEX)
376  return ret;
377  /* Exclude LEBs with too little space */
378  if (lprops->free < data->min_space)
379  return ret;
380  /* If specified, exclude empty LEBs */
381  if (!data->pick_free && lprops->free == c->leb_size)
382  return ret;
383  /*
384  * LEBs that have only free and dirty space must not be allocated
385  * because they may have been unmapped already or they may have data
386  * that is obsolete only because of nodes that are still sitting in a
387  * wbuf.
388  */
389  if (lprops->free + lprops->dirty == c->leb_size && lprops->dirty > 0)
390  return ret;
391  /* Finally we found space */
392  data->lnum = lprops->lnum;
393  return LPT_SCAN_ADD | LPT_SCAN_STOP;
394 }
395 
406 static
407 const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c,
408  int min_space, int pick_free,
409  int squeeze)
410 {
411  const struct ubifs_lprops *lprops;
412  struct ubifs_lpt_heap *heap;
413  struct scan_data data;
414  int err, i;
415 
416  if (squeeze) {
417  lprops = ubifs_fast_find_free(c);
418  if (lprops && lprops->free >= min_space)
419  return lprops;
420  }
421  if (pick_free) {
422  lprops = ubifs_fast_find_empty(c);
423  if (lprops)
424  return lprops;
425  }
426  if (!squeeze) {
427  lprops = ubifs_fast_find_free(c);
428  if (lprops && lprops->free >= min_space)
429  return lprops;
430  }
431  /* There may be an LEB with enough free space on the dirty heap */
432  heap = &c->lpt_heap[LPROPS_DIRTY - 1];
433  for (i = 0; i < heap->cnt; i++) {
434  lprops = heap->arr[i];
435  if (lprops->free >= min_space)
436  return lprops;
437  }
438  /*
439  * A LEB may have fallen off of the bottom of the free heap, and ended
440  * up as uncategorized even though it has enough free space for us now,
441  * so check the uncategorized list. N.B. neither empty nor freeable LEBs
442  * can end up as uncategorized because they are kept on lists not
443  * finite-sized heaps.
444  */
445  list_for_each_entry(lprops, &c->uncat_list, list) {
446  if (lprops->flags & LPROPS_TAKEN)
447  continue;
448  if (lprops->flags & LPROPS_INDEX)
449  continue;
450  if (lprops->free >= min_space)
451  return lprops;
452  }
453  /* We have looked everywhere in main memory, now scan the flash */
454  if (c->pnodes_have >= c->pnode_cnt)
455  /* All pnodes are in memory, so skip scan */
456  return ERR_PTR(-ENOSPC);
457  data.min_space = min_space;
458  data.pick_free = pick_free;
459  data.lnum = -1;
460  err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum,
461  (ubifs_lpt_scan_callback)scan_for_free_cb,
462  &data);
463  if (err)
464  return ERR_PTR(err);
465  ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt);
466  c->lscan_lnum = data.lnum;
467  lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
468  if (IS_ERR(lprops))
469  return lprops;
470  ubifs_assert(lprops->lnum == data.lnum);
471  ubifs_assert(lprops->free >= min_space);
472  ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
473  ubifs_assert(!(lprops->flags & LPROPS_INDEX));
474  return lprops;
475 }
476 
493 int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,
494  int squeeze)
495 {
496  const struct ubifs_lprops *lprops;
497  int lebs, rsvd_idx_lebs, pick_free = 0, err, lnum, flags;
498 
499  dbg_find("min_space %d", min_space);
500  ubifs_get_lprops(c);
501 
502  /* Check if there are enough empty LEBs for commit */
503  spin_lock(&c->space_lock);
504  if (c->bi.min_idx_lebs > c->lst.idx_lebs)
505  rsvd_idx_lebs = c->bi.min_idx_lebs - c->lst.idx_lebs;
506  else
507  rsvd_idx_lebs = 0;
508  lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
509  c->lst.taken_empty_lebs;
510  if (rsvd_idx_lebs < lebs)
511  /*
512  * OK to allocate an empty LEB, but we still don't want to go
513  * looking for one if there aren't any.
514  */
515  if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
516  pick_free = 1;
517  /*
518  * Because we release the space lock, we must account
519  * for this allocation here. After the LEB properties
520  * flags have been updated, we subtract one. Note, the
521  * result of this is that lprops also decreases
522  * @taken_empty_lebs in 'ubifs_change_lp()', so it is
523  * off by one for a short period of time which may
524  * introduce a small disturbance to budgeting
525  * calculations, but this is harmless because at the
526  * worst case this would make the budgeting subsystem
527  * be more pessimistic than needed.
528  *
529  * Fundamentally, this is about serialization of the
530  * budgeting and lprops subsystems. We could make the
531  * @space_lock a mutex and avoid dropping it before
532  * calling 'ubifs_change_lp()', but mutex is more
533  * heavy-weight, and we want budgeting to be as fast as
534  * possible.
535  */
536  c->lst.taken_empty_lebs += 1;
537  }
538  spin_unlock(&c->space_lock);
539 
540  lprops = do_find_free_space(c, min_space, pick_free, squeeze);
541  if (IS_ERR(lprops)) {
542  err = PTR_ERR(lprops);
543  goto out;
544  }
545 
546  lnum = lprops->lnum;
547  flags = lprops->flags | LPROPS_TAKEN;
548 
549  lprops = ubifs_change_lp(c, lprops, LPROPS_NC, LPROPS_NC, flags, 0);
550  if (IS_ERR(lprops)) {
551  err = PTR_ERR(lprops);
552  goto out;
553  }
554 
555  if (pick_free) {
556  spin_lock(&c->space_lock);
557  c->lst.taken_empty_lebs -= 1;
558  spin_unlock(&c->space_lock);
559  }
560 
561  *offs = c->leb_size - lprops->free;
562  ubifs_release_lprops(c);
563 
564  if (*offs == 0) {
565  /*
566  * Ensure that empty LEBs have been unmapped. They may not have
567  * been, for example, because of an unclean unmount. Also
568  * LEBs that were freeable LEBs (free + dirty == leb_size) will
569  * not have been unmapped.
570  */
571  err = ubifs_leb_unmap(c, lnum);
572  if (err)
573  return err;
574  }
575 
576  dbg_find("found LEB %d, free %d", lnum, c->leb_size - *offs);
577  ubifs_assert(*offs <= c->leb_size - min_space);
578  return lnum;
579 
580 out:
581  if (pick_free) {
582  spin_lock(&c->space_lock);
583  c->lst.taken_empty_lebs -= 1;
584  spin_unlock(&c->space_lock);
585  }
586  ubifs_release_lprops(c);
587  return err;
588 }
589 
602 static int scan_for_idx_cb(struct ubifs_info *c,
603  const struct ubifs_lprops *lprops, int in_tree,
604  struct scan_data *data)
605 {
606  int ret = LPT_SCAN_CONTINUE;
607 
608  /* Exclude LEBs that are currently in use */
609  if (lprops->flags & LPROPS_TAKEN)
610  return LPT_SCAN_CONTINUE;
611  /* Determine whether to add these LEB properties to the tree */
612  if (!in_tree && valuable(c, lprops))
613  ret |= LPT_SCAN_ADD;
614  /* Exclude index LEBS */
615  if (lprops->flags & LPROPS_INDEX)
616  return ret;
617  /* Exclude LEBs that cannot be made empty */
618  if (lprops->free + lprops->dirty != c->leb_size)
619  return ret;
620  /*
621  * We are allocating for the index so it is safe to allocate LEBs with
622  * only free and dirty space, because write buffers are sync'd at commit
623  * start.
624  */
625  data->lnum = lprops->lnum;
626  return LPT_SCAN_ADD | LPT_SCAN_STOP;
627 }
628 
633 static const struct ubifs_lprops *scan_for_leb_for_idx(struct ubifs_info *c)
634 {
635  struct ubifs_lprops *lprops;
636  struct scan_data data;
637  int err;
638 
639  data.lnum = -1;
640  err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum,
641  (ubifs_lpt_scan_callback)scan_for_idx_cb,
642  &data);
643  if (err)
644  return ERR_PTR(err);
645  ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt);
646  c->lscan_lnum = data.lnum;
647  lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
648  if (IS_ERR(lprops))
649  return lprops;
650  ubifs_assert(lprops->lnum == data.lnum);
651  ubifs_assert(lprops->free + lprops->dirty == c->leb_size);
652  ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
653  ubifs_assert(!(lprops->flags & LPROPS_INDEX));
654  return lprops;
655 }
656 
674 {
675  const struct ubifs_lprops *lprops;
676  int lnum = -1, err, flags;
677 
678  ubifs_get_lprops(c);
679 
680  lprops = ubifs_fast_find_empty(c);
681  if (!lprops) {
682  lprops = ubifs_fast_find_freeable(c);
683  if (!lprops) {
684  /*
685  * The first condition means the following: go scan the
686  * LPT if there are uncategorized lprops, which means
687  * there may be freeable LEBs there (UBIFS does not
688  * store the information about freeable LEBs in the
689  * master node).
690  */
691  if (c->in_a_category_cnt != c->main_lebs ||
692  c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
693  ubifs_assert(c->freeable_cnt == 0);
694  lprops = scan_for_leb_for_idx(c);
695  if (IS_ERR(lprops)) {
696  err = PTR_ERR(lprops);
697  goto out;
698  }
699  }
700  }
701  }
702 
703  if (!lprops) {
704  err = -ENOSPC;
705  goto out;
706  }
707 
708  lnum = lprops->lnum;
709 
710  dbg_find("found LEB %d, free %d, dirty %d, flags %#x",
711  lnum, lprops->free, lprops->dirty, lprops->flags);
712 
713  flags = lprops->flags | LPROPS_TAKEN | LPROPS_INDEX;
714  lprops = ubifs_change_lp(c, lprops, c->leb_size, 0, flags, 0);
715  if (IS_ERR(lprops)) {
716  err = PTR_ERR(lprops);
717  goto out;
718  }
719 
720  ubifs_release_lprops(c);
721 
722  /*
723  * Ensure that empty LEBs have been unmapped. They may not have been,
724  * for example, because of an unclean unmount. Also LEBs that were
725  * freeable LEBs (free + dirty == leb_size) will not have been unmapped.
726  */
727  err = ubifs_leb_unmap(c, lnum);
728  if (err) {
731  return err;
732  }
733 
734  return lnum;
735 
736 out:
737  ubifs_release_lprops(c);
738  return err;
739 }
740 
741 static int cmp_dirty_idx(const struct ubifs_lprops **a,
742  const struct ubifs_lprops **b)
743 {
744  const struct ubifs_lprops *lpa = *a;
745  const struct ubifs_lprops *lpb = *b;
746 
747  return lpa->dirty + lpa->free - lpb->dirty - lpb->free;
748 }
749 
750 static void swap_dirty_idx(struct ubifs_lprops **a, struct ubifs_lprops **b,
751  int size)
752 {
753  struct ubifs_lprops *t = *a;
754 
755  *a = *b;
756  *b = t;
757 }
758 
768 {
769  int i;
770 
771  ubifs_get_lprops(c);
772  /* Copy the LPROPS_DIRTY_IDX heap */
773  c->dirty_idx.cnt = c->lpt_heap[LPROPS_DIRTY_IDX - 1].cnt;
774  memcpy(c->dirty_idx.arr, c->lpt_heap[LPROPS_DIRTY_IDX - 1].arr,
775  sizeof(void *) * c->dirty_idx.cnt);
776  /* Sort it so that the dirtiest is now at the end */
777  sort(c->dirty_idx.arr, c->dirty_idx.cnt, sizeof(void *),
778  (int (*)(const void *, const void *))cmp_dirty_idx,
779  (void (*)(void *, void *, int))swap_dirty_idx);
780  dbg_find("found %d dirty index LEBs", c->dirty_idx.cnt);
781  if (c->dirty_idx.cnt)
782  dbg_find("dirtiest index LEB is %d with dirty %d and free %d",
783  c->dirty_idx.arr[c->dirty_idx.cnt - 1]->lnum,
784  c->dirty_idx.arr[c->dirty_idx.cnt - 1]->dirty,
785  c->dirty_idx.arr[c->dirty_idx.cnt - 1]->free);
786  /* Replace the lprops pointers with LEB numbers */
787  for (i = 0; i < c->dirty_idx.cnt; i++)
788  c->dirty_idx.arr[i] = (void *)(size_t)c->dirty_idx.arr[i]->lnum;
789  ubifs_release_lprops(c);
790  return 0;
791 }
792 
805 static int scan_dirty_idx_cb(struct ubifs_info *c,
806  const struct ubifs_lprops *lprops, int in_tree,
807  struct scan_data *data)
808 {
809  int ret = LPT_SCAN_CONTINUE;
810 
811  /* Exclude LEBs that are currently in use */
812  if (lprops->flags & LPROPS_TAKEN)
813  return LPT_SCAN_CONTINUE;
814  /* Determine whether to add these LEB properties to the tree */
815  if (!in_tree && valuable(c, lprops))
816  ret |= LPT_SCAN_ADD;
817  /* Exclude non-index LEBs */
818  if (!(lprops->flags & LPROPS_INDEX))
819  return ret;
820  /* Exclude LEBs with too little space */
821  if (lprops->free + lprops->dirty < c->min_idx_node_sz)
822  return ret;
823  /* Finally we found space */
824  data->lnum = lprops->lnum;
825  return LPT_SCAN_ADD | LPT_SCAN_STOP;
826 }
827 
838 static int find_dirty_idx_leb(struct ubifs_info *c)
839 {
840  const struct ubifs_lprops *lprops;
841  struct ubifs_lpt_heap *heap;
842  struct scan_data data;
843  int err, i, ret;
844 
845  /* Check all structures in memory first */
846  data.lnum = -1;
847  heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1];
848  for (i = 0; i < heap->cnt; i++) {
849  lprops = heap->arr[i];
850  ret = scan_dirty_idx_cb(c, lprops, 1, &data);
851  if (ret & LPT_SCAN_STOP)
852  goto found;
853  }
854  list_for_each_entry(lprops, &c->frdi_idx_list, list) {
855  ret = scan_dirty_idx_cb(c, lprops, 1, &data);
856  if (ret & LPT_SCAN_STOP)
857  goto found;
858  }
859  list_for_each_entry(lprops, &c->uncat_list, list) {
860  ret = scan_dirty_idx_cb(c, lprops, 1, &data);
861  if (ret & LPT_SCAN_STOP)
862  goto found;
863  }
864  if (c->pnodes_have >= c->pnode_cnt)
865  /* All pnodes are in memory, so skip scan */
866  return -ENOSPC;
867  err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum,
868  (ubifs_lpt_scan_callback)scan_dirty_idx_cb,
869  &data);
870  if (err)
871  return err;
872 found:
873  ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt);
874  c->lscan_lnum = data.lnum;
875  lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
876  if (IS_ERR(lprops))
877  return PTR_ERR(lprops);
878  ubifs_assert(lprops->lnum == data.lnum);
879  ubifs_assert(lprops->free + lprops->dirty >= c->min_idx_node_sz);
880  ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
881  ubifs_assert((lprops->flags & LPROPS_INDEX));
882 
883  dbg_find("found dirty LEB %d, free %d, dirty %d, flags %#x",
884  lprops->lnum, lprops->free, lprops->dirty, lprops->flags);
885 
886  lprops = ubifs_change_lp(c, lprops, LPROPS_NC, LPROPS_NC,
887  lprops->flags | LPROPS_TAKEN, 0);
888  if (IS_ERR(lprops))
889  return PTR_ERR(lprops);
890 
891  return lprops->lnum;
892 }
893 
898 static int get_idx_gc_leb(struct ubifs_info *c)
899 {
900  const struct ubifs_lprops *lp;
901  int err, lnum;
902 
903  err = ubifs_get_idx_gc_leb(c);
904  if (err < 0)
905  return err;
906  lnum = err;
907  /*
908  * The LEB was due to be unmapped after the commit but
909  * it is needed now for this commit.
910  */
911  lp = ubifs_lpt_lookup_dirty(c, lnum);
912  if (IS_ERR(lp))
913  return PTR_ERR(lp);
914  lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC,
915  lp->flags | LPROPS_INDEX, -1);
916  if (IS_ERR(lp))
917  return PTR_ERR(lp);
918  dbg_find("LEB %d, dirty %d and free %d flags %#x",
919  lp->lnum, lp->dirty, lp->free, lp->flags);
920  return lnum;
921 }
922 
927 static int find_dirtiest_idx_leb(struct ubifs_info *c)
928 {
929  const struct ubifs_lprops *lp;
930  int lnum;
931 
932  while (1) {
933  if (!c->dirty_idx.cnt)
934  return -ENOSPC;
935  /* The lprops pointers were replaced by LEB numbers */
936  lnum = (size_t)c->dirty_idx.arr[--c->dirty_idx.cnt];
937  lp = ubifs_lpt_lookup(c, lnum);
938  if (IS_ERR(lp))
939  return PTR_ERR(lp);
940  if ((lp->flags & LPROPS_TAKEN) || !(lp->flags & LPROPS_INDEX))
941  continue;
942  lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC,
943  lp->flags | LPROPS_TAKEN, 0);
944  if (IS_ERR(lp))
945  return PTR_ERR(lp);
946  break;
947  }
948  dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty,
949  lp->free, lp->flags);
952  return lnum;
953 }
954 
964 {
965  int err;
966 
967  ubifs_get_lprops(c);
968 
969  /*
970  * We made an array of the dirtiest index LEB numbers as at the start of
971  * last commit. Try that array first.
972  */
973  err = find_dirtiest_idx_leb(c);
974 
975  /* Next try scanning the entire LPT */
976  if (err == -ENOSPC)
977  err = find_dirty_idx_leb(c);
978 
979  /* Finally take any index LEBs awaiting trivial GC */
980  if (err == -ENOSPC)
981  err = get_idx_gc_leb(c);
982 
983  ubifs_release_lprops(c);
984  return err;
985 }