Lines Matching +full:- +full:c

4  * Copyright (C) 2006-2008 Nokia Corporation.
6 * SPDX-License-Identifier: GPL-2.0+
26 * get_heap_comp_val - get the LEB properties value for heap comparisons.
34 return lprops->free; in get_heap_comp_val()
36 return lprops->free + lprops->dirty; in get_heap_comp_val()
38 return lprops->dirty; in get_heap_comp_val()
43 * move_up_lpt_heap - move a new heap entry up as far as possible.
44 * @c: UBIFS file-system description object
54 static void move_up_lpt_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, in move_up_lpt_heap() argument
59 hpos = lprops->hpos; in move_up_lpt_heap()
65 int ppos = (hpos - 1) / 2; in move_up_lpt_heap()
67 val2 = get_heap_comp_val(heap->arr[ppos], cat); in move_up_lpt_heap()
71 heap->arr[ppos]->hpos = hpos; in move_up_lpt_heap()
72 heap->arr[hpos] = heap->arr[ppos]; in move_up_lpt_heap()
73 heap->arr[ppos] = lprops; in move_up_lpt_heap()
74 lprops->hpos = ppos; in move_up_lpt_heap()
80 * adjust_lpt_heap - move a changed heap entry up or down the heap.
81 * @c: UBIFS file-system description object
91 static void adjust_lpt_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, in adjust_lpt_heap() argument
99 int ppos = (hpos - 1) / 2; in adjust_lpt_heap()
101 val2 = get_heap_comp_val(heap->arr[ppos], cat); in adjust_lpt_heap()
105 heap->arr[ppos]->hpos = hpos; in adjust_lpt_heap()
106 heap->arr[hpos] = heap->arr[ppos]; in adjust_lpt_heap()
107 heap->arr[ppos] = lprops; in adjust_lpt_heap()
108 lprops->hpos = ppos; in adjust_lpt_heap()
112 ppos = (hpos - 1) / 2; in adjust_lpt_heap()
113 val2 = get_heap_comp_val(heap->arr[ppos], cat); in adjust_lpt_heap()
125 if (cpos >= heap->cnt) in adjust_lpt_heap()
127 val2 = get_heap_comp_val(heap->arr[cpos], cat); in adjust_lpt_heap()
130 if (cpos + 1 < heap->cnt) { in adjust_lpt_heap()
131 val3 = get_heap_comp_val(heap->arr[cpos + 1], in adjust_lpt_heap()
136 heap->arr[cpos]->hpos = hpos; in adjust_lpt_heap()
137 heap->arr[hpos] = heap->arr[cpos]; in adjust_lpt_heap()
138 heap->arr[cpos] = lprops; in adjust_lpt_heap()
139 lprops->hpos = cpos; in adjust_lpt_heap()
145 if (cpos >= heap->cnt) in adjust_lpt_heap()
147 val3 = get_heap_comp_val(heap->arr[cpos], cat); in adjust_lpt_heap()
150 heap->arr[cpos]->hpos = hpos; in adjust_lpt_heap()
151 heap->arr[hpos] = heap->arr[cpos]; in adjust_lpt_heap()
152 heap->arr[cpos] = lprops; in adjust_lpt_heap()
153 lprops->hpos = cpos; in adjust_lpt_heap()
162 * add_to_lpt_heap - add LEB properties to a LEB category heap.
163 * @c: UBIFS file-system description object
170 static int add_to_lpt_heap(struct ubifs_info *c, struct ubifs_lprops *lprops, in add_to_lpt_heap() argument
173 struct ubifs_lpt_heap *heap = &c->lpt_heap[cat - 1]; in add_to_lpt_heap()
175 if (heap->cnt >= heap->max_cnt) { in add_to_lpt_heap()
176 const int b = LPT_HEAP_SZ / 2 - 1; in add_to_lpt_heap()
184 ubifs_assert(cpos < heap->cnt); in add_to_lpt_heap()
187 val2 = get_heap_comp_val(heap->arr[cpos], cat); in add_to_lpt_heap()
191 lp = heap->arr[cpos]; in add_to_lpt_heap()
192 lp->flags &= ~LPROPS_CAT_MASK; in add_to_lpt_heap()
193 lp->flags |= LPROPS_UNCAT; in add_to_lpt_heap()
194 list_add(&lp->list, &c->uncat_list); in add_to_lpt_heap()
195 lprops->hpos = cpos; in add_to_lpt_heap()
196 heap->arr[cpos] = lprops; in add_to_lpt_heap()
197 move_up_lpt_heap(c, heap, lprops, cat); in add_to_lpt_heap()
198 dbg_check_heap(c, heap, cat, lprops->hpos); in add_to_lpt_heap()
201 dbg_check_heap(c, heap, cat, -1); in add_to_lpt_heap()
204 lprops->hpos = heap->cnt++; in add_to_lpt_heap()
205 heap->arr[lprops->hpos] = lprops; in add_to_lpt_heap()
206 move_up_lpt_heap(c, heap, lprops, cat); in add_to_lpt_heap()
207 dbg_check_heap(c, heap, cat, lprops->hpos); in add_to_lpt_heap()
213 * remove_from_lpt_heap - remove LEB properties from a LEB category heap.
214 * @c: UBIFS file-system description object
218 static void remove_from_lpt_heap(struct ubifs_info *c, in remove_from_lpt_heap() argument
222 int hpos = lprops->hpos; in remove_from_lpt_heap()
224 heap = &c->lpt_heap[cat - 1]; in remove_from_lpt_heap()
225 ubifs_assert(hpos >= 0 && hpos < heap->cnt); in remove_from_lpt_heap()
226 ubifs_assert(heap->arr[hpos] == lprops); in remove_from_lpt_heap()
227 heap->cnt -= 1; in remove_from_lpt_heap()
228 if (hpos < heap->cnt) { in remove_from_lpt_heap()
229 heap->arr[hpos] = heap->arr[heap->cnt]; in remove_from_lpt_heap()
230 heap->arr[hpos]->hpos = hpos; in remove_from_lpt_heap()
231 adjust_lpt_heap(c, heap, heap->arr[hpos], hpos, cat); in remove_from_lpt_heap()
233 dbg_check_heap(c, heap, cat, -1); in remove_from_lpt_heap()
237 * lpt_heap_replace - replace lprops in a category heap.
238 * @c: UBIFS file-system description object
248 static void lpt_heap_replace(struct ubifs_info *c, in lpt_heap_replace() argument
253 int hpos = new_lprops->hpos; in lpt_heap_replace()
255 heap = &c->lpt_heap[cat - 1]; in lpt_heap_replace()
256 heap->arr[hpos] = new_lprops; in lpt_heap_replace()
260 * ubifs_add_to_cat - add LEB properties to a category list or heap.
261 * @c: UBIFS file-system description object
267 void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, in ubifs_add_to_cat() argument
274 if (add_to_lpt_heap(c, lprops, cat)) in ubifs_add_to_cat()
276 /* No more room on heap so make it un-categorized */ in ubifs_add_to_cat()
280 list_add(&lprops->list, &c->uncat_list); in ubifs_add_to_cat()
283 list_add(&lprops->list, &c->empty_list); in ubifs_add_to_cat()
286 list_add(&lprops->list, &c->freeable_list); in ubifs_add_to_cat()
287 c->freeable_cnt += 1; in ubifs_add_to_cat()
290 list_add(&lprops->list, &c->frdi_idx_list); in ubifs_add_to_cat()
296 lprops->flags &= ~LPROPS_CAT_MASK; in ubifs_add_to_cat()
297 lprops->flags |= cat; in ubifs_add_to_cat()
298 c->in_a_category_cnt += 1; in ubifs_add_to_cat()
299 ubifs_assert(c->in_a_category_cnt <= c->main_lebs); in ubifs_add_to_cat()
303 * ubifs_remove_from_cat - remove LEB properties from a category list or heap.
304 * @c: UBIFS file-system description object
310 static void ubifs_remove_from_cat(struct ubifs_info *c, in ubifs_remove_from_cat() argument
317 remove_from_lpt_heap(c, lprops, cat); in ubifs_remove_from_cat()
320 c->freeable_cnt -= 1; in ubifs_remove_from_cat()
321 ubifs_assert(c->freeable_cnt >= 0); in ubifs_remove_from_cat()
326 ubifs_assert(!list_empty(&lprops->list)); in ubifs_remove_from_cat()
327 list_del(&lprops->list); in ubifs_remove_from_cat()
333 c->in_a_category_cnt -= 1; in ubifs_remove_from_cat()
334 ubifs_assert(c->in_a_category_cnt >= 0); in ubifs_remove_from_cat()
338 * ubifs_replace_cat - replace lprops in a category list or heap.
339 * @c: UBIFS file-system description object
347 void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops, in ubifs_replace_cat() argument
352 cat = new_lprops->flags & LPROPS_CAT_MASK; in ubifs_replace_cat()
357 lpt_heap_replace(c, old_lprops, new_lprops, cat); in ubifs_replace_cat()
363 list_replace(&old_lprops->list, &new_lprops->list); in ubifs_replace_cat()
371 * ubifs_ensure_cat - ensure LEB properties are categorized.
372 * @c: UBIFS file-system description object
376 * un-categorized even though it has enough space for us now. If that is the
379 void ubifs_ensure_cat(struct ubifs_info *c, struct ubifs_lprops *lprops) in ubifs_ensure_cat() argument
381 int cat = lprops->flags & LPROPS_CAT_MASK; in ubifs_ensure_cat()
385 cat = ubifs_categorize_lprops(c, lprops); in ubifs_ensure_cat()
388 ubifs_remove_from_cat(c, lprops, LPROPS_UNCAT); in ubifs_ensure_cat()
389 ubifs_add_to_cat(c, lprops, cat); in ubifs_ensure_cat()
393 * ubifs_categorize_lprops - categorize LEB properties.
394 * @c: UBIFS file-system description object
402 int ubifs_categorize_lprops(const struct ubifs_info *c, in ubifs_categorize_lprops() argument
405 if (lprops->flags & LPROPS_TAKEN) in ubifs_categorize_lprops()
408 if (lprops->free == c->leb_size) { in ubifs_categorize_lprops()
409 ubifs_assert(!(lprops->flags & LPROPS_INDEX)); in ubifs_categorize_lprops()
413 if (lprops->free + lprops->dirty == c->leb_size) { in ubifs_categorize_lprops()
414 if (lprops->flags & LPROPS_INDEX) in ubifs_categorize_lprops()
420 if (lprops->flags & LPROPS_INDEX) { in ubifs_categorize_lprops()
421 if (lprops->dirty + lprops->free >= c->min_idx_node_sz) in ubifs_categorize_lprops()
424 if (lprops->dirty >= c->dead_wm && in ubifs_categorize_lprops()
425 lprops->dirty > lprops->free) in ubifs_categorize_lprops()
427 if (lprops->free > 0) in ubifs_categorize_lprops()
435 * change_category - change LEB properties category.
436 * @c: UBIFS file-system description object
437 * @lprops: LEB properties to re-categorize
440 * properties change they must be re-categorized.
442 static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops) in change_category() argument
444 int old_cat = lprops->flags & LPROPS_CAT_MASK; in change_category()
445 int new_cat = ubifs_categorize_lprops(c, lprops); in change_category()
453 heap = &c->lpt_heap[new_cat - 1]; in change_category()
454 adjust_lpt_heap(c, heap, lprops, lprops->hpos, new_cat); in change_category()
456 ubifs_remove_from_cat(c, lprops, old_cat); in change_category()
457 ubifs_add_to_cat(c, lprops, new_cat); in change_category()
462 * ubifs_calc_dark - calculate LEB dark space size.
463 * @c: the UBIFS file-system description object
473 int ubifs_calc_dark(const struct ubifs_info *c, int spc) in ubifs_calc_dark() argument
477 if (spc < c->dark_wm) in ubifs_calc_dark()
485 if (spc - c->dark_wm < MIN_WRITE_SZ) in ubifs_calc_dark()
486 return spc - MIN_WRITE_SZ; in ubifs_calc_dark()
488 return c->dark_wm; in ubifs_calc_dark()
492 * is_lprops_dirty - determine if LEB properties are dirty.
493 * @c: the UBIFS file-system description object
496 static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops) in is_lprops_dirty() argument
501 pos = (lprops->lnum - c->main_first) & (UBIFS_LPT_FANOUT - 1); in is_lprops_dirty()
502 pnode = (struct ubifs_pnode *)container_of(lprops - pos, in is_lprops_dirty()
505 return !test_bit(COW_CNODE, &pnode->flags) && in is_lprops_dirty()
506 test_bit(DIRTY_CNODE, &pnode->flags); in is_lprops_dirty()
510 * ubifs_change_lp - change LEB properties.
511 * @c: the UBIFS file-system description object
526 const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, in ubifs_change_lp() argument
538 lprops->lnum, free, dirty, flags); in ubifs_change_lp()
540 ubifs_assert(mutex_is_locked(&c->lp_mutex)); in ubifs_change_lp()
541 ubifs_assert(c->lst.empty_lebs >= 0 && in ubifs_change_lp()
542 c->lst.empty_lebs <= c->main_lebs); in ubifs_change_lp()
543 ubifs_assert(c->freeable_cnt >= 0); in ubifs_change_lp()
544 ubifs_assert(c->freeable_cnt <= c->main_lebs); in ubifs_change_lp()
545 ubifs_assert(c->lst.taken_empty_lebs >= 0); in ubifs_change_lp()
546 ubifs_assert(c->lst.taken_empty_lebs <= c->lst.empty_lebs); in ubifs_change_lp()
547 ubifs_assert(!(c->lst.total_free & 7) && !(c->lst.total_dirty & 7)); in ubifs_change_lp()
548 ubifs_assert(!(c->lst.total_dead & 7) && !(c->lst.total_dark & 7)); in ubifs_change_lp()
549 ubifs_assert(!(c->lst.total_used & 7)); in ubifs_change_lp()
553 if (!is_lprops_dirty(c, lprops)) { in ubifs_change_lp()
554 lprops = ubifs_lpt_lookup_dirty(c, lprops->lnum); in ubifs_change_lp()
558 ubifs_assert(lprops == ubifs_lpt_lookup_dirty(c, lprops->lnum)); in ubifs_change_lp()
560 ubifs_assert(!(lprops->free & 7) && !(lprops->dirty & 7)); in ubifs_change_lp()
562 spin_lock(&c->space_lock); in ubifs_change_lp()
563 if ((lprops->flags & LPROPS_TAKEN) && lprops->free == c->leb_size) in ubifs_change_lp()
564 c->lst.taken_empty_lebs -= 1; in ubifs_change_lp()
566 if (!(lprops->flags & LPROPS_INDEX)) { in ubifs_change_lp()
569 old_spc = lprops->free + lprops->dirty; in ubifs_change_lp()
570 if (old_spc < c->dead_wm) in ubifs_change_lp()
571 c->lst.total_dead -= old_spc; in ubifs_change_lp()
573 c->lst.total_dark -= ubifs_calc_dark(c, old_spc); in ubifs_change_lp()
575 c->lst.total_used -= c->leb_size - old_spc; in ubifs_change_lp()
580 c->lst.total_free += free - lprops->free; in ubifs_change_lp()
583 if (free == c->leb_size) { in ubifs_change_lp()
584 if (lprops->free != c->leb_size) in ubifs_change_lp()
585 c->lst.empty_lebs += 1; in ubifs_change_lp()
586 } else if (lprops->free == c->leb_size) in ubifs_change_lp()
587 c->lst.empty_lebs -= 1; in ubifs_change_lp()
588 lprops->free = free; in ubifs_change_lp()
593 c->lst.total_dirty += dirty - lprops->dirty; in ubifs_change_lp()
594 lprops->dirty = dirty; in ubifs_change_lp()
599 if ((lprops->flags & LPROPS_INDEX)) { in ubifs_change_lp()
601 c->lst.idx_lebs -= 1; in ubifs_change_lp()
603 c->lst.idx_lebs += 1; in ubifs_change_lp()
604 lprops->flags = flags; in ubifs_change_lp()
607 if (!(lprops->flags & LPROPS_INDEX)) { in ubifs_change_lp()
610 new_spc = lprops->free + lprops->dirty; in ubifs_change_lp()
611 if (new_spc < c->dead_wm) in ubifs_change_lp()
612 c->lst.total_dead += new_spc; in ubifs_change_lp()
614 c->lst.total_dark += ubifs_calc_dark(c, new_spc); in ubifs_change_lp()
616 c->lst.total_used += c->leb_size - new_spc; in ubifs_change_lp()
619 if ((lprops->flags & LPROPS_TAKEN) && lprops->free == c->leb_size) in ubifs_change_lp()
620 c->lst.taken_empty_lebs += 1; in ubifs_change_lp()
622 change_category(c, lprops); in ubifs_change_lp()
623 c->idx_gc_cnt += idx_gc_cnt; in ubifs_change_lp()
624 spin_unlock(&c->space_lock); in ubifs_change_lp()
629 * ubifs_get_lp_stats - get lprops statistics.
630 * @c: UBIFS file-system description object
633 void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *lst) in ubifs_get_lp_stats() argument
635 spin_lock(&c->space_lock); in ubifs_get_lp_stats()
636 memcpy(lst, &c->lst, sizeof(struct ubifs_lp_stats)); in ubifs_get_lp_stats()
637 spin_unlock(&c->space_lock); in ubifs_get_lp_stats()
641 * ubifs_change_one_lp - change LEB properties.
642 * @c: the UBIFS file-system description object
655 int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, in ubifs_change_one_lp() argument
661 ubifs_get_lprops(c); in ubifs_change_one_lp()
663 lp = ubifs_lpt_lookup_dirty(c, lnum); in ubifs_change_one_lp()
669 flags = (lp->flags | flags_set) & ~flags_clean; in ubifs_change_one_lp()
670 lp = ubifs_change_lp(c, lp, free, dirty, flags, idx_gc_cnt); in ubifs_change_one_lp()
675 ubifs_release_lprops(c); in ubifs_change_one_lp()
677 ubifs_err(c, "cannot change properties of LEB %d, error %d", in ubifs_change_one_lp()
683 * ubifs_update_one_lp - update LEB properties.
684 * @c: the UBIFS file-system description object
694 int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, in ubifs_update_one_lp() argument
700 ubifs_get_lprops(c); in ubifs_update_one_lp()
702 lp = ubifs_lpt_lookup_dirty(c, lnum); in ubifs_update_one_lp()
708 flags = (lp->flags | flags_set) & ~flags_clean; in ubifs_update_one_lp()
709 lp = ubifs_change_lp(c, lp, free, lp->dirty + dirty, flags, 0); in ubifs_update_one_lp()
714 ubifs_release_lprops(c); in ubifs_update_one_lp()
716 ubifs_err(c, "cannot update properties of LEB %d, error %d", in ubifs_update_one_lp()
722 * ubifs_read_one_lp - read LEB properties.
723 * @c: the UBIFS file-system description object
731 int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp) in ubifs_read_one_lp() argument
736 ubifs_get_lprops(c); in ubifs_read_one_lp()
738 lpp = ubifs_lpt_lookup(c, lnum); in ubifs_read_one_lp()
741 ubifs_err(c, "cannot read properties of LEB %d, error %d", in ubifs_read_one_lp()
749 ubifs_release_lprops(c); in ubifs_read_one_lp()
754 * ubifs_fast_find_free - try to find a LEB with free space quickly.
755 * @c: the UBIFS file-system description object
760 const struct ubifs_lprops *ubifs_fast_find_free(struct ubifs_info *c) in ubifs_fast_find_free() argument
765 ubifs_assert(mutex_is_locked(&c->lp_mutex)); in ubifs_fast_find_free()
767 heap = &c->lpt_heap[LPROPS_FREE - 1]; in ubifs_fast_find_free()
768 if (heap->cnt == 0) in ubifs_fast_find_free()
771 lprops = heap->arr[0]; in ubifs_fast_find_free()
772 ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); in ubifs_fast_find_free()
773 ubifs_assert(!(lprops->flags & LPROPS_INDEX)); in ubifs_fast_find_free()
778 * ubifs_fast_find_empty - try to find an empty LEB quickly.
779 * @c: the UBIFS file-system description object
784 const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c) in ubifs_fast_find_empty() argument
788 ubifs_assert(mutex_is_locked(&c->lp_mutex)); in ubifs_fast_find_empty()
790 if (list_empty(&c->empty_list)) in ubifs_fast_find_empty()
793 lprops = list_entry(c->empty_list.next, struct ubifs_lprops, list); in ubifs_fast_find_empty()
794 ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); in ubifs_fast_find_empty()
795 ubifs_assert(!(lprops->flags & LPROPS_INDEX)); in ubifs_fast_find_empty()
796 ubifs_assert(lprops->free == c->leb_size); in ubifs_fast_find_empty()
801 * ubifs_fast_find_freeable - try to find a freeable LEB quickly.
802 * @c: the UBIFS file-system description object
807 const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c) in ubifs_fast_find_freeable() argument
811 ubifs_assert(mutex_is_locked(&c->lp_mutex)); in ubifs_fast_find_freeable()
813 if (list_empty(&c->freeable_list)) in ubifs_fast_find_freeable()
816 lprops = list_entry(c->freeable_list.next, struct ubifs_lprops, list); in ubifs_fast_find_freeable()
817 ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); in ubifs_fast_find_freeable()
818 ubifs_assert(!(lprops->flags & LPROPS_INDEX)); in ubifs_fast_find_freeable()
819 ubifs_assert(lprops->free + lprops->dirty == c->leb_size); in ubifs_fast_find_freeable()
820 ubifs_assert(c->freeable_cnt > 0); in ubifs_fast_find_freeable()
825 * ubifs_fast_find_frdi_idx - try to find a freeable index LEB quickly.
826 * @c: the UBIFS file-system description object
831 const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c) in ubifs_fast_find_frdi_idx() argument
835 ubifs_assert(mutex_is_locked(&c->lp_mutex)); in ubifs_fast_find_frdi_idx()
837 if (list_empty(&c->frdi_idx_list)) in ubifs_fast_find_frdi_idx()
840 lprops = list_entry(c->frdi_idx_list.next, struct ubifs_lprops, list); in ubifs_fast_find_frdi_idx()
841 ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); in ubifs_fast_find_frdi_idx()
842 ubifs_assert((lprops->flags & LPROPS_INDEX)); in ubifs_fast_find_frdi_idx()
843 ubifs_assert(lprops->free + lprops->dirty == c->leb_size); in ubifs_fast_find_frdi_idx()
852 * dbg_check_cats - check category heaps and lists.
853 * @c: UBIFS file-system description object
857 int dbg_check_cats(struct ubifs_info *c) in dbg_check_cats() argument
863 if (!dbg_is_chk_gen(c) && !dbg_is_chk_lprops(c)) in dbg_check_cats()
866 list_for_each_entry(lprops, &c->empty_list, list) { in dbg_check_cats()
867 if (lprops->free != c->leb_size) { in dbg_check_cats()
868 ubifs_err(c, "non-empty LEB %d on empty list (free %d dirty %d flags %d)", in dbg_check_cats()
869 lprops->lnum, lprops->free, lprops->dirty, in dbg_check_cats()
870 lprops->flags); in dbg_check_cats()
871 return -EINVAL; in dbg_check_cats()
873 if (lprops->flags & LPROPS_TAKEN) { in dbg_check_cats()
874 ubifs_err(c, "taken LEB %d on empty list (free %d dirty %d flags %d)", in dbg_check_cats()
875 lprops->lnum, lprops->free, lprops->dirty, in dbg_check_cats()
876 lprops->flags); in dbg_check_cats()
877 return -EINVAL; in dbg_check_cats()
882 list_for_each_entry(lprops, &c->freeable_list, list) { in dbg_check_cats()
883 if (lprops->free + lprops->dirty != c->leb_size) { in dbg_check_cats()
884 ubifs_err(c, "non-freeable LEB %d on freeable list (free %d dirty %d flags %d)", in dbg_check_cats()
885 lprops->lnum, lprops->free, lprops->dirty, in dbg_check_cats()
886 lprops->flags); in dbg_check_cats()
887 return -EINVAL; in dbg_check_cats()
889 if (lprops->flags & LPROPS_TAKEN) { in dbg_check_cats()
890 ubifs_err(c, "taken LEB %d on freeable list (free %d dirty %d flags %d)", in dbg_check_cats()
891 lprops->lnum, lprops->free, lprops->dirty, in dbg_check_cats()
892 lprops->flags); in dbg_check_cats()
893 return -EINVAL; in dbg_check_cats()
897 if (i != c->freeable_cnt) { in dbg_check_cats()
898 ubifs_err(c, "freeable list count %d expected %d", i, in dbg_check_cats()
899 c->freeable_cnt); in dbg_check_cats()
900 return -EINVAL; in dbg_check_cats()
904 list_for_each(pos, &c->idx_gc) in dbg_check_cats()
906 if (i != c->idx_gc_cnt) { in dbg_check_cats()
907 ubifs_err(c, "idx_gc list count %d expected %d", i, in dbg_check_cats()
908 c->idx_gc_cnt); in dbg_check_cats()
909 return -EINVAL; in dbg_check_cats()
912 list_for_each_entry(lprops, &c->frdi_idx_list, list) { in dbg_check_cats()
913 if (lprops->free + lprops->dirty != c->leb_size) { in dbg_check_cats()
914 ubifs_err(c, "non-freeable LEB %d on frdi_idx list (free %d dirty %d flags %d)", in dbg_check_cats()
915 lprops->lnum, lprops->free, lprops->dirty, in dbg_check_cats()
916 lprops->flags); in dbg_check_cats()
917 return -EINVAL; in dbg_check_cats()
919 if (lprops->flags & LPROPS_TAKEN) { in dbg_check_cats()
920 ubifs_err(c, "taken LEB %d on frdi_idx list (free %d dirty %d flags %d)", in dbg_check_cats()
921 lprops->lnum, lprops->free, lprops->dirty, in dbg_check_cats()
922 lprops->flags); in dbg_check_cats()
923 return -EINVAL; in dbg_check_cats()
925 if (!(lprops->flags & LPROPS_INDEX)) { in dbg_check_cats()
926 ubifs_err(c, "non-index LEB %d on frdi_idx list (free %d dirty %d flags %d)", in dbg_check_cats()
927 lprops->lnum, lprops->free, lprops->dirty, in dbg_check_cats()
928 lprops->flags); in dbg_check_cats()
929 return -EINVAL; in dbg_check_cats()
934 struct ubifs_lpt_heap *heap = &c->lpt_heap[cat - 1]; in dbg_check_cats()
936 for (i = 0; i < heap->cnt; i++) { in dbg_check_cats()
937 lprops = heap->arr[i]; in dbg_check_cats()
939 ubifs_err(c, "null ptr in LPT heap cat %d", cat); in dbg_check_cats()
940 return -EINVAL; in dbg_check_cats()
942 if (lprops->hpos != i) { in dbg_check_cats()
943 ubifs_err(c, "bad ptr in LPT heap cat %d", cat); in dbg_check_cats()
944 return -EINVAL; in dbg_check_cats()
946 if (lprops->flags & LPROPS_TAKEN) { in dbg_check_cats()
947 ubifs_err(c, "taken LEB in LPT heap cat %d", cat); in dbg_check_cats()
948 return -EINVAL; in dbg_check_cats()
956 void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, in dbg_check_heap() argument
961 if (!dbg_is_chk_gen(c) && !dbg_is_chk_lprops(c)) in dbg_check_heap()
964 for (i = 0; i < heap->cnt; i++) { in dbg_check_heap()
965 struct ubifs_lprops *lprops = heap->arr[i]; in dbg_check_heap()
969 if ((lprops->flags & LPROPS_CAT_MASK) != cat) { in dbg_check_heap()
973 if (lprops->hpos != i) { in dbg_check_heap()
977 lp = ubifs_lpt_lookup(c, lprops->lnum); in dbg_check_heap()
983 ubifs_err(c, "lprops %zx lp %zx lprops->lnum %d lp->lnum %d", in dbg_check_heap()
984 (size_t)lprops, (size_t)lp, lprops->lnum, in dbg_check_heap()
985 lp->lnum); in dbg_check_heap()
990 lp = heap->arr[j]; in dbg_check_heap()
995 if (lp->lnum == lprops->lnum) { in dbg_check_heap()
1003 ubifs_err(c, "failed cat %d hpos %d err %d", cat, i, err); in dbg_check_heap()
1005 ubifs_dump_heap(c, heap, cat); in dbg_check_heap()
1010 * scan_check_cb - scan callback.
1011 * @c: the UBIFS file-system description object
1021 static int scan_check_cb(struct ubifs_info *c, in scan_check_cb() argument
1027 int cat, lnum = lp->lnum, is_idx = 0, used = 0, free, dirty, ret; in scan_check_cb()
1030 cat = lp->flags & LPROPS_CAT_MASK; in scan_check_cb()
1032 cat = ubifs_categorize_lprops(c, lp); in scan_check_cb()
1033 if (cat != (lp->flags & LPROPS_CAT_MASK)) { in scan_check_cb()
1034 ubifs_err(c, "bad LEB category %d expected %d", in scan_check_cb()
1035 (lp->flags & LPROPS_CAT_MASK), cat); in scan_check_cb()
1036 return -EINVAL; in scan_check_cb()
1046 list = &c->empty_list; in scan_check_cb()
1049 list = &c->freeable_list; in scan_check_cb()
1052 list = &c->frdi_idx_list; in scan_check_cb()
1055 list = &c->uncat_list; in scan_check_cb()
1069 ubifs_err(c, "bad LPT list (category %d)", cat); in scan_check_cb()
1070 return -EINVAL; in scan_check_cb()
1077 struct ubifs_lpt_heap *heap = &c->lpt_heap[cat - 1]; in scan_check_cb()
1079 if ((lp->hpos != -1 && heap->arr[lp->hpos]->lnum != lnum) || in scan_check_cb()
1080 lp != heap->arr[lp->hpos]) { in scan_check_cb()
1081 ubifs_err(c, "bad LPT heap (category %d)", cat); in scan_check_cb()
1082 return -EINVAL; in scan_check_cb()
1086 buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); in scan_check_cb()
1088 return -ENOMEM; in scan_check_cb()
1092 * may contain garbage - do not scan them. in scan_check_cb()
1094 if (lp->free == c->leb_size) { in scan_check_cb()
1095 lst->empty_lebs += 1; in scan_check_cb()
1096 lst->total_free += c->leb_size; in scan_check_cb()
1097 lst->total_dark += ubifs_calc_dark(c, c->leb_size); in scan_check_cb()
1100 if (lp->free + lp->dirty == c->leb_size && in scan_check_cb()
1101 !(lp->flags & LPROPS_INDEX)) { in scan_check_cb()
1102 lst->total_free += lp->free; in scan_check_cb()
1103 lst->total_dirty += lp->dirty; in scan_check_cb()
1104 lst->total_dark += ubifs_calc_dark(c, c->leb_size); in scan_check_cb()
1108 sleb = ubifs_scan(c, lnum, 0, buf, 0); in scan_check_cb()
1111 if (ret == -EUCLEAN) { in scan_check_cb()
1112 ubifs_dump_lprops(c); in scan_check_cb()
1113 ubifs_dump_budg(c, &c->bi); in scan_check_cb()
1118 is_idx = -1; in scan_check_cb()
1119 list_for_each_entry(snod, &sleb->nodes, list) { in scan_check_cb()
1124 if (is_idx == -1) in scan_check_cb()
1125 is_idx = (snod->type == UBIFS_IDX_NODE) ? 1 : 0; in scan_check_cb()
1127 if (is_idx && snod->type != UBIFS_IDX_NODE) { in scan_check_cb()
1128 ubifs_err(c, "indexing node in data LEB %d:%d", in scan_check_cb()
1129 lnum, snod->offs); in scan_check_cb()
1133 if (snod->type == UBIFS_IDX_NODE) { in scan_check_cb()
1134 struct ubifs_idx_node *idx = snod->node; in scan_check_cb()
1136 key_read(c, ubifs_idx_key(c, idx), &snod->key); in scan_check_cb()
1137 level = le16_to_cpu(idx->level); in scan_check_cb()
1140 found = ubifs_tnc_has_node(c, &snod->key, level, lnum, in scan_check_cb()
1141 snod->offs, is_idx); in scan_check_cb()
1145 used += ALIGN(snod->len, 8); in scan_check_cb()
1149 free = c->leb_size - sleb->endpt; in scan_check_cb()
1150 dirty = sleb->endpt - used; in scan_check_cb()
1152 if (free > c->leb_size || free < 0 || dirty > c->leb_size || in scan_check_cb()
1154 ubifs_err(c, "bad calculated accounting for LEB %d: free %d, dirty %d", in scan_check_cb()
1159 if (lp->free + lp->dirty == c->leb_size && in scan_check_cb()
1160 free + dirty == c->leb_size) in scan_check_cb()
1161 if ((is_idx && !(lp->flags & LPROPS_INDEX)) || in scan_check_cb()
1162 (!is_idx && free == c->leb_size) || in scan_check_cb()
1163 lp->free == c->leb_size) { in scan_check_cb()
1171 free = lp->free; in scan_check_cb()
1172 dirty = lp->dirty; in scan_check_cb()
1176 if (is_idx && lp->free + lp->dirty == free + dirty && in scan_check_cb()
1177 lnum != c->ihead_lnum) { in scan_check_cb()
1181 * is because the in-the-gaps method may use free space or in scan_check_cb()
1182 * create free space (as a side-effect of using ubi_leb_change in scan_check_cb()
1186 * write to the free space at the end of an index LEB - except in scan_check_cb()
1187 * by the in-the-gaps method for which it is not a problem. in scan_check_cb()
1189 free = lp->free; in scan_check_cb()
1190 dirty = lp->dirty; in scan_check_cb()
1193 if (lp->free != free || lp->dirty != dirty) in scan_check_cb()
1196 if (is_idx && !(lp->flags & LPROPS_INDEX)) { in scan_check_cb()
1197 if (free == c->leb_size) in scan_check_cb()
1201 ubifs_err(c, "indexing node without indexing flag"); in scan_check_cb()
1206 if (!is_idx && (lp->flags & LPROPS_INDEX)) { in scan_check_cb()
1207 ubifs_err(c, "data node with indexing flag"); in scan_check_cb()
1211 if (free == c->leb_size) in scan_check_cb()
1212 lst->empty_lebs += 1; in scan_check_cb()
1215 lst->idx_lebs += 1; in scan_check_cb()
1217 if (!(lp->flags & LPROPS_INDEX)) in scan_check_cb()
1218 lst->total_used += c->leb_size - free - dirty; in scan_check_cb()
1219 lst->total_free += free; in scan_check_cb()
1220 lst->total_dirty += dirty; in scan_check_cb()
1222 if (!(lp->flags & LPROPS_INDEX)) { in scan_check_cb()
1225 if (spc < c->dead_wm) in scan_check_cb()
1226 lst->total_dead += spc; in scan_check_cb()
1228 lst->total_dark += ubifs_calc_dark(c, spc); in scan_check_cb()
1236 ubifs_err(c, "bad accounting of LEB %d: free %d, dirty %d flags %#x, should be free %d, dirty %d", in scan_check_cb()
1237 lnum, lp->free, lp->dirty, lp->flags, free, dirty); in scan_check_cb()
1238 ubifs_dump_leb(c, lnum); in scan_check_cb()
1241 ret = -EINVAL; in scan_check_cb()
1248 * dbg_check_lprops - check all LEB properties.
1249 * @c: UBIFS file-system description object
1252 * It returns zero if everything is fine, %-EINVAL if there is an inconsistency
1258 int dbg_check_lprops(struct ubifs_info *c) in dbg_check_lprops() argument
1263 if (!dbg_is_chk_lprops(c)) in dbg_check_lprops()
1270 for (i = 0; i < c->jhead_cnt; i++) { in dbg_check_lprops()
1271 err = ubifs_wbuf_sync(&c->jheads[i].wbuf); in dbg_check_lprops()
1277 err = ubifs_lpt_scan_nolock(c, c->main_first, c->leb_cnt - 1, in dbg_check_lprops()
1280 if (err && err != -ENOSPC) in dbg_check_lprops()
1283 if (lst.empty_lebs != c->lst.empty_lebs || in dbg_check_lprops()
1284 lst.idx_lebs != c->lst.idx_lebs || in dbg_check_lprops()
1285 lst.total_free != c->lst.total_free || in dbg_check_lprops()
1286 lst.total_dirty != c->lst.total_dirty || in dbg_check_lprops()
1287 lst.total_used != c->lst.total_used) { in dbg_check_lprops()
1288 ubifs_err(c, "bad overall accounting"); in dbg_check_lprops()
1289 …ubifs_err(c, "calculated: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_use… in dbg_check_lprops()
1292 …ubifs_err(c, "read from lprops: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, tot… in dbg_check_lprops()
1293 c->lst.empty_lebs, c->lst.idx_lebs, c->lst.total_free, in dbg_check_lprops()
1294 c->lst.total_dirty, c->lst.total_used); in dbg_check_lprops()
1295 err = -EINVAL; in dbg_check_lprops()
1299 if (lst.total_dead != c->lst.total_dead || in dbg_check_lprops()
1300 lst.total_dark != c->lst.total_dark) { in dbg_check_lprops()
1301 ubifs_err(c, "bad dead/dark space accounting"); in dbg_check_lprops()
1302 ubifs_err(c, "calculated: total_dead %lld, total_dark %lld", in dbg_check_lprops()
1304 ubifs_err(c, "read from lprops: total_dead %lld, total_dark %lld", in dbg_check_lprops()
1305 c->lst.total_dead, c->lst.total_dark); in dbg_check_lprops()
1306 err = -EINVAL; in dbg_check_lprops()
1310 err = dbg_check_cats(c); in dbg_check_lprops()