1*2b27bdccSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21e51764aSArtem Bityutskiy /*
31e51764aSArtem Bityutskiy * This file is part of UBIFS.
41e51764aSArtem Bityutskiy *
51e51764aSArtem Bityutskiy * Copyright (C) 2006-2008 Nokia Corporation.
61e51764aSArtem Bityutskiy *
71e51764aSArtem Bityutskiy * Authors: Artem Bityutskiy (Битюцкий Артём)
81e51764aSArtem Bityutskiy * Adrian Hunter
91e51764aSArtem Bityutskiy */
101e51764aSArtem Bityutskiy
111e51764aSArtem Bityutskiy /*
121e51764aSArtem Bityutskiy * This file contains functions for finding LEBs for various purposes e.g.
131e51764aSArtem Bityutskiy * garbage collection. In general, lprops category heaps and lists are used
141e51764aSArtem Bityutskiy * for fast access, falling back on scanning the LPT as a last resort.
151e51764aSArtem Bityutskiy */
161e51764aSArtem Bityutskiy
171e51764aSArtem Bityutskiy #include <linux/sort.h>
181e51764aSArtem Bityutskiy #include "ubifs.h"
191e51764aSArtem Bityutskiy
201e51764aSArtem Bityutskiy /**
211e51764aSArtem Bityutskiy * struct scan_data - data provided to scan callback functions
221e51764aSArtem Bityutskiy * @min_space: minimum number of bytes for which to scan
231e51764aSArtem Bityutskiy * @pick_free: whether it is OK to scan for empty LEBs
241e51764aSArtem Bityutskiy * @lnum: LEB number found is returned here
251e51764aSArtem Bityutskiy * @exclude_index: whether to exclude index LEBs
261e51764aSArtem Bityutskiy */
271e51764aSArtem Bityutskiy struct scan_data {
281e51764aSArtem Bityutskiy int min_space;
291e51764aSArtem Bityutskiy int pick_free;
301e51764aSArtem Bityutskiy int lnum;
311e51764aSArtem Bityutskiy int exclude_index;
321e51764aSArtem Bityutskiy };
331e51764aSArtem Bityutskiy
341e51764aSArtem Bityutskiy /**
351e51764aSArtem Bityutskiy * valuable - determine whether LEB properties are valuable.
361e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
371e51764aSArtem Bityutskiy * @lprops: LEB properties
381e51764aSArtem Bityutskiy *
391e51764aSArtem Bityutskiy * This function return %1 if the LEB properties should be added to the LEB
401e51764aSArtem Bityutskiy * properties tree in memory. Otherwise %0 is returned.
411e51764aSArtem Bityutskiy */
valuable(struct ubifs_info * c,const struct ubifs_lprops * lprops)421e51764aSArtem Bityutskiy static int valuable(struct ubifs_info *c, const struct ubifs_lprops *lprops)
431e51764aSArtem Bityutskiy {
441e51764aSArtem Bityutskiy int n, cat = lprops->flags & LPROPS_CAT_MASK;
451e51764aSArtem Bityutskiy struct ubifs_lpt_heap *heap;
461e51764aSArtem Bityutskiy
471e51764aSArtem Bityutskiy switch (cat) {
481e51764aSArtem Bityutskiy case LPROPS_DIRTY:
491e51764aSArtem Bityutskiy case LPROPS_DIRTY_IDX:
501e51764aSArtem Bityutskiy case LPROPS_FREE:
511e51764aSArtem Bityutskiy heap = &c->lpt_heap[cat - 1];
521e51764aSArtem Bityutskiy if (heap->cnt < heap->max_cnt)
531e51764aSArtem Bityutskiy return 1;
541e51764aSArtem Bityutskiy if (lprops->free + lprops->dirty >= c->dark_wm)
551e51764aSArtem Bityutskiy return 1;
561e51764aSArtem Bityutskiy return 0;
571e51764aSArtem Bityutskiy case LPROPS_EMPTY:
581e51764aSArtem Bityutskiy n = c->lst.empty_lebs + c->freeable_cnt -
591e51764aSArtem Bityutskiy c->lst.taken_empty_lebs;
601e51764aSArtem Bityutskiy if (n < c->lsave_cnt)
611e51764aSArtem Bityutskiy return 1;
621e51764aSArtem Bityutskiy return 0;
631e51764aSArtem Bityutskiy case LPROPS_FREEABLE:
641e51764aSArtem Bityutskiy return 1;
651e51764aSArtem Bityutskiy case LPROPS_FRDI_IDX:
661e51764aSArtem Bityutskiy return 1;
671e51764aSArtem Bityutskiy }
681e51764aSArtem Bityutskiy return 0;
691e51764aSArtem Bityutskiy }
701e51764aSArtem Bityutskiy
711e51764aSArtem Bityutskiy /**
721e51764aSArtem Bityutskiy * scan_for_dirty_cb - dirty space scan callback.
731e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
741e51764aSArtem Bityutskiy * @lprops: LEB properties to scan
751e51764aSArtem Bityutskiy * @in_tree: whether the LEB properties are in main memory
761e51764aSArtem Bityutskiy * @data: information passed to and from the caller of the scan
771e51764aSArtem Bityutskiy *
781e51764aSArtem Bityutskiy * This function returns a code that indicates whether the scan should continue
791e51764aSArtem Bityutskiy * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree
801e51764aSArtem Bityutskiy * in main memory (%LPT_SCAN_ADD), or whether the scan should stop
811e51764aSArtem Bityutskiy * (%LPT_SCAN_STOP).
821e51764aSArtem Bityutskiy */
scan_for_dirty_cb(struct ubifs_info * c,const struct ubifs_lprops * lprops,int in_tree,struct scan_data * data)831e51764aSArtem Bityutskiy static int scan_for_dirty_cb(struct ubifs_info *c,
841e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops, int in_tree,
851e51764aSArtem Bityutskiy struct scan_data *data)
861e51764aSArtem Bityutskiy {
871e51764aSArtem Bityutskiy int ret = LPT_SCAN_CONTINUE;
881e51764aSArtem Bityutskiy
891e51764aSArtem Bityutskiy /* Exclude LEBs that are currently in use */
901e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_TAKEN)
911e51764aSArtem Bityutskiy return LPT_SCAN_CONTINUE;
921e51764aSArtem Bityutskiy /* Determine whether to add these LEB properties to the tree */
931e51764aSArtem Bityutskiy if (!in_tree && valuable(c, lprops))
941e51764aSArtem Bityutskiy ret |= LPT_SCAN_ADD;
951e51764aSArtem Bityutskiy /* Exclude LEBs with too little space */
961e51764aSArtem Bityutskiy if (lprops->free + lprops->dirty < data->min_space)
971e51764aSArtem Bityutskiy return ret;
981e51764aSArtem Bityutskiy /* If specified, exclude index LEBs */
991e51764aSArtem Bityutskiy if (data->exclude_index && lprops->flags & LPROPS_INDEX)
1001e51764aSArtem Bityutskiy return ret;
1011e51764aSArtem Bityutskiy /* If specified, exclude empty or freeable LEBs */
1021e51764aSArtem Bityutskiy if (lprops->free + lprops->dirty == c->leb_size) {
1031e51764aSArtem Bityutskiy if (!data->pick_free)
1041e51764aSArtem Bityutskiy return ret;
1051e51764aSArtem Bityutskiy /* Exclude LEBs with too little dirty space (unless it is empty) */
1061e51764aSArtem Bityutskiy } else if (lprops->dirty < c->dead_wm)
1071e51764aSArtem Bityutskiy return ret;
1081e51764aSArtem Bityutskiy /* Finally we found space */
1091e51764aSArtem Bityutskiy data->lnum = lprops->lnum;
1101e51764aSArtem Bityutskiy return LPT_SCAN_ADD | LPT_SCAN_STOP;
1111e51764aSArtem Bityutskiy }
1121e51764aSArtem Bityutskiy
1131e51764aSArtem Bityutskiy /**
1141e51764aSArtem Bityutskiy * scan_for_dirty - find a data LEB with free space.
1151e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
1161e51764aSArtem Bityutskiy * @min_space: minimum amount free plus dirty space the returned LEB has to
1171e51764aSArtem Bityutskiy * have
1181e51764aSArtem Bityutskiy * @pick_free: if it is OK to return a free or freeable LEB
1191e51764aSArtem Bityutskiy * @exclude_index: whether to exclude index LEBs
1201e51764aSArtem Bityutskiy *
1211e51764aSArtem Bityutskiy * This function returns a pointer to the LEB properties found or a negative
1221e51764aSArtem Bityutskiy * error code.
1231e51764aSArtem Bityutskiy */
scan_for_dirty(struct ubifs_info * c,int min_space,int pick_free,int exclude_index)1241e51764aSArtem Bityutskiy static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c,
1251e51764aSArtem Bityutskiy int min_space, int pick_free,
1261e51764aSArtem Bityutskiy int exclude_index)
1271e51764aSArtem Bityutskiy {
1281e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops;
1291e51764aSArtem Bityutskiy struct ubifs_lpt_heap *heap;
1301e51764aSArtem Bityutskiy struct scan_data data;
1311e51764aSArtem Bityutskiy int err, i;
1321e51764aSArtem Bityutskiy
1331e51764aSArtem Bityutskiy /* There may be an LEB with enough dirty space on the free heap */
1341e51764aSArtem Bityutskiy heap = &c->lpt_heap[LPROPS_FREE - 1];
1351e51764aSArtem Bityutskiy for (i = 0; i < heap->cnt; i++) {
1361e51764aSArtem Bityutskiy lprops = heap->arr[i];
1371e51764aSArtem Bityutskiy if (lprops->free + lprops->dirty < min_space)
1381e51764aSArtem Bityutskiy continue;
1391e51764aSArtem Bityutskiy if (lprops->dirty < c->dead_wm)
1401e51764aSArtem Bityutskiy continue;
1411e51764aSArtem Bityutskiy return lprops;
1421e51764aSArtem Bityutskiy }
1431e51764aSArtem Bityutskiy /*
1441e51764aSArtem Bityutskiy * A LEB may have fallen off of the bottom of the dirty heap, and ended
1451e51764aSArtem Bityutskiy * up as uncategorized even though it has enough dirty space for us now,
1461e51764aSArtem Bityutskiy * so check the uncategorized list. N.B. neither empty nor freeable LEBs
1471e51764aSArtem Bityutskiy * can end up as uncategorized because they are kept on lists not
1481e51764aSArtem Bityutskiy * finite-sized heaps.
1491e51764aSArtem Bityutskiy */
1501e51764aSArtem Bityutskiy list_for_each_entry(lprops, &c->uncat_list, list) {
1511e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_TAKEN)
1521e51764aSArtem Bityutskiy continue;
1531e51764aSArtem Bityutskiy if (lprops->free + lprops->dirty < min_space)
1541e51764aSArtem Bityutskiy continue;
1551e51764aSArtem Bityutskiy if (exclude_index && (lprops->flags & LPROPS_INDEX))
1561e51764aSArtem Bityutskiy continue;
1571e51764aSArtem Bityutskiy if (lprops->dirty < c->dead_wm)
1581e51764aSArtem Bityutskiy continue;
1591e51764aSArtem Bityutskiy return lprops;
1601e51764aSArtem Bityutskiy }
1611e51764aSArtem Bityutskiy /* We have looked everywhere in main memory, now scan the flash */
1621e51764aSArtem Bityutskiy if (c->pnodes_have >= c->pnode_cnt)
1631e51764aSArtem Bityutskiy /* All pnodes are in memory, so skip scan */
1641e51764aSArtem Bityutskiy return ERR_PTR(-ENOSPC);
1651e51764aSArtem Bityutskiy data.min_space = min_space;
1661e51764aSArtem Bityutskiy data.pick_free = pick_free;
1671e51764aSArtem Bityutskiy data.lnum = -1;
1681e51764aSArtem Bityutskiy data.exclude_index = exclude_index;
1691e51764aSArtem Bityutskiy err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum,
1701e51764aSArtem Bityutskiy (ubifs_lpt_scan_callback)scan_for_dirty_cb,
1711e51764aSArtem Bityutskiy &data);
1721e51764aSArtem Bityutskiy if (err)
1731e51764aSArtem Bityutskiy return ERR_PTR(err);
1746eb61d58SRichard Weinberger ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
1751e51764aSArtem Bityutskiy c->lscan_lnum = data.lnum;
1761e51764aSArtem Bityutskiy lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
1771e51764aSArtem Bityutskiy if (IS_ERR(lprops))
1781e51764aSArtem Bityutskiy return lprops;
1796eb61d58SRichard Weinberger ubifs_assert(c, lprops->lnum == data.lnum);
1806eb61d58SRichard Weinberger ubifs_assert(c, lprops->free + lprops->dirty >= min_space);
1816eb61d58SRichard Weinberger ubifs_assert(c, lprops->dirty >= c->dead_wm ||
1821e51764aSArtem Bityutskiy (pick_free &&
1831e51764aSArtem Bityutskiy lprops->free + lprops->dirty == c->leb_size));
1846eb61d58SRichard Weinberger ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
1856eb61d58SRichard Weinberger ubifs_assert(c, !exclude_index || !(lprops->flags & LPROPS_INDEX));
1861e51764aSArtem Bityutskiy return lprops;
1871e51764aSArtem Bityutskiy }
1881e51764aSArtem Bityutskiy
1891e51764aSArtem Bityutskiy /**
1901e51764aSArtem Bityutskiy * ubifs_find_dirty_leb - find a dirty LEB for the Garbage Collector.
1911e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
1921e51764aSArtem Bityutskiy * @ret_lp: LEB properties are returned here on exit
1931e51764aSArtem Bityutskiy * @min_space: minimum amount free plus dirty space the returned LEB has to
1941e51764aSArtem Bityutskiy * have
1951e51764aSArtem Bityutskiy * @pick_free: controls whether it is OK to pick empty or index LEBs
1961e51764aSArtem Bityutskiy *
1971e51764aSArtem Bityutskiy * This function tries to find a dirty logical eraseblock which has at least
1981e51764aSArtem Bityutskiy * @min_space free and dirty space. It prefers to take an LEB from the dirty or
1991e51764aSArtem Bityutskiy * dirty index heap, and it falls-back to LPT scanning if the heaps are empty
2001e51764aSArtem Bityutskiy * or do not have an LEB which satisfies the @min_space criteria.
2011e51764aSArtem Bityutskiy *
202ad507653SArtem Bityutskiy * Note, LEBs which have less than dead watermark of free + dirty space are
203ad507653SArtem Bityutskiy * never picked by this function.
2041e51764aSArtem Bityutskiy *
2051e51764aSArtem Bityutskiy * The additional @pick_free argument controls if this function has to return a
2061e51764aSArtem Bityutskiy * free or freeable LEB if one is present. For example, GC must to set it to %1,
2071e51764aSArtem Bityutskiy * when called from the journal space reservation function, because the
2081e51764aSArtem Bityutskiy * appearance of free space may coincide with the loss of enough dirty space
2091e51764aSArtem Bityutskiy * for GC to succeed anyway.
2101e51764aSArtem Bityutskiy *
2111e51764aSArtem Bityutskiy * In contrast, if the Garbage Collector is called from budgeting, it should
2121e51764aSArtem Bityutskiy * just make free space, not return LEBs which are already free or freeable.
2131e51764aSArtem Bityutskiy *
2141e51764aSArtem Bityutskiy * In addition @pick_free is set to %2 by the recovery process in order to
2151e51764aSArtem Bityutskiy * recover gc_lnum in which case an index LEB must not be returned.
216ad507653SArtem Bityutskiy *
217ad507653SArtem Bityutskiy * This function returns zero and the LEB properties of found dirty LEB in case
218ad507653SArtem Bityutskiy * of success, %-ENOSPC if no dirty LEB was found and a negative error code in
219ad507653SArtem Bityutskiy * case of other failures. The returned LEB is marked as "taken".
2201e51764aSArtem Bityutskiy */
ubifs_find_dirty_leb(struct ubifs_info * c,struct ubifs_lprops * ret_lp,int min_space,int pick_free)2211e51764aSArtem Bityutskiy int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
2221e51764aSArtem Bityutskiy int min_space, int pick_free)
2231e51764aSArtem Bityutskiy {
2241e51764aSArtem Bityutskiy int err = 0, sum, exclude_index = pick_free == 2 ? 1 : 0;
2251e51764aSArtem Bityutskiy const struct ubifs_lprops *lp = NULL, *idx_lp = NULL;
2261e51764aSArtem Bityutskiy struct ubifs_lpt_heap *heap, *idx_heap;
2271e51764aSArtem Bityutskiy
2281e51764aSArtem Bityutskiy ubifs_get_lprops(c);
2291e51764aSArtem Bityutskiy
2301e51764aSArtem Bityutskiy if (pick_free) {
2311e51764aSArtem Bityutskiy int lebs, rsvd_idx_lebs = 0;
2321e51764aSArtem Bityutskiy
2331e51764aSArtem Bityutskiy spin_lock(&c->space_lock);
234131130b9SArtem Bityutskiy lebs = c->lst.empty_lebs + c->idx_gc_cnt;
2351e51764aSArtem Bityutskiy lebs += c->freeable_cnt - c->lst.taken_empty_lebs;
2361e51764aSArtem Bityutskiy
2371e51764aSArtem Bityutskiy /*
2381e51764aSArtem Bityutskiy * Note, the index may consume more LEBs than have been reserved
2391e51764aSArtem Bityutskiy * for it. It is OK because it might be consolidated by GC.
2401e51764aSArtem Bityutskiy * But if the index takes fewer LEBs than it is reserved for it,
2411e51764aSArtem Bityutskiy * this function must avoid picking those reserved LEBs.
2421e51764aSArtem Bityutskiy */
243b137545cSArtem Bityutskiy if (c->bi.min_idx_lebs >= c->lst.idx_lebs) {
244b137545cSArtem Bityutskiy rsvd_idx_lebs = c->bi.min_idx_lebs - c->lst.idx_lebs;
2451e51764aSArtem Bityutskiy exclude_index = 1;
2461e51764aSArtem Bityutskiy }
2471e51764aSArtem Bityutskiy spin_unlock(&c->space_lock);
2481e51764aSArtem Bityutskiy
2491e51764aSArtem Bityutskiy /* Check if there are enough free LEBs for the index */
2501e51764aSArtem Bityutskiy if (rsvd_idx_lebs < lebs) {
2511e51764aSArtem Bityutskiy /* OK, try to find an empty LEB */
2521e51764aSArtem Bityutskiy lp = ubifs_fast_find_empty(c);
2531e51764aSArtem Bityutskiy if (lp)
2541e51764aSArtem Bityutskiy goto found;
2551e51764aSArtem Bityutskiy
2561e51764aSArtem Bityutskiy /* Or a freeable LEB */
2571e51764aSArtem Bityutskiy lp = ubifs_fast_find_freeable(c);
2581e51764aSArtem Bityutskiy if (lp)
2591e51764aSArtem Bityutskiy goto found;
2601e51764aSArtem Bityutskiy } else
2611e51764aSArtem Bityutskiy /*
2621e51764aSArtem Bityutskiy * We cannot pick free/freeable LEBs in the below code.
2631e51764aSArtem Bityutskiy */
2641e51764aSArtem Bityutskiy pick_free = 0;
2651e51764aSArtem Bityutskiy } else {
2661e51764aSArtem Bityutskiy spin_lock(&c->space_lock);
267b137545cSArtem Bityutskiy exclude_index = (c->bi.min_idx_lebs >= c->lst.idx_lebs);
2681e51764aSArtem Bityutskiy spin_unlock(&c->space_lock);
2691e51764aSArtem Bityutskiy }
2701e51764aSArtem Bityutskiy
2711e51764aSArtem Bityutskiy /* Look on the dirty and dirty index heaps */
2721e51764aSArtem Bityutskiy heap = &c->lpt_heap[LPROPS_DIRTY - 1];
2731e51764aSArtem Bityutskiy idx_heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1];
2741e51764aSArtem Bityutskiy
2751e51764aSArtem Bityutskiy if (idx_heap->cnt && !exclude_index) {
2761e51764aSArtem Bityutskiy idx_lp = idx_heap->arr[0];
2771e51764aSArtem Bityutskiy sum = idx_lp->free + idx_lp->dirty;
2781e51764aSArtem Bityutskiy /*
2793a13252cSAdrian Hunter * Since we reserve thrice as much space for the index than it
2801e51764aSArtem Bityutskiy * actually takes, it does not make sense to pick indexing LEBs
281b364b41aSArtem Bityutskiy * with less than, say, half LEB of dirty space. May be half is
282b364b41aSArtem Bityutskiy * not the optimal boundary - this should be tested and
283b364b41aSArtem Bityutskiy * checked. This boundary should determine how much we use
284b364b41aSArtem Bityutskiy * in-the-gaps to consolidate the index comparing to how much
285b364b41aSArtem Bityutskiy * we use garbage collector to consolidate it. The "half"
286b364b41aSArtem Bityutskiy * criteria just feels to be fine.
2871e51764aSArtem Bityutskiy */
2881e51764aSArtem Bityutskiy if (sum < min_space || sum < c->half_leb_size)
2891e51764aSArtem Bityutskiy idx_lp = NULL;
2901e51764aSArtem Bityutskiy }
2911e51764aSArtem Bityutskiy
2921e51764aSArtem Bityutskiy if (heap->cnt) {
2931e51764aSArtem Bityutskiy lp = heap->arr[0];
2941e51764aSArtem Bityutskiy if (lp->dirty + lp->free < min_space)
2951e51764aSArtem Bityutskiy lp = NULL;
2961e51764aSArtem Bityutskiy }
2971e51764aSArtem Bityutskiy
2981e51764aSArtem Bityutskiy /* Pick the LEB with most space */
2991e51764aSArtem Bityutskiy if (idx_lp && lp) {
3001e51764aSArtem Bityutskiy if (idx_lp->free + idx_lp->dirty >= lp->free + lp->dirty)
3011e51764aSArtem Bityutskiy lp = idx_lp;
3021e51764aSArtem Bityutskiy } else if (idx_lp && !lp)
3031e51764aSArtem Bityutskiy lp = idx_lp;
3041e51764aSArtem Bityutskiy
3051e51764aSArtem Bityutskiy if (lp) {
3066eb61d58SRichard Weinberger ubifs_assert(c, lp->free + lp->dirty >= c->dead_wm);
3071e51764aSArtem Bityutskiy goto found;
3081e51764aSArtem Bityutskiy }
3091e51764aSArtem Bityutskiy
3101e51764aSArtem Bityutskiy /* Did not find a dirty LEB on the dirty heaps, have to scan */
3111e51764aSArtem Bityutskiy dbg_find("scanning LPT for a dirty LEB");
3121e51764aSArtem Bityutskiy lp = scan_for_dirty(c, min_space, pick_free, exclude_index);
3131e51764aSArtem Bityutskiy if (IS_ERR(lp)) {
3141e51764aSArtem Bityutskiy err = PTR_ERR(lp);
3151e51764aSArtem Bityutskiy goto out;
3161e51764aSArtem Bityutskiy }
3176eb61d58SRichard Weinberger ubifs_assert(c, lp->dirty >= c->dead_wm ||
3181e51764aSArtem Bityutskiy (pick_free && lp->free + lp->dirty == c->leb_size));
3191e51764aSArtem Bityutskiy
3201e51764aSArtem Bityutskiy found:
3211e51764aSArtem Bityutskiy dbg_find("found LEB %d, free %d, dirty %d, flags %#x",
3221e51764aSArtem Bityutskiy lp->lnum, lp->free, lp->dirty, lp->flags);
3231e51764aSArtem Bityutskiy
3241e51764aSArtem Bityutskiy lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC,
3251e51764aSArtem Bityutskiy lp->flags | LPROPS_TAKEN, 0);
3261e51764aSArtem Bityutskiy if (IS_ERR(lp)) {
3271e51764aSArtem Bityutskiy err = PTR_ERR(lp);
3281e51764aSArtem Bityutskiy goto out;
3291e51764aSArtem Bityutskiy }
3301e51764aSArtem Bityutskiy
3311e51764aSArtem Bityutskiy memcpy(ret_lp, lp, sizeof(struct ubifs_lprops));
3321e51764aSArtem Bityutskiy
3331e51764aSArtem Bityutskiy out:
3341e51764aSArtem Bityutskiy ubifs_release_lprops(c);
3351e51764aSArtem Bityutskiy return err;
3361e51764aSArtem Bityutskiy }
3371e51764aSArtem Bityutskiy
3381e51764aSArtem Bityutskiy /**
3391e51764aSArtem Bityutskiy * scan_for_free_cb - free space scan callback.
3401e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
3411e51764aSArtem Bityutskiy * @lprops: LEB properties to scan
3421e51764aSArtem Bityutskiy * @in_tree: whether the LEB properties are in main memory
3431e51764aSArtem Bityutskiy * @data: information passed to and from the caller of the scan
3441e51764aSArtem Bityutskiy *
3451e51764aSArtem Bityutskiy * This function returns a code that indicates whether the scan should continue
3461e51764aSArtem Bityutskiy * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree
3471e51764aSArtem Bityutskiy * in main memory (%LPT_SCAN_ADD), or whether the scan should stop
3481e51764aSArtem Bityutskiy * (%LPT_SCAN_STOP).
3491e51764aSArtem Bityutskiy */
scan_for_free_cb(struct ubifs_info * c,const struct ubifs_lprops * lprops,int in_tree,struct scan_data * data)3501e51764aSArtem Bityutskiy static int scan_for_free_cb(struct ubifs_info *c,
3511e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops, int in_tree,
3521e51764aSArtem Bityutskiy struct scan_data *data)
3531e51764aSArtem Bityutskiy {
3541e51764aSArtem Bityutskiy int ret = LPT_SCAN_CONTINUE;
3551e51764aSArtem Bityutskiy
3561e51764aSArtem Bityutskiy /* Exclude LEBs that are currently in use */
3571e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_TAKEN)
3581e51764aSArtem Bityutskiy return LPT_SCAN_CONTINUE;
3591e51764aSArtem Bityutskiy /* Determine whether to add these LEB properties to the tree */
3601e51764aSArtem Bityutskiy if (!in_tree && valuable(c, lprops))
3611e51764aSArtem Bityutskiy ret |= LPT_SCAN_ADD;
3621e51764aSArtem Bityutskiy /* Exclude index LEBs */
3631e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_INDEX)
3641e51764aSArtem Bityutskiy return ret;
3651e51764aSArtem Bityutskiy /* Exclude LEBs with too little space */
3661e51764aSArtem Bityutskiy if (lprops->free < data->min_space)
3671e51764aSArtem Bityutskiy return ret;
3681e51764aSArtem Bityutskiy /* If specified, exclude empty LEBs */
3691e51764aSArtem Bityutskiy if (!data->pick_free && lprops->free == c->leb_size)
3701e51764aSArtem Bityutskiy return ret;
3711e51764aSArtem Bityutskiy /*
3721e51764aSArtem Bityutskiy * LEBs that have only free and dirty space must not be allocated
3731e51764aSArtem Bityutskiy * because they may have been unmapped already or they may have data
3741e51764aSArtem Bityutskiy * that is obsolete only because of nodes that are still sitting in a
3751e51764aSArtem Bityutskiy * wbuf.
3761e51764aSArtem Bityutskiy */
3771e51764aSArtem Bityutskiy if (lprops->free + lprops->dirty == c->leb_size && lprops->dirty > 0)
3781e51764aSArtem Bityutskiy return ret;
3791e51764aSArtem Bityutskiy /* Finally we found space */
3801e51764aSArtem Bityutskiy data->lnum = lprops->lnum;
3811e51764aSArtem Bityutskiy return LPT_SCAN_ADD | LPT_SCAN_STOP;
3821e51764aSArtem Bityutskiy }
3831e51764aSArtem Bityutskiy
3841e51764aSArtem Bityutskiy /**
3851e51764aSArtem Bityutskiy * do_find_free_space - find a data LEB with free space.
3861e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
3871e51764aSArtem Bityutskiy * @min_space: minimum amount of free space required
3881e51764aSArtem Bityutskiy * @pick_free: whether it is OK to scan for empty LEBs
3891e51764aSArtem Bityutskiy * @squeeze: whether to try to find space in a non-empty LEB first
3901e51764aSArtem Bityutskiy *
3911e51764aSArtem Bityutskiy * This function returns a pointer to the LEB properties found or a negative
3921e51764aSArtem Bityutskiy * error code.
3931e51764aSArtem Bityutskiy */
3941e51764aSArtem Bityutskiy static
do_find_free_space(struct ubifs_info * c,int min_space,int pick_free,int squeeze)3951e51764aSArtem Bityutskiy const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c,
3961e51764aSArtem Bityutskiy int min_space, int pick_free,
3971e51764aSArtem Bityutskiy int squeeze)
3981e51764aSArtem Bityutskiy {
3991e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops;
4001e51764aSArtem Bityutskiy struct ubifs_lpt_heap *heap;
4011e51764aSArtem Bityutskiy struct scan_data data;
4021e51764aSArtem Bityutskiy int err, i;
4031e51764aSArtem Bityutskiy
4041e51764aSArtem Bityutskiy if (squeeze) {
4051e51764aSArtem Bityutskiy lprops = ubifs_fast_find_free(c);
4061e51764aSArtem Bityutskiy if (lprops && lprops->free >= min_space)
4071e51764aSArtem Bityutskiy return lprops;
4081e51764aSArtem Bityutskiy }
4091e51764aSArtem Bityutskiy if (pick_free) {
4101e51764aSArtem Bityutskiy lprops = ubifs_fast_find_empty(c);
4111e51764aSArtem Bityutskiy if (lprops)
4121e51764aSArtem Bityutskiy return lprops;
4131e51764aSArtem Bityutskiy }
4141e51764aSArtem Bityutskiy if (!squeeze) {
4151e51764aSArtem Bityutskiy lprops = ubifs_fast_find_free(c);
4161e51764aSArtem Bityutskiy if (lprops && lprops->free >= min_space)
4171e51764aSArtem Bityutskiy return lprops;
4181e51764aSArtem Bityutskiy }
4191e51764aSArtem Bityutskiy /* There may be an LEB with enough free space on the dirty heap */
4201e51764aSArtem Bityutskiy heap = &c->lpt_heap[LPROPS_DIRTY - 1];
4211e51764aSArtem Bityutskiy for (i = 0; i < heap->cnt; i++) {
4221e51764aSArtem Bityutskiy lprops = heap->arr[i];
4231e51764aSArtem Bityutskiy if (lprops->free >= min_space)
4241e51764aSArtem Bityutskiy return lprops;
4251e51764aSArtem Bityutskiy }
4261e51764aSArtem Bityutskiy /*
4271e51764aSArtem Bityutskiy * A LEB may have fallen off of the bottom of the free heap, and ended
4281e51764aSArtem Bityutskiy * up as uncategorized even though it has enough free space for us now,
4291e51764aSArtem Bityutskiy * so check the uncategorized list. N.B. neither empty nor freeable LEBs
4301e51764aSArtem Bityutskiy * can end up as uncategorized because they are kept on lists not
4311e51764aSArtem Bityutskiy * finite-sized heaps.
4321e51764aSArtem Bityutskiy */
4331e51764aSArtem Bityutskiy list_for_each_entry(lprops, &c->uncat_list, list) {
4341e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_TAKEN)
4351e51764aSArtem Bityutskiy continue;
4361e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_INDEX)
4371e51764aSArtem Bityutskiy continue;
4381e51764aSArtem Bityutskiy if (lprops->free >= min_space)
4391e51764aSArtem Bityutskiy return lprops;
4401e51764aSArtem Bityutskiy }
4411e51764aSArtem Bityutskiy /* We have looked everywhere in main memory, now scan the flash */
4421e51764aSArtem Bityutskiy if (c->pnodes_have >= c->pnode_cnt)
4431e51764aSArtem Bityutskiy /* All pnodes are in memory, so skip scan */
4441e51764aSArtem Bityutskiy return ERR_PTR(-ENOSPC);
4451e51764aSArtem Bityutskiy data.min_space = min_space;
4461e51764aSArtem Bityutskiy data.pick_free = pick_free;
4471e51764aSArtem Bityutskiy data.lnum = -1;
4481e51764aSArtem Bityutskiy err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum,
4491e51764aSArtem Bityutskiy (ubifs_lpt_scan_callback)scan_for_free_cb,
4501e51764aSArtem Bityutskiy &data);
4511e51764aSArtem Bityutskiy if (err)
4521e51764aSArtem Bityutskiy return ERR_PTR(err);
4536eb61d58SRichard Weinberger ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
4541e51764aSArtem Bityutskiy c->lscan_lnum = data.lnum;
4551e51764aSArtem Bityutskiy lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
4561e51764aSArtem Bityutskiy if (IS_ERR(lprops))
4571e51764aSArtem Bityutskiy return lprops;
4586eb61d58SRichard Weinberger ubifs_assert(c, lprops->lnum == data.lnum);
4596eb61d58SRichard Weinberger ubifs_assert(c, lprops->free >= min_space);
4606eb61d58SRichard Weinberger ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
4616eb61d58SRichard Weinberger ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
4621e51764aSArtem Bityutskiy return lprops;
4631e51764aSArtem Bityutskiy }
4641e51764aSArtem Bityutskiy
4651e51764aSArtem Bityutskiy /**
4661e51764aSArtem Bityutskiy * ubifs_find_free_space - find a data LEB with free space.
4671e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
4681e51764aSArtem Bityutskiy * @min_space: minimum amount of required free space
4693edaae7cSArtem Bityutskiy * @offs: contains offset of where free space starts on exit
4701e51764aSArtem Bityutskiy * @squeeze: whether to try to find space in a non-empty LEB first
4711e51764aSArtem Bityutskiy *
4721e51764aSArtem Bityutskiy * This function looks for an LEB with at least @min_space bytes of free space.
4731e51764aSArtem Bityutskiy * It tries to find an empty LEB if possible. If no empty LEBs are available,
4741e51764aSArtem Bityutskiy * this function searches for a non-empty data LEB. The returned LEB is marked
4751e51764aSArtem Bityutskiy * as "taken".
4761e51764aSArtem Bityutskiy *
4771e51764aSArtem Bityutskiy * This function returns found LEB number in case of success, %-ENOSPC if it
4781e51764aSArtem Bityutskiy * failed to find a LEB with @min_space bytes of free space and other a negative
4791e51764aSArtem Bityutskiy * error codes in case of failure.
4801e51764aSArtem Bityutskiy */
ubifs_find_free_space(struct ubifs_info * c,int min_space,int * offs,int squeeze)4813edaae7cSArtem Bityutskiy int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,
4821e51764aSArtem Bityutskiy int squeeze)
4831e51764aSArtem Bityutskiy {
4841e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops;
4851e51764aSArtem Bityutskiy int lebs, rsvd_idx_lebs, pick_free = 0, err, lnum, flags;
4861e51764aSArtem Bityutskiy
4871e51764aSArtem Bityutskiy dbg_find("min_space %d", min_space);
4881e51764aSArtem Bityutskiy ubifs_get_lprops(c);
4891e51764aSArtem Bityutskiy
4901e51764aSArtem Bityutskiy /* Check if there are enough empty LEBs for commit */
4911e51764aSArtem Bityutskiy spin_lock(&c->space_lock);
492b137545cSArtem Bityutskiy if (c->bi.min_idx_lebs > c->lst.idx_lebs)
493b137545cSArtem Bityutskiy rsvd_idx_lebs = c->bi.min_idx_lebs - c->lst.idx_lebs;
4941e51764aSArtem Bityutskiy else
4951e51764aSArtem Bityutskiy rsvd_idx_lebs = 0;
4961e51764aSArtem Bityutskiy lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
4971e51764aSArtem Bityutskiy c->lst.taken_empty_lebs;
4981e51764aSArtem Bityutskiy if (rsvd_idx_lebs < lebs)
4991e51764aSArtem Bityutskiy /*
5001e51764aSArtem Bityutskiy * OK to allocate an empty LEB, but we still don't want to go
5011e51764aSArtem Bityutskiy * looking for one if there aren't any.
5021e51764aSArtem Bityutskiy */
5031e51764aSArtem Bityutskiy if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
5041e51764aSArtem Bityutskiy pick_free = 1;
5051e51764aSArtem Bityutskiy /*
5061e51764aSArtem Bityutskiy * Because we release the space lock, we must account
5071e51764aSArtem Bityutskiy * for this allocation here. After the LEB properties
5081e51764aSArtem Bityutskiy * flags have been updated, we subtract one. Note, the
5091e51764aSArtem Bityutskiy * result of this is that lprops also decreases
5101e51764aSArtem Bityutskiy * @taken_empty_lebs in 'ubifs_change_lp()', so it is
5111e51764aSArtem Bityutskiy * off by one for a short period of time which may
5121e51764aSArtem Bityutskiy * introduce a small disturbance to budgeting
5131e51764aSArtem Bityutskiy * calculations, but this is harmless because at the
5141e51764aSArtem Bityutskiy * worst case this would make the budgeting subsystem
5151e51764aSArtem Bityutskiy * be more pessimistic than needed.
5161e51764aSArtem Bityutskiy *
5171e51764aSArtem Bityutskiy * Fundamentally, this is about serialization of the
5181e51764aSArtem Bityutskiy * budgeting and lprops subsystems. We could make the
5191e51764aSArtem Bityutskiy * @space_lock a mutex and avoid dropping it before
5201e51764aSArtem Bityutskiy * calling 'ubifs_change_lp()', but mutex is more
5211e51764aSArtem Bityutskiy * heavy-weight, and we want budgeting to be as fast as
5221e51764aSArtem Bityutskiy * possible.
5231e51764aSArtem Bityutskiy */
5241e51764aSArtem Bityutskiy c->lst.taken_empty_lebs += 1;
5251e51764aSArtem Bityutskiy }
5261e51764aSArtem Bityutskiy spin_unlock(&c->space_lock);
5271e51764aSArtem Bityutskiy
5281e51764aSArtem Bityutskiy lprops = do_find_free_space(c, min_space, pick_free, squeeze);
5291e51764aSArtem Bityutskiy if (IS_ERR(lprops)) {
5301e51764aSArtem Bityutskiy err = PTR_ERR(lprops);
5311e51764aSArtem Bityutskiy goto out;
5321e51764aSArtem Bityutskiy }
5331e51764aSArtem Bityutskiy
5341e51764aSArtem Bityutskiy lnum = lprops->lnum;
5351e51764aSArtem Bityutskiy flags = lprops->flags | LPROPS_TAKEN;
5361e51764aSArtem Bityutskiy
5371e51764aSArtem Bityutskiy lprops = ubifs_change_lp(c, lprops, LPROPS_NC, LPROPS_NC, flags, 0);
5381e51764aSArtem Bityutskiy if (IS_ERR(lprops)) {
5391e51764aSArtem Bityutskiy err = PTR_ERR(lprops);
5401e51764aSArtem Bityutskiy goto out;
5411e51764aSArtem Bityutskiy }
5421e51764aSArtem Bityutskiy
5431e51764aSArtem Bityutskiy if (pick_free) {
5441e51764aSArtem Bityutskiy spin_lock(&c->space_lock);
5451e51764aSArtem Bityutskiy c->lst.taken_empty_lebs -= 1;
5461e51764aSArtem Bityutskiy spin_unlock(&c->space_lock);
5471e51764aSArtem Bityutskiy }
5481e51764aSArtem Bityutskiy
5493edaae7cSArtem Bityutskiy *offs = c->leb_size - lprops->free;
5501e51764aSArtem Bityutskiy ubifs_release_lprops(c);
5511e51764aSArtem Bityutskiy
5523edaae7cSArtem Bityutskiy if (*offs == 0) {
5531e51764aSArtem Bityutskiy /*
5541e51764aSArtem Bityutskiy * Ensure that empty LEBs have been unmapped. They may not have
5551e51764aSArtem Bityutskiy * been, for example, because of an unclean unmount. Also
5561e51764aSArtem Bityutskiy * LEBs that were freeable LEBs (free + dirty == leb_size) will
5571e51764aSArtem Bityutskiy * not have been unmapped.
5581e51764aSArtem Bityutskiy */
5591e51764aSArtem Bityutskiy err = ubifs_leb_unmap(c, lnum);
5601e51764aSArtem Bityutskiy if (err)
5611e51764aSArtem Bityutskiy return err;
5621e51764aSArtem Bityutskiy }
5631e51764aSArtem Bityutskiy
5643edaae7cSArtem Bityutskiy dbg_find("found LEB %d, free %d", lnum, c->leb_size - *offs);
5656eb61d58SRichard Weinberger ubifs_assert(c, *offs <= c->leb_size - min_space);
5661e51764aSArtem Bityutskiy return lnum;
5671e51764aSArtem Bityutskiy
5681e51764aSArtem Bityutskiy out:
5691e51764aSArtem Bityutskiy if (pick_free) {
5701e51764aSArtem Bityutskiy spin_lock(&c->space_lock);
5711e51764aSArtem Bityutskiy c->lst.taken_empty_lebs -= 1;
5721e51764aSArtem Bityutskiy spin_unlock(&c->space_lock);
5731e51764aSArtem Bityutskiy }
5741e51764aSArtem Bityutskiy ubifs_release_lprops(c);
5751e51764aSArtem Bityutskiy return err;
5761e51764aSArtem Bityutskiy }
5771e51764aSArtem Bityutskiy
5781e51764aSArtem Bityutskiy /**
5791e51764aSArtem Bityutskiy * scan_for_idx_cb - callback used by the scan for a free LEB for the index.
5801e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
5811e51764aSArtem Bityutskiy * @lprops: LEB properties to scan
5821e51764aSArtem Bityutskiy * @in_tree: whether the LEB properties are in main memory
5831e51764aSArtem Bityutskiy * @data: information passed to and from the caller of the scan
5841e51764aSArtem Bityutskiy *
5851e51764aSArtem Bityutskiy * This function returns a code that indicates whether the scan should continue
5861e51764aSArtem Bityutskiy * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree
5871e51764aSArtem Bityutskiy * in main memory (%LPT_SCAN_ADD), or whether the scan should stop
5881e51764aSArtem Bityutskiy * (%LPT_SCAN_STOP).
5891e51764aSArtem Bityutskiy */
scan_for_idx_cb(struct ubifs_info * c,const struct ubifs_lprops * lprops,int in_tree,struct scan_data * data)5901e51764aSArtem Bityutskiy static int scan_for_idx_cb(struct ubifs_info *c,
5911e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops, int in_tree,
5921e51764aSArtem Bityutskiy struct scan_data *data)
5931e51764aSArtem Bityutskiy {
5941e51764aSArtem Bityutskiy int ret = LPT_SCAN_CONTINUE;
5951e51764aSArtem Bityutskiy
5961e51764aSArtem Bityutskiy /* Exclude LEBs that are currently in use */
5971e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_TAKEN)
5981e51764aSArtem Bityutskiy return LPT_SCAN_CONTINUE;
5991e51764aSArtem Bityutskiy /* Determine whether to add these LEB properties to the tree */
6001e51764aSArtem Bityutskiy if (!in_tree && valuable(c, lprops))
6011e51764aSArtem Bityutskiy ret |= LPT_SCAN_ADD;
6021e51764aSArtem Bityutskiy /* Exclude index LEBS */
6031e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_INDEX)
6041e51764aSArtem Bityutskiy return ret;
6051e51764aSArtem Bityutskiy /* Exclude LEBs that cannot be made empty */
6061e51764aSArtem Bityutskiy if (lprops->free + lprops->dirty != c->leb_size)
6071e51764aSArtem Bityutskiy return ret;
6081e51764aSArtem Bityutskiy /*
6091e51764aSArtem Bityutskiy * We are allocating for the index so it is safe to allocate LEBs with
6101e51764aSArtem Bityutskiy * only free and dirty space, because write buffers are sync'd at commit
6111e51764aSArtem Bityutskiy * start.
6121e51764aSArtem Bityutskiy */
6131e51764aSArtem Bityutskiy data->lnum = lprops->lnum;
6141e51764aSArtem Bityutskiy return LPT_SCAN_ADD | LPT_SCAN_STOP;
6151e51764aSArtem Bityutskiy }
6161e51764aSArtem Bityutskiy
6171e51764aSArtem Bityutskiy /**
6181e51764aSArtem Bityutskiy * scan_for_leb_for_idx - scan for a free LEB for the index.
6191e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
6201e51764aSArtem Bityutskiy */
scan_for_leb_for_idx(struct ubifs_info * c)6211e51764aSArtem Bityutskiy static const struct ubifs_lprops *scan_for_leb_for_idx(struct ubifs_info *c)
6221e51764aSArtem Bityutskiy {
623cc194783SJiang Biao const struct ubifs_lprops *lprops;
6241e51764aSArtem Bityutskiy struct scan_data data;
6251e51764aSArtem Bityutskiy int err;
6261e51764aSArtem Bityutskiy
6271e51764aSArtem Bityutskiy data.lnum = -1;
6281e51764aSArtem Bityutskiy err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum,
6291e51764aSArtem Bityutskiy (ubifs_lpt_scan_callback)scan_for_idx_cb,
6301e51764aSArtem Bityutskiy &data);
6311e51764aSArtem Bityutskiy if (err)
6321e51764aSArtem Bityutskiy return ERR_PTR(err);
6336eb61d58SRichard Weinberger ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
6341e51764aSArtem Bityutskiy c->lscan_lnum = data.lnum;
6351e51764aSArtem Bityutskiy lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
6361e51764aSArtem Bityutskiy if (IS_ERR(lprops))
6371e51764aSArtem Bityutskiy return lprops;
6386eb61d58SRichard Weinberger ubifs_assert(c, lprops->lnum == data.lnum);
6396eb61d58SRichard Weinberger ubifs_assert(c, lprops->free + lprops->dirty == c->leb_size);
6406eb61d58SRichard Weinberger ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
6416eb61d58SRichard Weinberger ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
6421e51764aSArtem Bityutskiy return lprops;
6431e51764aSArtem Bityutskiy }
6441e51764aSArtem Bityutskiy
6451e51764aSArtem Bityutskiy /**
6461e51764aSArtem Bityutskiy * ubifs_find_free_leb_for_idx - find a free LEB for the index.
6471e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
6481e51764aSArtem Bityutskiy *
6491e51764aSArtem Bityutskiy * This function looks for a free LEB and returns that LEB number. The returned
6501e51764aSArtem Bityutskiy * LEB is marked as "taken", "index".
6511e51764aSArtem Bityutskiy *
6521e51764aSArtem Bityutskiy * Only empty LEBs are allocated. This is for two reasons. First, the commit
6531e51764aSArtem Bityutskiy * calculates the number of LEBs to allocate based on the assumption that they
6541e51764aSArtem Bityutskiy * will be empty. Secondly, free space at the end of an index LEB is not
6551e51764aSArtem Bityutskiy * guaranteed to be empty because it may have been used by the in-the-gaps
6561e51764aSArtem Bityutskiy * method prior to an unclean unmount.
6571e51764aSArtem Bityutskiy *
6581e51764aSArtem Bityutskiy * If no LEB is found %-ENOSPC is returned. For other failures another negative
6591e51764aSArtem Bityutskiy * error code is returned.
6601e51764aSArtem Bityutskiy */
ubifs_find_free_leb_for_idx(struct ubifs_info * c)6611e51764aSArtem Bityutskiy int ubifs_find_free_leb_for_idx(struct ubifs_info *c)
6621e51764aSArtem Bityutskiy {
6631e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops;
6641e51764aSArtem Bityutskiy int lnum = -1, err, flags;
6651e51764aSArtem Bityutskiy
6661e51764aSArtem Bityutskiy ubifs_get_lprops(c);
6671e51764aSArtem Bityutskiy
6681e51764aSArtem Bityutskiy lprops = ubifs_fast_find_empty(c);
6691e51764aSArtem Bityutskiy if (!lprops) {
6701e51764aSArtem Bityutskiy lprops = ubifs_fast_find_freeable(c);
6711e51764aSArtem Bityutskiy if (!lprops) {
672a28ad42aSArtem Bityutskiy /*
673a28ad42aSArtem Bityutskiy * The first condition means the following: go scan the
674a28ad42aSArtem Bityutskiy * LPT if there are uncategorized lprops, which means
675a28ad42aSArtem Bityutskiy * there may be freeable LEBs there (UBIFS does not
676a28ad42aSArtem Bityutskiy * store the information about freeable LEBs in the
677a28ad42aSArtem Bityutskiy * master node).
678a28ad42aSArtem Bityutskiy */
679a28ad42aSArtem Bityutskiy if (c->in_a_category_cnt != c->main_lebs ||
680a28ad42aSArtem Bityutskiy c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
6816eb61d58SRichard Weinberger ubifs_assert(c, c->freeable_cnt == 0);
6821e51764aSArtem Bityutskiy lprops = scan_for_leb_for_idx(c);
6831e51764aSArtem Bityutskiy if (IS_ERR(lprops)) {
6841e51764aSArtem Bityutskiy err = PTR_ERR(lprops);
6851e51764aSArtem Bityutskiy goto out;
6861e51764aSArtem Bityutskiy }
6871e51764aSArtem Bityutskiy }
6881e51764aSArtem Bityutskiy }
6891e51764aSArtem Bityutskiy }
6901e51764aSArtem Bityutskiy
6911e51764aSArtem Bityutskiy if (!lprops) {
6921e51764aSArtem Bityutskiy err = -ENOSPC;
6931e51764aSArtem Bityutskiy goto out;
6941e51764aSArtem Bityutskiy }
6951e51764aSArtem Bityutskiy
6961e51764aSArtem Bityutskiy lnum = lprops->lnum;
6971e51764aSArtem Bityutskiy
6981e51764aSArtem Bityutskiy dbg_find("found LEB %d, free %d, dirty %d, flags %#x",
6991e51764aSArtem Bityutskiy lnum, lprops->free, lprops->dirty, lprops->flags);
7001e51764aSArtem Bityutskiy
7011e51764aSArtem Bityutskiy flags = lprops->flags | LPROPS_TAKEN | LPROPS_INDEX;
7021e51764aSArtem Bityutskiy lprops = ubifs_change_lp(c, lprops, c->leb_size, 0, flags, 0);
7031e51764aSArtem Bityutskiy if (IS_ERR(lprops)) {
7041e51764aSArtem Bityutskiy err = PTR_ERR(lprops);
7051e51764aSArtem Bityutskiy goto out;
7061e51764aSArtem Bityutskiy }
7071e51764aSArtem Bityutskiy
7081e51764aSArtem Bityutskiy ubifs_release_lprops(c);
7091e51764aSArtem Bityutskiy
7101e51764aSArtem Bityutskiy /*
7111e51764aSArtem Bityutskiy * Ensure that empty LEBs have been unmapped. They may not have been,
7121e51764aSArtem Bityutskiy * for example, because of an unclean unmount. Also LEBs that were
7131e51764aSArtem Bityutskiy * freeable LEBs (free + dirty == leb_size) will not have been unmapped.
7141e51764aSArtem Bityutskiy */
7151e51764aSArtem Bityutskiy err = ubifs_leb_unmap(c, lnum);
7161e51764aSArtem Bityutskiy if (err) {
7171e51764aSArtem Bityutskiy ubifs_change_one_lp(c, lnum, LPROPS_NC, LPROPS_NC, 0,
7181e51764aSArtem Bityutskiy LPROPS_TAKEN | LPROPS_INDEX, 0);
7191e51764aSArtem Bityutskiy return err;
7201e51764aSArtem Bityutskiy }
7211e51764aSArtem Bityutskiy
7221e51764aSArtem Bityutskiy return lnum;
7231e51764aSArtem Bityutskiy
7241e51764aSArtem Bityutskiy out:
7251e51764aSArtem Bityutskiy ubifs_release_lprops(c);
7261e51764aSArtem Bityutskiy return err;
7271e51764aSArtem Bityutskiy }
7281e51764aSArtem Bityutskiy
cmp_dirty_idx(const struct ubifs_lprops ** a,const struct ubifs_lprops ** b)7291e51764aSArtem Bityutskiy static int cmp_dirty_idx(const struct ubifs_lprops **a,
7301e51764aSArtem Bityutskiy const struct ubifs_lprops **b)
7311e51764aSArtem Bityutskiy {
7321e51764aSArtem Bityutskiy const struct ubifs_lprops *lpa = *a;
7331e51764aSArtem Bityutskiy const struct ubifs_lprops *lpb = *b;
7341e51764aSArtem Bityutskiy
7351e51764aSArtem Bityutskiy return lpa->dirty + lpa->free - lpb->dirty - lpb->free;
7361e51764aSArtem Bityutskiy }
7371e51764aSArtem Bityutskiy
7381e51764aSArtem Bityutskiy /**
7391e51764aSArtem Bityutskiy * ubifs_save_dirty_idx_lnums - save an array of the most dirty index LEB nos.
7401e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
7411e51764aSArtem Bityutskiy *
7421e51764aSArtem Bityutskiy * This function is called each commit to create an array of LEB numbers of
7431e51764aSArtem Bityutskiy * dirty index LEBs sorted in order of dirty and free space. This is used by
7441e51764aSArtem Bityutskiy * the in-the-gaps method of TNC commit.
7451e51764aSArtem Bityutskiy */
ubifs_save_dirty_idx_lnums(struct ubifs_info * c)7461e51764aSArtem Bityutskiy int ubifs_save_dirty_idx_lnums(struct ubifs_info *c)
7471e51764aSArtem Bityutskiy {
7481e51764aSArtem Bityutskiy int i;
7491e51764aSArtem Bityutskiy
7501e51764aSArtem Bityutskiy ubifs_get_lprops(c);
7511e51764aSArtem Bityutskiy /* Copy the LPROPS_DIRTY_IDX heap */
7521e51764aSArtem Bityutskiy c->dirty_idx.cnt = c->lpt_heap[LPROPS_DIRTY_IDX - 1].cnt;
7531e51764aSArtem Bityutskiy memcpy(c->dirty_idx.arr, c->lpt_heap[LPROPS_DIRTY_IDX - 1].arr,
7541e51764aSArtem Bityutskiy sizeof(void *) * c->dirty_idx.cnt);
7551e51764aSArtem Bityutskiy /* Sort it so that the dirtiest is now at the end */
7561e51764aSArtem Bityutskiy sort(c->dirty_idx.arr, c->dirty_idx.cnt, sizeof(void *),
757257bb924SAndrey Abramov (int (*)(const void *, const void *))cmp_dirty_idx, NULL);
7581e51764aSArtem Bityutskiy dbg_find("found %d dirty index LEBs", c->dirty_idx.cnt);
7591e51764aSArtem Bityutskiy if (c->dirty_idx.cnt)
7601e51764aSArtem Bityutskiy dbg_find("dirtiest index LEB is %d with dirty %d and free %d",
7611e51764aSArtem Bityutskiy c->dirty_idx.arr[c->dirty_idx.cnt - 1]->lnum,
7621e51764aSArtem Bityutskiy c->dirty_idx.arr[c->dirty_idx.cnt - 1]->dirty,
7631e51764aSArtem Bityutskiy c->dirty_idx.arr[c->dirty_idx.cnt - 1]->free);
7641e51764aSArtem Bityutskiy /* Replace the lprops pointers with LEB numbers */
7651e51764aSArtem Bityutskiy for (i = 0; i < c->dirty_idx.cnt; i++)
7661e51764aSArtem Bityutskiy c->dirty_idx.arr[i] = (void *)(size_t)c->dirty_idx.arr[i]->lnum;
7671e51764aSArtem Bityutskiy ubifs_release_lprops(c);
7681e51764aSArtem Bityutskiy return 0;
7691e51764aSArtem Bityutskiy }
7701e51764aSArtem Bityutskiy
7711e51764aSArtem Bityutskiy /**
7721e51764aSArtem Bityutskiy * scan_dirty_idx_cb - callback used by the scan for a dirty index LEB.
7731e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
7741e51764aSArtem Bityutskiy * @lprops: LEB properties to scan
7751e51764aSArtem Bityutskiy * @in_tree: whether the LEB properties are in main memory
7761e51764aSArtem Bityutskiy * @data: information passed to and from the caller of the scan
7771e51764aSArtem Bityutskiy *
7781e51764aSArtem Bityutskiy * This function returns a code that indicates whether the scan should continue
7791e51764aSArtem Bityutskiy * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree
7801e51764aSArtem Bityutskiy * in main memory (%LPT_SCAN_ADD), or whether the scan should stop
7811e51764aSArtem Bityutskiy * (%LPT_SCAN_STOP).
7821e51764aSArtem Bityutskiy */
scan_dirty_idx_cb(struct ubifs_info * c,const struct ubifs_lprops * lprops,int in_tree,struct scan_data * data)7831e51764aSArtem Bityutskiy static int scan_dirty_idx_cb(struct ubifs_info *c,
7841e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops, int in_tree,
7851e51764aSArtem Bityutskiy struct scan_data *data)
7861e51764aSArtem Bityutskiy {
7871e51764aSArtem Bityutskiy int ret = LPT_SCAN_CONTINUE;
7881e51764aSArtem Bityutskiy
7891e51764aSArtem Bityutskiy /* Exclude LEBs that are currently in use */
7901e51764aSArtem Bityutskiy if (lprops->flags & LPROPS_TAKEN)
7911e51764aSArtem Bityutskiy return LPT_SCAN_CONTINUE;
7921e51764aSArtem Bityutskiy /* Determine whether to add these LEB properties to the tree */
7931e51764aSArtem Bityutskiy if (!in_tree && valuable(c, lprops))
7941e51764aSArtem Bityutskiy ret |= LPT_SCAN_ADD;
7951e51764aSArtem Bityutskiy /* Exclude non-index LEBs */
7961e51764aSArtem Bityutskiy if (!(lprops->flags & LPROPS_INDEX))
7971e51764aSArtem Bityutskiy return ret;
7981e51764aSArtem Bityutskiy /* Exclude LEBs with too little space */
7991e51764aSArtem Bityutskiy if (lprops->free + lprops->dirty < c->min_idx_node_sz)
8001e51764aSArtem Bityutskiy return ret;
8011e51764aSArtem Bityutskiy /* Finally we found space */
8021e51764aSArtem Bityutskiy data->lnum = lprops->lnum;
8031e51764aSArtem Bityutskiy return LPT_SCAN_ADD | LPT_SCAN_STOP;
8041e51764aSArtem Bityutskiy }
8051e51764aSArtem Bityutskiy
8061e51764aSArtem Bityutskiy /**
8071e51764aSArtem Bityutskiy * find_dirty_idx_leb - find a dirty index LEB.
8081e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
8091e51764aSArtem Bityutskiy *
8101e51764aSArtem Bityutskiy * This function returns LEB number upon success and a negative error code upon
8111e51764aSArtem Bityutskiy * failure. In particular, -ENOSPC is returned if a dirty index LEB is not
8121e51764aSArtem Bityutskiy * found.
8131e51764aSArtem Bityutskiy *
8141e51764aSArtem Bityutskiy * Note that this function scans the entire LPT but it is called very rarely.
8151e51764aSArtem Bityutskiy */
find_dirty_idx_leb(struct ubifs_info * c)8161e51764aSArtem Bityutskiy static int find_dirty_idx_leb(struct ubifs_info *c)
8171e51764aSArtem Bityutskiy {
8181e51764aSArtem Bityutskiy const struct ubifs_lprops *lprops;
8191e51764aSArtem Bityutskiy struct ubifs_lpt_heap *heap;
8201e51764aSArtem Bityutskiy struct scan_data data;
8211e51764aSArtem Bityutskiy int err, i, ret;
8221e51764aSArtem Bityutskiy
8231e51764aSArtem Bityutskiy /* Check all structures in memory first */
8241e51764aSArtem Bityutskiy data.lnum = -1;
8251e51764aSArtem Bityutskiy heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1];
8261e51764aSArtem Bityutskiy for (i = 0; i < heap->cnt; i++) {
8271e51764aSArtem Bityutskiy lprops = heap->arr[i];
8281e51764aSArtem Bityutskiy ret = scan_dirty_idx_cb(c, lprops, 1, &data);
8291e51764aSArtem Bityutskiy if (ret & LPT_SCAN_STOP)
8301e51764aSArtem Bityutskiy goto found;
8311e51764aSArtem Bityutskiy }
8321e51764aSArtem Bityutskiy list_for_each_entry(lprops, &c->frdi_idx_list, list) {
8331e51764aSArtem Bityutskiy ret = scan_dirty_idx_cb(c, lprops, 1, &data);
8341e51764aSArtem Bityutskiy if (ret & LPT_SCAN_STOP)
8351e51764aSArtem Bityutskiy goto found;
8361e51764aSArtem Bityutskiy }
8371e51764aSArtem Bityutskiy list_for_each_entry(lprops, &c->uncat_list, list) {
8381e51764aSArtem Bityutskiy ret = scan_dirty_idx_cb(c, lprops, 1, &data);
8391e51764aSArtem Bityutskiy if (ret & LPT_SCAN_STOP)
8401e51764aSArtem Bityutskiy goto found;
8411e51764aSArtem Bityutskiy }
8421e51764aSArtem Bityutskiy if (c->pnodes_have >= c->pnode_cnt)
8431e51764aSArtem Bityutskiy /* All pnodes are in memory, so skip scan */
8441e51764aSArtem Bityutskiy return -ENOSPC;
8451e51764aSArtem Bityutskiy err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum,
8461e51764aSArtem Bityutskiy (ubifs_lpt_scan_callback)scan_dirty_idx_cb,
8471e51764aSArtem Bityutskiy &data);
8481e51764aSArtem Bityutskiy if (err)
8491e51764aSArtem Bityutskiy return err;
8501e51764aSArtem Bityutskiy found:
8516eb61d58SRichard Weinberger ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
8521e51764aSArtem Bityutskiy c->lscan_lnum = data.lnum;
8531e51764aSArtem Bityutskiy lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
8541e51764aSArtem Bityutskiy if (IS_ERR(lprops))
8551e51764aSArtem Bityutskiy return PTR_ERR(lprops);
8566eb61d58SRichard Weinberger ubifs_assert(c, lprops->lnum == data.lnum);
8576eb61d58SRichard Weinberger ubifs_assert(c, lprops->free + lprops->dirty >= c->min_idx_node_sz);
8586eb61d58SRichard Weinberger ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
8596eb61d58SRichard Weinberger ubifs_assert(c, (lprops->flags & LPROPS_INDEX));
8601e51764aSArtem Bityutskiy
8611e51764aSArtem Bityutskiy dbg_find("found dirty LEB %d, free %d, dirty %d, flags %#x",
8621e51764aSArtem Bityutskiy lprops->lnum, lprops->free, lprops->dirty, lprops->flags);
8631e51764aSArtem Bityutskiy
8641e51764aSArtem Bityutskiy lprops = ubifs_change_lp(c, lprops, LPROPS_NC, LPROPS_NC,
8651e51764aSArtem Bityutskiy lprops->flags | LPROPS_TAKEN, 0);
8661e51764aSArtem Bityutskiy if (IS_ERR(lprops))
8671e51764aSArtem Bityutskiy return PTR_ERR(lprops);
8681e51764aSArtem Bityutskiy
8691e51764aSArtem Bityutskiy return lprops->lnum;
8701e51764aSArtem Bityutskiy }
8711e51764aSArtem Bityutskiy
8721e51764aSArtem Bityutskiy /**
8731e51764aSArtem Bityutskiy * get_idx_gc_leb - try to get a LEB number from trivial GC.
8741e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
8751e51764aSArtem Bityutskiy */
get_idx_gc_leb(struct ubifs_info * c)8761e51764aSArtem Bityutskiy static int get_idx_gc_leb(struct ubifs_info *c)
8771e51764aSArtem Bityutskiy {
8781e51764aSArtem Bityutskiy const struct ubifs_lprops *lp;
8791e51764aSArtem Bityutskiy int err, lnum;
8801e51764aSArtem Bityutskiy
8811e51764aSArtem Bityutskiy err = ubifs_get_idx_gc_leb(c);
8821e51764aSArtem Bityutskiy if (err < 0)
8831e51764aSArtem Bityutskiy return err;
8841e51764aSArtem Bityutskiy lnum = err;
8851e51764aSArtem Bityutskiy /*
8861e51764aSArtem Bityutskiy * The LEB was due to be unmapped after the commit but
8871e51764aSArtem Bityutskiy * it is needed now for this commit.
8881e51764aSArtem Bityutskiy */
8891e51764aSArtem Bityutskiy lp = ubifs_lpt_lookup_dirty(c, lnum);
8908d47aef4SHirofumi Nakagawa if (IS_ERR(lp))
8911e51764aSArtem Bityutskiy return PTR_ERR(lp);
8921e51764aSArtem Bityutskiy lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC,
8931e51764aSArtem Bityutskiy lp->flags | LPROPS_INDEX, -1);
8948d47aef4SHirofumi Nakagawa if (IS_ERR(lp))
8951e51764aSArtem Bityutskiy return PTR_ERR(lp);
8961e51764aSArtem Bityutskiy dbg_find("LEB %d, dirty %d and free %d flags %#x",
8971e51764aSArtem Bityutskiy lp->lnum, lp->dirty, lp->free, lp->flags);
8981e51764aSArtem Bityutskiy return lnum;
8991e51764aSArtem Bityutskiy }
9001e51764aSArtem Bityutskiy
9011e51764aSArtem Bityutskiy /**
9021e51764aSArtem Bityutskiy * find_dirtiest_idx_leb - find dirtiest index LEB from dirtiest array.
9031e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
9041e51764aSArtem Bityutskiy */
find_dirtiest_idx_leb(struct ubifs_info * c)9051e51764aSArtem Bityutskiy static int find_dirtiest_idx_leb(struct ubifs_info *c)
9061e51764aSArtem Bityutskiy {
9071e51764aSArtem Bityutskiy const struct ubifs_lprops *lp;
9081e51764aSArtem Bityutskiy int lnum;
9091e51764aSArtem Bityutskiy
9101e51764aSArtem Bityutskiy while (1) {
9111e51764aSArtem Bityutskiy if (!c->dirty_idx.cnt)
9121e51764aSArtem Bityutskiy return -ENOSPC;
9131e51764aSArtem Bityutskiy /* The lprops pointers were replaced by LEB numbers */
9141e51764aSArtem Bityutskiy lnum = (size_t)c->dirty_idx.arr[--c->dirty_idx.cnt];
9151e51764aSArtem Bityutskiy lp = ubifs_lpt_lookup(c, lnum);
9161e51764aSArtem Bityutskiy if (IS_ERR(lp))
9171e51764aSArtem Bityutskiy return PTR_ERR(lp);
9181e51764aSArtem Bityutskiy if ((lp->flags & LPROPS_TAKEN) || !(lp->flags & LPROPS_INDEX))
9191e51764aSArtem Bityutskiy continue;
9201e51764aSArtem Bityutskiy lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC,
9211e51764aSArtem Bityutskiy lp->flags | LPROPS_TAKEN, 0);
9221e51764aSArtem Bityutskiy if (IS_ERR(lp))
9231e51764aSArtem Bityutskiy return PTR_ERR(lp);
9241e51764aSArtem Bityutskiy break;
9251e51764aSArtem Bityutskiy }
9261e51764aSArtem Bityutskiy dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty,
9271e51764aSArtem Bityutskiy lp->free, lp->flags);
9286eb61d58SRichard Weinberger ubifs_assert(c, lp->flags & LPROPS_TAKEN);
9296eb61d58SRichard Weinberger ubifs_assert(c, lp->flags & LPROPS_INDEX);
9301e51764aSArtem Bityutskiy return lnum;
9311e51764aSArtem Bityutskiy }
9321e51764aSArtem Bityutskiy
9331e51764aSArtem Bityutskiy /**
9341e51764aSArtem Bityutskiy * ubifs_find_dirty_idx_leb - try to find dirtiest index LEB as at last commit.
9351e51764aSArtem Bityutskiy * @c: the UBIFS file-system description object
9361e51764aSArtem Bityutskiy *
9371e51764aSArtem Bityutskiy * This function attempts to find an untaken index LEB with the most free and
9381e51764aSArtem Bityutskiy * dirty space that can be used without overwriting index nodes that were in the
9391e51764aSArtem Bityutskiy * last index committed.
9401e51764aSArtem Bityutskiy */
ubifs_find_dirty_idx_leb(struct ubifs_info * c)9411e51764aSArtem Bityutskiy int ubifs_find_dirty_idx_leb(struct ubifs_info *c)
9421e51764aSArtem Bityutskiy {
9431e51764aSArtem Bityutskiy int err;
9441e51764aSArtem Bityutskiy
9451e51764aSArtem Bityutskiy ubifs_get_lprops(c);
9461e51764aSArtem Bityutskiy
9471e51764aSArtem Bityutskiy /*
9481e51764aSArtem Bityutskiy * We made an array of the dirtiest index LEB numbers as at the start of
9491e51764aSArtem Bityutskiy * last commit. Try that array first.
9501e51764aSArtem Bityutskiy */
9511e51764aSArtem Bityutskiy err = find_dirtiest_idx_leb(c);
9521e51764aSArtem Bityutskiy
9531e51764aSArtem Bityutskiy /* Next try scanning the entire LPT */
9541e51764aSArtem Bityutskiy if (err == -ENOSPC)
9551e51764aSArtem Bityutskiy err = find_dirty_idx_leb(c);
9561e51764aSArtem Bityutskiy
9571e51764aSArtem Bityutskiy /* Finally take any index LEBs awaiting trivial GC */
9581e51764aSArtem Bityutskiy if (err == -ENOSPC)
9591e51764aSArtem Bityutskiy err = get_idx_gc_leb(c);
9601e51764aSArtem Bityutskiy
9611e51764aSArtem Bityutskiy ubifs_release_lprops(c);
9621e51764aSArtem Bityutskiy return err;
9631e51764aSArtem Bityutskiy }
964