xref: /kernel/linux/linux-6.6/fs/ubifs/gc.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * This file is part of UBIFS.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2006-2008 Nokia Corporation.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Authors: Adrian Hunter
862306a36Sopenharmony_ci *          Artem Bityutskiy (Битюцкий Артём)
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/*
1262306a36Sopenharmony_ci * This file implements garbage collection. The procedure for garbage collection
1362306a36Sopenharmony_ci * is different depending on whether a LEB as an index LEB (contains index
1462306a36Sopenharmony_ci * nodes) or not. For non-index LEBs, garbage collection finds a LEB which
1562306a36Sopenharmony_ci * contains a lot of dirty space (obsolete nodes), and copies the non-obsolete
1662306a36Sopenharmony_ci * nodes to the journal, at which point the garbage-collected LEB is free to be
1762306a36Sopenharmony_ci * reused. For index LEBs, garbage collection marks the non-obsolete index nodes
1862306a36Sopenharmony_ci * dirty in the TNC, and after the next commit, the garbage-collected LEB is
1962306a36Sopenharmony_ci * to be reused. Garbage collection will cause the number of dirty index nodes
2062306a36Sopenharmony_ci * to grow, however sufficient space is reserved for the index to ensure the
2162306a36Sopenharmony_ci * commit will never run out of space.
2262306a36Sopenharmony_ci *
2362306a36Sopenharmony_ci * Notes about dead watermark. At current UBIFS implementation we assume that
2462306a36Sopenharmony_ci * LEBs which have less than @c->dead_wm bytes of free + dirty space are full
2562306a36Sopenharmony_ci * and not worth garbage-collecting. The dead watermark is one min. I/O unit
2662306a36Sopenharmony_ci * size, or min. UBIFS node size, depending on what is greater. Indeed, UBIFS
2762306a36Sopenharmony_ci * Garbage Collector has to synchronize the GC head's write buffer before
2862306a36Sopenharmony_ci * returning, so this is about wasting one min. I/O unit. However, UBIFS GC can
2962306a36Sopenharmony_ci * actually reclaim even very small pieces of dirty space by garbage collecting
3062306a36Sopenharmony_ci * enough dirty LEBs, but we do not bother doing this at this implementation.
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * Notes about dark watermark. The results of GC work depends on how big are
3362306a36Sopenharmony_ci * the UBIFS nodes GC deals with. Large nodes make GC waste more space. Indeed,
3462306a36Sopenharmony_ci * if GC move data from LEB A to LEB B and nodes in LEB A are large, GC would
3562306a36Sopenharmony_ci * have to waste large pieces of free space at the end of LEB B, because nodes
3662306a36Sopenharmony_ci * from LEB A would not fit. And the worst situation is when all nodes are of
3762306a36Sopenharmony_ci * maximum size. So dark watermark is the amount of free + dirty space in LEB
3862306a36Sopenharmony_ci * which are guaranteed to be reclaimable. If LEB has less space, the GC might
3962306a36Sopenharmony_ci * be unable to reclaim it. So, LEBs with free + dirty greater than dark
4062306a36Sopenharmony_ci * watermark are "good" LEBs from GC's point of view. The other LEBs are not so
4162306a36Sopenharmony_ci * good, and GC takes extra care when moving them.
4262306a36Sopenharmony_ci */
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#include <linux/slab.h>
4562306a36Sopenharmony_ci#include <linux/pagemap.h>
4662306a36Sopenharmony_ci#include <linux/list_sort.h>
4762306a36Sopenharmony_ci#include "ubifs.h"
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/*
5062306a36Sopenharmony_ci * GC may need to move more than one LEB to make progress. The below constants
5162306a36Sopenharmony_ci * define "soft" and "hard" limits on the number of LEBs the garbage collector
5262306a36Sopenharmony_ci * may move.
5362306a36Sopenharmony_ci */
5462306a36Sopenharmony_ci#define SOFT_LEBS_LIMIT 4
5562306a36Sopenharmony_ci#define HARD_LEBS_LIMIT 32
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/**
5862306a36Sopenharmony_ci * switch_gc_head - switch the garbage collection journal head.
5962306a36Sopenharmony_ci * @c: UBIFS file-system description object
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * This function switch the GC head to the next LEB which is reserved in
6262306a36Sopenharmony_ci * @c->gc_lnum. Returns %0 in case of success, %-EAGAIN if commit is required,
6362306a36Sopenharmony_ci * and other negative error code in case of failures.
6462306a36Sopenharmony_ci */
6562306a36Sopenharmony_cistatic int switch_gc_head(struct ubifs_info *c)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	int err, gc_lnum = c->gc_lnum;
6862306a36Sopenharmony_ci	struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	ubifs_assert(c, gc_lnum != -1);
7162306a36Sopenharmony_ci	dbg_gc("switch GC head from LEB %d:%d to LEB %d (waste %d bytes)",
7262306a36Sopenharmony_ci	       wbuf->lnum, wbuf->offs + wbuf->used, gc_lnum,
7362306a36Sopenharmony_ci	       c->leb_size - wbuf->offs - wbuf->used);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	err = ubifs_wbuf_sync_nolock(wbuf);
7662306a36Sopenharmony_ci	if (err)
7762306a36Sopenharmony_ci		return err;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	/*
8062306a36Sopenharmony_ci	 * The GC write-buffer was synchronized, we may safely unmap
8162306a36Sopenharmony_ci	 * 'c->gc_lnum'.
8262306a36Sopenharmony_ci	 */
8362306a36Sopenharmony_ci	err = ubifs_leb_unmap(c, gc_lnum);
8462306a36Sopenharmony_ci	if (err)
8562306a36Sopenharmony_ci		return err;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	err = ubifs_add_bud_to_log(c, GCHD, gc_lnum, 0);
8862306a36Sopenharmony_ci	if (err)
8962306a36Sopenharmony_ci		return err;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	c->gc_lnum = -1;
9262306a36Sopenharmony_ci	err = ubifs_wbuf_seek_nolock(wbuf, gc_lnum, 0);
9362306a36Sopenharmony_ci	return err;
9462306a36Sopenharmony_ci}
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/**
9762306a36Sopenharmony_ci * data_nodes_cmp - compare 2 data nodes.
9862306a36Sopenharmony_ci * @priv: UBIFS file-system description object
9962306a36Sopenharmony_ci * @a: first data node
10062306a36Sopenharmony_ci * @b: second data node
10162306a36Sopenharmony_ci *
10262306a36Sopenharmony_ci * This function compares data nodes @a and @b. Returns %1 if @a has greater
10362306a36Sopenharmony_ci * inode or block number, and %-1 otherwise.
10462306a36Sopenharmony_ci */
10562306a36Sopenharmony_cistatic int data_nodes_cmp(void *priv, const struct list_head *a,
10662306a36Sopenharmony_ci			  const struct list_head *b)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	ino_t inuma, inumb;
10962306a36Sopenharmony_ci	struct ubifs_info *c = priv;
11062306a36Sopenharmony_ci	struct ubifs_scan_node *sa, *sb;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	cond_resched();
11362306a36Sopenharmony_ci	if (a == b)
11462306a36Sopenharmony_ci		return 0;
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	sa = list_entry(a, struct ubifs_scan_node, list);
11762306a36Sopenharmony_ci	sb = list_entry(b, struct ubifs_scan_node, list);
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	ubifs_assert(c, key_type(c, &sa->key) == UBIFS_DATA_KEY);
12062306a36Sopenharmony_ci	ubifs_assert(c, key_type(c, &sb->key) == UBIFS_DATA_KEY);
12162306a36Sopenharmony_ci	ubifs_assert(c, sa->type == UBIFS_DATA_NODE);
12262306a36Sopenharmony_ci	ubifs_assert(c, sb->type == UBIFS_DATA_NODE);
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	inuma = key_inum(c, &sa->key);
12562306a36Sopenharmony_ci	inumb = key_inum(c, &sb->key);
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	if (inuma == inumb) {
12862306a36Sopenharmony_ci		unsigned int blka = key_block(c, &sa->key);
12962306a36Sopenharmony_ci		unsigned int blkb = key_block(c, &sb->key);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci		if (blka <= blkb)
13262306a36Sopenharmony_ci			return -1;
13362306a36Sopenharmony_ci	} else if (inuma <= inumb)
13462306a36Sopenharmony_ci		return -1;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	return 1;
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/*
14062306a36Sopenharmony_ci * nondata_nodes_cmp - compare 2 non-data nodes.
14162306a36Sopenharmony_ci * @priv: UBIFS file-system description object
14262306a36Sopenharmony_ci * @a: first node
14362306a36Sopenharmony_ci * @a: second node
14462306a36Sopenharmony_ci *
14562306a36Sopenharmony_ci * This function compares nodes @a and @b. It makes sure that inode nodes go
14662306a36Sopenharmony_ci * first and sorted by length in descending order. Directory entry nodes go
14762306a36Sopenharmony_ci * after inode nodes and are sorted in ascending hash valuer order.
14862306a36Sopenharmony_ci */
14962306a36Sopenharmony_cistatic int nondata_nodes_cmp(void *priv, const struct list_head *a,
15062306a36Sopenharmony_ci			     const struct list_head *b)
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	ino_t inuma, inumb;
15362306a36Sopenharmony_ci	struct ubifs_info *c = priv;
15462306a36Sopenharmony_ci	struct ubifs_scan_node *sa, *sb;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	cond_resched();
15762306a36Sopenharmony_ci	if (a == b)
15862306a36Sopenharmony_ci		return 0;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	sa = list_entry(a, struct ubifs_scan_node, list);
16162306a36Sopenharmony_ci	sb = list_entry(b, struct ubifs_scan_node, list);
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	ubifs_assert(c, key_type(c, &sa->key) != UBIFS_DATA_KEY &&
16462306a36Sopenharmony_ci		     key_type(c, &sb->key) != UBIFS_DATA_KEY);
16562306a36Sopenharmony_ci	ubifs_assert(c, sa->type != UBIFS_DATA_NODE &&
16662306a36Sopenharmony_ci		     sb->type != UBIFS_DATA_NODE);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	/* Inodes go before directory entries */
16962306a36Sopenharmony_ci	if (sa->type == UBIFS_INO_NODE) {
17062306a36Sopenharmony_ci		if (sb->type == UBIFS_INO_NODE)
17162306a36Sopenharmony_ci			return sb->len - sa->len;
17262306a36Sopenharmony_ci		return -1;
17362306a36Sopenharmony_ci	}
17462306a36Sopenharmony_ci	if (sb->type == UBIFS_INO_NODE)
17562306a36Sopenharmony_ci		return 1;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	ubifs_assert(c, key_type(c, &sa->key) == UBIFS_DENT_KEY ||
17862306a36Sopenharmony_ci		     key_type(c, &sa->key) == UBIFS_XENT_KEY);
17962306a36Sopenharmony_ci	ubifs_assert(c, key_type(c, &sb->key) == UBIFS_DENT_KEY ||
18062306a36Sopenharmony_ci		     key_type(c, &sb->key) == UBIFS_XENT_KEY);
18162306a36Sopenharmony_ci	ubifs_assert(c, sa->type == UBIFS_DENT_NODE ||
18262306a36Sopenharmony_ci		     sa->type == UBIFS_XENT_NODE);
18362306a36Sopenharmony_ci	ubifs_assert(c, sb->type == UBIFS_DENT_NODE ||
18462306a36Sopenharmony_ci		     sb->type == UBIFS_XENT_NODE);
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	inuma = key_inum(c, &sa->key);
18762306a36Sopenharmony_ci	inumb = key_inum(c, &sb->key);
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	if (inuma == inumb) {
19062306a36Sopenharmony_ci		uint32_t hasha = key_hash(c, &sa->key);
19162306a36Sopenharmony_ci		uint32_t hashb = key_hash(c, &sb->key);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci		if (hasha <= hashb)
19462306a36Sopenharmony_ci			return -1;
19562306a36Sopenharmony_ci	} else if (inuma <= inumb)
19662306a36Sopenharmony_ci		return -1;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	return 1;
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/**
20262306a36Sopenharmony_ci * sort_nodes - sort nodes for GC.
20362306a36Sopenharmony_ci * @c: UBIFS file-system description object
20462306a36Sopenharmony_ci * @sleb: describes nodes to sort and contains the result on exit
20562306a36Sopenharmony_ci * @nondata: contains non-data nodes on exit
20662306a36Sopenharmony_ci * @min: minimum node size is returned here
20762306a36Sopenharmony_ci *
20862306a36Sopenharmony_ci * This function sorts the list of inodes to garbage collect. First of all, it
20962306a36Sopenharmony_ci * kills obsolete nodes and separates data and non-data nodes to the
21062306a36Sopenharmony_ci * @sleb->nodes and @nondata lists correspondingly.
21162306a36Sopenharmony_ci *
21262306a36Sopenharmony_ci * Data nodes are then sorted in block number order - this is important for
21362306a36Sopenharmony_ci * bulk-read; data nodes with lower inode number go before data nodes with
21462306a36Sopenharmony_ci * higher inode number, and data nodes with lower block number go before data
21562306a36Sopenharmony_ci * nodes with higher block number;
21662306a36Sopenharmony_ci *
21762306a36Sopenharmony_ci * Non-data nodes are sorted as follows.
21862306a36Sopenharmony_ci *   o First go inode nodes - they are sorted in descending length order.
21962306a36Sopenharmony_ci *   o Then go directory entry nodes - they are sorted in hash order, which
22062306a36Sopenharmony_ci *     should supposedly optimize 'readdir()'. Direntry nodes with lower parent
22162306a36Sopenharmony_ci *     inode number go before direntry nodes with higher parent inode number,
22262306a36Sopenharmony_ci *     and direntry nodes with lower name hash values go before direntry nodes
22362306a36Sopenharmony_ci *     with higher name hash values.
22462306a36Sopenharmony_ci *
22562306a36Sopenharmony_ci * This function returns zero in case of success and a negative error code in
22662306a36Sopenharmony_ci * case of failure.
22762306a36Sopenharmony_ci */
22862306a36Sopenharmony_cistatic int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
22962306a36Sopenharmony_ci		      struct list_head *nondata, int *min)
23062306a36Sopenharmony_ci{
23162306a36Sopenharmony_ci	int err;
23262306a36Sopenharmony_ci	struct ubifs_scan_node *snod, *tmp;
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	*min = INT_MAX;
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	/* Separate data nodes and non-data nodes */
23762306a36Sopenharmony_ci	list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
23862306a36Sopenharmony_ci		ubifs_assert(c, snod->type == UBIFS_INO_NODE  ||
23962306a36Sopenharmony_ci			     snod->type == UBIFS_DATA_NODE ||
24062306a36Sopenharmony_ci			     snod->type == UBIFS_DENT_NODE ||
24162306a36Sopenharmony_ci			     snod->type == UBIFS_XENT_NODE ||
24262306a36Sopenharmony_ci			     snod->type == UBIFS_TRUN_NODE ||
24362306a36Sopenharmony_ci			     snod->type == UBIFS_AUTH_NODE);
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci		if (snod->type != UBIFS_INO_NODE  &&
24662306a36Sopenharmony_ci		    snod->type != UBIFS_DATA_NODE &&
24762306a36Sopenharmony_ci		    snod->type != UBIFS_DENT_NODE &&
24862306a36Sopenharmony_ci		    snod->type != UBIFS_XENT_NODE) {
24962306a36Sopenharmony_ci			/* Probably truncation node, zap it */
25062306a36Sopenharmony_ci			list_del(&snod->list);
25162306a36Sopenharmony_ci			kfree(snod);
25262306a36Sopenharmony_ci			continue;
25362306a36Sopenharmony_ci		}
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci		ubifs_assert(c, key_type(c, &snod->key) == UBIFS_DATA_KEY ||
25662306a36Sopenharmony_ci			     key_type(c, &snod->key) == UBIFS_INO_KEY  ||
25762306a36Sopenharmony_ci			     key_type(c, &snod->key) == UBIFS_DENT_KEY ||
25862306a36Sopenharmony_ci			     key_type(c, &snod->key) == UBIFS_XENT_KEY);
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci		err = ubifs_tnc_has_node(c, &snod->key, 0, sleb->lnum,
26162306a36Sopenharmony_ci					 snod->offs, 0);
26262306a36Sopenharmony_ci		if (err < 0)
26362306a36Sopenharmony_ci			return err;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci		if (!err) {
26662306a36Sopenharmony_ci			/* The node is obsolete, remove it from the list */
26762306a36Sopenharmony_ci			list_del(&snod->list);
26862306a36Sopenharmony_ci			kfree(snod);
26962306a36Sopenharmony_ci			continue;
27062306a36Sopenharmony_ci		}
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci		if (snod->len < *min)
27362306a36Sopenharmony_ci			*min = snod->len;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci		if (key_type(c, &snod->key) != UBIFS_DATA_KEY)
27662306a36Sopenharmony_ci			list_move_tail(&snod->list, nondata);
27762306a36Sopenharmony_ci	}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	/* Sort data and non-data nodes */
28062306a36Sopenharmony_ci	list_sort(c, &sleb->nodes, &data_nodes_cmp);
28162306a36Sopenharmony_ci	list_sort(c, nondata, &nondata_nodes_cmp);
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	err = dbg_check_data_nodes_order(c, &sleb->nodes);
28462306a36Sopenharmony_ci	if (err)
28562306a36Sopenharmony_ci		return err;
28662306a36Sopenharmony_ci	err = dbg_check_nondata_nodes_order(c, nondata);
28762306a36Sopenharmony_ci	if (err)
28862306a36Sopenharmony_ci		return err;
28962306a36Sopenharmony_ci	return 0;
29062306a36Sopenharmony_ci}
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci/**
29362306a36Sopenharmony_ci * move_node - move a node.
29462306a36Sopenharmony_ci * @c: UBIFS file-system description object
29562306a36Sopenharmony_ci * @sleb: describes the LEB to move nodes from
29662306a36Sopenharmony_ci * @snod: the mode to move
29762306a36Sopenharmony_ci * @wbuf: write-buffer to move node to
29862306a36Sopenharmony_ci *
29962306a36Sopenharmony_ci * This function moves node @snod to @wbuf, changes TNC correspondingly, and
30062306a36Sopenharmony_ci * destroys @snod. Returns zero in case of success and a negative error code in
30162306a36Sopenharmony_ci * case of failure.
30262306a36Sopenharmony_ci */
30362306a36Sopenharmony_cistatic int move_node(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
30462306a36Sopenharmony_ci		     struct ubifs_scan_node *snod, struct ubifs_wbuf *wbuf)
30562306a36Sopenharmony_ci{
30662306a36Sopenharmony_ci	int err, new_lnum = wbuf->lnum, new_offs = wbuf->offs + wbuf->used;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	cond_resched();
30962306a36Sopenharmony_ci	err = ubifs_wbuf_write_nolock(wbuf, snod->node, snod->len);
31062306a36Sopenharmony_ci	if (err)
31162306a36Sopenharmony_ci		return err;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	err = ubifs_tnc_replace(c, &snod->key, sleb->lnum,
31462306a36Sopenharmony_ci				snod->offs, new_lnum, new_offs,
31562306a36Sopenharmony_ci				snod->len);
31662306a36Sopenharmony_ci	list_del(&snod->list);
31762306a36Sopenharmony_ci	kfree(snod);
31862306a36Sopenharmony_ci	return err;
31962306a36Sopenharmony_ci}
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci/**
32262306a36Sopenharmony_ci * move_nodes - move nodes.
32362306a36Sopenharmony_ci * @c: UBIFS file-system description object
32462306a36Sopenharmony_ci * @sleb: describes the LEB to move nodes from
32562306a36Sopenharmony_ci *
32662306a36Sopenharmony_ci * This function moves valid nodes from data LEB described by @sleb to the GC
32762306a36Sopenharmony_ci * journal head. This function returns zero in case of success, %-EAGAIN if
32862306a36Sopenharmony_ci * commit is required, and other negative error codes in case of other
32962306a36Sopenharmony_ci * failures.
33062306a36Sopenharmony_ci */
33162306a36Sopenharmony_cistatic int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
33262306a36Sopenharmony_ci{
33362306a36Sopenharmony_ci	int err, min;
33462306a36Sopenharmony_ci	LIST_HEAD(nondata);
33562306a36Sopenharmony_ci	struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	if (wbuf->lnum == -1) {
33862306a36Sopenharmony_ci		/*
33962306a36Sopenharmony_ci		 * The GC journal head is not set, because it is the first GC
34062306a36Sopenharmony_ci		 * invocation since mount.
34162306a36Sopenharmony_ci		 */
34262306a36Sopenharmony_ci		err = switch_gc_head(c);
34362306a36Sopenharmony_ci		if (err)
34462306a36Sopenharmony_ci			return err;
34562306a36Sopenharmony_ci	}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	err = sort_nodes(c, sleb, &nondata, &min);
34862306a36Sopenharmony_ci	if (err)
34962306a36Sopenharmony_ci		goto out;
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	/* Write nodes to their new location. Use the first-fit strategy */
35262306a36Sopenharmony_ci	while (1) {
35362306a36Sopenharmony_ci		int avail, moved = 0;
35462306a36Sopenharmony_ci		struct ubifs_scan_node *snod, *tmp;
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci		/* Move data nodes */
35762306a36Sopenharmony_ci		list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
35862306a36Sopenharmony_ci			avail = c->leb_size - wbuf->offs - wbuf->used -
35962306a36Sopenharmony_ci					ubifs_auth_node_sz(c);
36062306a36Sopenharmony_ci			if  (snod->len > avail)
36162306a36Sopenharmony_ci				/*
36262306a36Sopenharmony_ci				 * Do not skip data nodes in order to optimize
36362306a36Sopenharmony_ci				 * bulk-read.
36462306a36Sopenharmony_ci				 */
36562306a36Sopenharmony_ci				break;
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci			err = ubifs_shash_update(c, c->jheads[GCHD].log_hash,
36862306a36Sopenharmony_ci						 snod->node, snod->len);
36962306a36Sopenharmony_ci			if (err)
37062306a36Sopenharmony_ci				goto out;
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci			err = move_node(c, sleb, snod, wbuf);
37362306a36Sopenharmony_ci			if (err)
37462306a36Sopenharmony_ci				goto out;
37562306a36Sopenharmony_ci			moved = 1;
37662306a36Sopenharmony_ci		}
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci		/* Move non-data nodes */
37962306a36Sopenharmony_ci		list_for_each_entry_safe(snod, tmp, &nondata, list) {
38062306a36Sopenharmony_ci			avail = c->leb_size - wbuf->offs - wbuf->used -
38162306a36Sopenharmony_ci					ubifs_auth_node_sz(c);
38262306a36Sopenharmony_ci			if (avail < min)
38362306a36Sopenharmony_ci				break;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci			if  (snod->len > avail) {
38662306a36Sopenharmony_ci				/*
38762306a36Sopenharmony_ci				 * Keep going only if this is an inode with
38862306a36Sopenharmony_ci				 * some data. Otherwise stop and switch the GC
38962306a36Sopenharmony_ci				 * head. IOW, we assume that data-less inode
39062306a36Sopenharmony_ci				 * nodes and direntry nodes are roughly of the
39162306a36Sopenharmony_ci				 * same size.
39262306a36Sopenharmony_ci				 */
39362306a36Sopenharmony_ci				if (key_type(c, &snod->key) == UBIFS_DENT_KEY ||
39462306a36Sopenharmony_ci				    snod->len == UBIFS_INO_NODE_SZ)
39562306a36Sopenharmony_ci					break;
39662306a36Sopenharmony_ci				continue;
39762306a36Sopenharmony_ci			}
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci			err = ubifs_shash_update(c, c->jheads[GCHD].log_hash,
40062306a36Sopenharmony_ci						 snod->node, snod->len);
40162306a36Sopenharmony_ci			if (err)
40262306a36Sopenharmony_ci				goto out;
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci			err = move_node(c, sleb, snod, wbuf);
40562306a36Sopenharmony_ci			if (err)
40662306a36Sopenharmony_ci				goto out;
40762306a36Sopenharmony_ci			moved = 1;
40862306a36Sopenharmony_ci		}
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci		if (ubifs_authenticated(c) && moved) {
41162306a36Sopenharmony_ci			struct ubifs_auth_node *auth;
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci			auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS);
41462306a36Sopenharmony_ci			if (!auth) {
41562306a36Sopenharmony_ci				err = -ENOMEM;
41662306a36Sopenharmony_ci				goto out;
41762306a36Sopenharmony_ci			}
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci			err = ubifs_prepare_auth_node(c, auth,
42062306a36Sopenharmony_ci						c->jheads[GCHD].log_hash);
42162306a36Sopenharmony_ci			if (err) {
42262306a36Sopenharmony_ci				kfree(auth);
42362306a36Sopenharmony_ci				goto out;
42462306a36Sopenharmony_ci			}
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci			err = ubifs_wbuf_write_nolock(wbuf, auth,
42762306a36Sopenharmony_ci						      ubifs_auth_node_sz(c));
42862306a36Sopenharmony_ci			if (err) {
42962306a36Sopenharmony_ci				kfree(auth);
43062306a36Sopenharmony_ci				goto out;
43162306a36Sopenharmony_ci			}
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci			ubifs_add_dirt(c, wbuf->lnum, ubifs_auth_node_sz(c));
43462306a36Sopenharmony_ci		}
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci		if (list_empty(&sleb->nodes) && list_empty(&nondata))
43762306a36Sopenharmony_ci			break;
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci		/*
44062306a36Sopenharmony_ci		 * Waste the rest of the space in the LEB and switch to the
44162306a36Sopenharmony_ci		 * next LEB.
44262306a36Sopenharmony_ci		 */
44362306a36Sopenharmony_ci		err = switch_gc_head(c);
44462306a36Sopenharmony_ci		if (err)
44562306a36Sopenharmony_ci			goto out;
44662306a36Sopenharmony_ci	}
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	return 0;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ciout:
45162306a36Sopenharmony_ci	list_splice_tail(&nondata, &sleb->nodes);
45262306a36Sopenharmony_ci	return err;
45362306a36Sopenharmony_ci}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci/**
45662306a36Sopenharmony_ci * gc_sync_wbufs - sync write-buffers for GC.
45762306a36Sopenharmony_ci * @c: UBIFS file-system description object
45862306a36Sopenharmony_ci *
45962306a36Sopenharmony_ci * We must guarantee that obsoleting nodes are on flash. Unfortunately they may
46062306a36Sopenharmony_ci * be in a write-buffer instead. That is, a node could be written to a
46162306a36Sopenharmony_ci * write-buffer, obsoleting another node in a LEB that is GC'd. If that LEB is
46262306a36Sopenharmony_ci * erased before the write-buffer is sync'd and then there is an unclean
46362306a36Sopenharmony_ci * unmount, then an existing node is lost. To avoid this, we sync all
46462306a36Sopenharmony_ci * write-buffers.
46562306a36Sopenharmony_ci *
46662306a36Sopenharmony_ci * This function returns %0 on success or a negative error code on failure.
46762306a36Sopenharmony_ci */
46862306a36Sopenharmony_cistatic int gc_sync_wbufs(struct ubifs_info *c)
46962306a36Sopenharmony_ci{
47062306a36Sopenharmony_ci	int err, i;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	for (i = 0; i < c->jhead_cnt; i++) {
47362306a36Sopenharmony_ci		if (i == GCHD)
47462306a36Sopenharmony_ci			continue;
47562306a36Sopenharmony_ci		err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
47662306a36Sopenharmony_ci		if (err)
47762306a36Sopenharmony_ci			return err;
47862306a36Sopenharmony_ci	}
47962306a36Sopenharmony_ci	return 0;
48062306a36Sopenharmony_ci}
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci/**
48362306a36Sopenharmony_ci * ubifs_garbage_collect_leb - garbage-collect a logical eraseblock.
48462306a36Sopenharmony_ci * @c: UBIFS file-system description object
48562306a36Sopenharmony_ci * @lp: describes the LEB to garbage collect
48662306a36Sopenharmony_ci *
48762306a36Sopenharmony_ci * This function garbage-collects an LEB and returns one of the @LEB_FREED,
48862306a36Sopenharmony_ci * @LEB_RETAINED, etc positive codes in case of success, %-EAGAIN if commit is
48962306a36Sopenharmony_ci * required, and other negative error codes in case of failures.
49062306a36Sopenharmony_ci */
49162306a36Sopenharmony_ciint ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
49262306a36Sopenharmony_ci{
49362306a36Sopenharmony_ci	struct ubifs_scan_leb *sleb;
49462306a36Sopenharmony_ci	struct ubifs_scan_node *snod;
49562306a36Sopenharmony_ci	struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
49662306a36Sopenharmony_ci	int err = 0, lnum = lp->lnum;
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	ubifs_assert(c, c->gc_lnum != -1 || wbuf->offs + wbuf->used == 0 ||
49962306a36Sopenharmony_ci		     c->need_recovery);
50062306a36Sopenharmony_ci	ubifs_assert(c, c->gc_lnum != lnum);
50162306a36Sopenharmony_ci	ubifs_assert(c, wbuf->lnum != lnum);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	if (lp->free + lp->dirty == c->leb_size) {
50462306a36Sopenharmony_ci		/* Special case - a free LEB  */
50562306a36Sopenharmony_ci		dbg_gc("LEB %d is free, return it", lp->lnum);
50662306a36Sopenharmony_ci		ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci		if (lp->free != c->leb_size) {
50962306a36Sopenharmony_ci			/*
51062306a36Sopenharmony_ci			 * Write buffers must be sync'd before unmapping
51162306a36Sopenharmony_ci			 * freeable LEBs, because one of them may contain data
51262306a36Sopenharmony_ci			 * which obsoletes something in 'lp->lnum'.
51362306a36Sopenharmony_ci			 */
51462306a36Sopenharmony_ci			err = gc_sync_wbufs(c);
51562306a36Sopenharmony_ci			if (err)
51662306a36Sopenharmony_ci				return err;
51762306a36Sopenharmony_ci			err = ubifs_change_one_lp(c, lp->lnum, c->leb_size,
51862306a36Sopenharmony_ci						  0, 0, 0, 0);
51962306a36Sopenharmony_ci			if (err)
52062306a36Sopenharmony_ci				return err;
52162306a36Sopenharmony_ci		}
52262306a36Sopenharmony_ci		err = ubifs_leb_unmap(c, lp->lnum);
52362306a36Sopenharmony_ci		if (err)
52462306a36Sopenharmony_ci			return err;
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci		if (c->gc_lnum == -1) {
52762306a36Sopenharmony_ci			c->gc_lnum = lnum;
52862306a36Sopenharmony_ci			return LEB_RETAINED;
52962306a36Sopenharmony_ci		}
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci		return LEB_FREED;
53262306a36Sopenharmony_ci	}
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	/*
53562306a36Sopenharmony_ci	 * We scan the entire LEB even though we only really need to scan up to
53662306a36Sopenharmony_ci	 * (c->leb_size - lp->free).
53762306a36Sopenharmony_ci	 */
53862306a36Sopenharmony_ci	sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0);
53962306a36Sopenharmony_ci	if (IS_ERR(sleb))
54062306a36Sopenharmony_ci		return PTR_ERR(sleb);
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci	ubifs_assert(c, !list_empty(&sleb->nodes));
54362306a36Sopenharmony_ci	snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	if (snod->type == UBIFS_IDX_NODE) {
54662306a36Sopenharmony_ci		struct ubifs_gced_idx_leb *idx_gc;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci		dbg_gc("indexing LEB %d (free %d, dirty %d)",
54962306a36Sopenharmony_ci		       lnum, lp->free, lp->dirty);
55062306a36Sopenharmony_ci		list_for_each_entry(snod, &sleb->nodes, list) {
55162306a36Sopenharmony_ci			struct ubifs_idx_node *idx = snod->node;
55262306a36Sopenharmony_ci			int level = le16_to_cpu(idx->level);
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci			ubifs_assert(c, snod->type == UBIFS_IDX_NODE);
55562306a36Sopenharmony_ci			key_read(c, ubifs_idx_key(c, idx), &snod->key);
55662306a36Sopenharmony_ci			err = ubifs_dirty_idx_node(c, &snod->key, level, lnum,
55762306a36Sopenharmony_ci						   snod->offs);
55862306a36Sopenharmony_ci			if (err)
55962306a36Sopenharmony_ci				goto out;
56062306a36Sopenharmony_ci		}
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci		idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS);
56362306a36Sopenharmony_ci		if (!idx_gc) {
56462306a36Sopenharmony_ci			err = -ENOMEM;
56562306a36Sopenharmony_ci			goto out;
56662306a36Sopenharmony_ci		}
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci		idx_gc->lnum = lnum;
56962306a36Sopenharmony_ci		idx_gc->unmap = 0;
57062306a36Sopenharmony_ci		list_add(&idx_gc->list, &c->idx_gc);
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci		/*
57362306a36Sopenharmony_ci		 * Don't release the LEB until after the next commit, because
57462306a36Sopenharmony_ci		 * it may contain data which is needed for recovery. So
57562306a36Sopenharmony_ci		 * although we freed this LEB, it will become usable only after
57662306a36Sopenharmony_ci		 * the commit.
57762306a36Sopenharmony_ci		 */
57862306a36Sopenharmony_ci		err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0,
57962306a36Sopenharmony_ci					  LPROPS_INDEX, 1);
58062306a36Sopenharmony_ci		if (err)
58162306a36Sopenharmony_ci			goto out;
58262306a36Sopenharmony_ci		err = LEB_FREED_IDX;
58362306a36Sopenharmony_ci	} else {
58462306a36Sopenharmony_ci		dbg_gc("data LEB %d (free %d, dirty %d)",
58562306a36Sopenharmony_ci		       lnum, lp->free, lp->dirty);
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci		err = move_nodes(c, sleb);
58862306a36Sopenharmony_ci		if (err)
58962306a36Sopenharmony_ci			goto out_inc_seq;
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci		err = gc_sync_wbufs(c);
59262306a36Sopenharmony_ci		if (err)
59362306a36Sopenharmony_ci			goto out_inc_seq;
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci		err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0);
59662306a36Sopenharmony_ci		if (err)
59762306a36Sopenharmony_ci			goto out_inc_seq;
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci		/* Allow for races with TNC */
60062306a36Sopenharmony_ci		c->gced_lnum = lnum;
60162306a36Sopenharmony_ci		smp_wmb();
60262306a36Sopenharmony_ci		c->gc_seq += 1;
60362306a36Sopenharmony_ci		smp_wmb();
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci		if (c->gc_lnum == -1) {
60662306a36Sopenharmony_ci			c->gc_lnum = lnum;
60762306a36Sopenharmony_ci			err = LEB_RETAINED;
60862306a36Sopenharmony_ci		} else {
60962306a36Sopenharmony_ci			err = ubifs_wbuf_sync_nolock(wbuf);
61062306a36Sopenharmony_ci			if (err)
61162306a36Sopenharmony_ci				goto out;
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci			err = ubifs_leb_unmap(c, lnum);
61462306a36Sopenharmony_ci			if (err)
61562306a36Sopenharmony_ci				goto out;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci			err = LEB_FREED;
61862306a36Sopenharmony_ci		}
61962306a36Sopenharmony_ci	}
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ciout:
62262306a36Sopenharmony_ci	ubifs_scan_destroy(sleb);
62362306a36Sopenharmony_ci	return err;
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ciout_inc_seq:
62662306a36Sopenharmony_ci	/* We may have moved at least some nodes so allow for races with TNC */
62762306a36Sopenharmony_ci	c->gced_lnum = lnum;
62862306a36Sopenharmony_ci	smp_wmb();
62962306a36Sopenharmony_ci	c->gc_seq += 1;
63062306a36Sopenharmony_ci	smp_wmb();
63162306a36Sopenharmony_ci	goto out;
63262306a36Sopenharmony_ci}
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci/**
63562306a36Sopenharmony_ci * ubifs_garbage_collect - UBIFS garbage collector.
63662306a36Sopenharmony_ci * @c: UBIFS file-system description object
63762306a36Sopenharmony_ci * @anyway: do GC even if there are free LEBs
63862306a36Sopenharmony_ci *
63962306a36Sopenharmony_ci * This function does out-of-place garbage collection. The return codes are:
64062306a36Sopenharmony_ci *   o positive LEB number if the LEB has been freed and may be used;
64162306a36Sopenharmony_ci *   o %-EAGAIN if the caller has to run commit;
64262306a36Sopenharmony_ci *   o %-ENOSPC if GC failed to make any progress;
64362306a36Sopenharmony_ci *   o other negative error codes in case of other errors.
64462306a36Sopenharmony_ci *
64562306a36Sopenharmony_ci * Garbage collector writes data to the journal when GC'ing data LEBs, and just
64662306a36Sopenharmony_ci * marking indexing nodes dirty when GC'ing indexing LEBs. Thus, at some point
64762306a36Sopenharmony_ci * commit may be required. But commit cannot be run from inside GC, because the
64862306a36Sopenharmony_ci * caller might be holding the commit lock, so %-EAGAIN is returned instead;
64962306a36Sopenharmony_ci * And this error code means that the caller has to run commit, and re-run GC
65062306a36Sopenharmony_ci * if there is still no free space.
65162306a36Sopenharmony_ci *
65262306a36Sopenharmony_ci * There are many reasons why this function may return %-EAGAIN:
65362306a36Sopenharmony_ci * o the log is full and there is no space to write an LEB reference for
65462306a36Sopenharmony_ci *   @c->gc_lnum;
65562306a36Sopenharmony_ci * o the journal is too large and exceeds size limitations;
65662306a36Sopenharmony_ci * o GC moved indexing LEBs, but they can be used only after the commit;
65762306a36Sopenharmony_ci * o the shrinker fails to find clean znodes to free and requests the commit;
65862306a36Sopenharmony_ci * o etc.
65962306a36Sopenharmony_ci *
66062306a36Sopenharmony_ci * Note, if the file-system is close to be full, this function may return
66162306a36Sopenharmony_ci * %-EAGAIN infinitely, so the caller has to limit amount of re-invocations of
66262306a36Sopenharmony_ci * the function. E.g., this happens if the limits on the journal size are too
66362306a36Sopenharmony_ci * tough and GC writes too much to the journal before an LEB is freed. This
66462306a36Sopenharmony_ci * might also mean that the journal is too large, and the TNC becomes to big,
66562306a36Sopenharmony_ci * so that the shrinker is constantly called, finds not clean znodes to free,
66662306a36Sopenharmony_ci * and requests commit. Well, this may also happen if the journal is all right,
66762306a36Sopenharmony_ci * but another kernel process consumes too much memory. Anyway, infinite
66862306a36Sopenharmony_ci * %-EAGAIN may happen, but in some extreme/misconfiguration cases.
66962306a36Sopenharmony_ci */
67062306a36Sopenharmony_ciint ubifs_garbage_collect(struct ubifs_info *c, int anyway)
67162306a36Sopenharmony_ci{
67262306a36Sopenharmony_ci	int i, err, ret, min_space = c->dead_wm;
67362306a36Sopenharmony_ci	struct ubifs_lprops lp;
67462306a36Sopenharmony_ci	struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	ubifs_assert_cmt_locked(c);
67762306a36Sopenharmony_ci	ubifs_assert(c, !c->ro_media && !c->ro_mount);
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	if (ubifs_gc_should_commit(c))
68062306a36Sopenharmony_ci		return -EAGAIN;
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	if (c->ro_error) {
68562306a36Sopenharmony_ci		ret = -EROFS;
68662306a36Sopenharmony_ci		goto out_unlock;
68762306a36Sopenharmony_ci	}
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ci	/* We expect the write-buffer to be empty on entry */
69062306a36Sopenharmony_ci	ubifs_assert(c, !wbuf->used);
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	for (i = 0; ; i++) {
69362306a36Sopenharmony_ci		int space_before, space_after;
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci		/* Maybe continue after find and break before find */
69662306a36Sopenharmony_ci		lp.lnum = -1;
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci		cond_resched();
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci		/* Give the commit an opportunity to run */
70162306a36Sopenharmony_ci		if (ubifs_gc_should_commit(c)) {
70262306a36Sopenharmony_ci			ret = -EAGAIN;
70362306a36Sopenharmony_ci			break;
70462306a36Sopenharmony_ci		}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci		if (i > SOFT_LEBS_LIMIT && !list_empty(&c->idx_gc)) {
70762306a36Sopenharmony_ci			/*
70862306a36Sopenharmony_ci			 * We've done enough iterations. Indexing LEBs were
70962306a36Sopenharmony_ci			 * moved and will be available after the commit.
71062306a36Sopenharmony_ci			 */
71162306a36Sopenharmony_ci			dbg_gc("soft limit, some index LEBs GC'ed, -EAGAIN");
71262306a36Sopenharmony_ci			ubifs_commit_required(c);
71362306a36Sopenharmony_ci			ret = -EAGAIN;
71462306a36Sopenharmony_ci			break;
71562306a36Sopenharmony_ci		}
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci		if (i > HARD_LEBS_LIMIT) {
71862306a36Sopenharmony_ci			/*
71962306a36Sopenharmony_ci			 * We've moved too many LEBs and have not made
72062306a36Sopenharmony_ci			 * progress, give up.
72162306a36Sopenharmony_ci			 */
72262306a36Sopenharmony_ci			dbg_gc("hard limit, -ENOSPC");
72362306a36Sopenharmony_ci			ret = -ENOSPC;
72462306a36Sopenharmony_ci			break;
72562306a36Sopenharmony_ci		}
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci		/*
72862306a36Sopenharmony_ci		 * Empty and freeable LEBs can turn up while we waited for
72962306a36Sopenharmony_ci		 * the wbuf lock, or while we have been running GC. In that
73062306a36Sopenharmony_ci		 * case, we should just return one of those instead of
73162306a36Sopenharmony_ci		 * continuing to GC dirty LEBs. Hence we request
73262306a36Sopenharmony_ci		 * 'ubifs_find_dirty_leb()' to return an empty LEB if it can.
73362306a36Sopenharmony_ci		 */
73462306a36Sopenharmony_ci		ret = ubifs_find_dirty_leb(c, &lp, min_space, anyway ? 0 : 1);
73562306a36Sopenharmony_ci		if (ret) {
73662306a36Sopenharmony_ci			if (ret == -ENOSPC)
73762306a36Sopenharmony_ci				dbg_gc("no more dirty LEBs");
73862306a36Sopenharmony_ci			break;
73962306a36Sopenharmony_ci		}
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci		dbg_gc("found LEB %d: free %d, dirty %d, sum %d (min. space %d)",
74262306a36Sopenharmony_ci		       lp.lnum, lp.free, lp.dirty, lp.free + lp.dirty,
74362306a36Sopenharmony_ci		       min_space);
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci		space_before = c->leb_size - wbuf->offs - wbuf->used;
74662306a36Sopenharmony_ci		if (wbuf->lnum == -1)
74762306a36Sopenharmony_ci			space_before = 0;
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci		ret = ubifs_garbage_collect_leb(c, &lp);
75062306a36Sopenharmony_ci		if (ret < 0) {
75162306a36Sopenharmony_ci			if (ret == -EAGAIN) {
75262306a36Sopenharmony_ci				/*
75362306a36Sopenharmony_ci				 * This is not error, so we have to return the
75462306a36Sopenharmony_ci				 * LEB to lprops. But if 'ubifs_return_leb()'
75562306a36Sopenharmony_ci				 * fails, its failure code is propagated to the
75662306a36Sopenharmony_ci				 * caller instead of the original '-EAGAIN'.
75762306a36Sopenharmony_ci				 */
75862306a36Sopenharmony_ci				err = ubifs_return_leb(c, lp.lnum);
75962306a36Sopenharmony_ci				if (err) {
76062306a36Sopenharmony_ci					ret = err;
76162306a36Sopenharmony_ci					/*
76262306a36Sopenharmony_ci					 * An LEB may always be "taken",
76362306a36Sopenharmony_ci					 * so setting ubifs to read-only,
76462306a36Sopenharmony_ci					 * and then executing sync wbuf will
76562306a36Sopenharmony_ci					 * return -EROFS and enter the "out"
76662306a36Sopenharmony_ci					 * error branch.
76762306a36Sopenharmony_ci					 */
76862306a36Sopenharmony_ci					ubifs_ro_mode(c, ret);
76962306a36Sopenharmony_ci				}
77062306a36Sopenharmony_ci				/*  Maybe double return LEB if goto out */
77162306a36Sopenharmony_ci				lp.lnum = -1;
77262306a36Sopenharmony_ci				break;
77362306a36Sopenharmony_ci			}
77462306a36Sopenharmony_ci			goto out;
77562306a36Sopenharmony_ci		}
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci		if (ret == LEB_FREED) {
77862306a36Sopenharmony_ci			/* An LEB has been freed and is ready for use */
77962306a36Sopenharmony_ci			dbg_gc("LEB %d freed, return", lp.lnum);
78062306a36Sopenharmony_ci			ret = lp.lnum;
78162306a36Sopenharmony_ci			break;
78262306a36Sopenharmony_ci		}
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ci		if (ret == LEB_FREED_IDX) {
78562306a36Sopenharmony_ci			/*
78662306a36Sopenharmony_ci			 * This was an indexing LEB and it cannot be
78762306a36Sopenharmony_ci			 * immediately used. And instead of requesting the
78862306a36Sopenharmony_ci			 * commit straight away, we try to garbage collect some
78962306a36Sopenharmony_ci			 * more.
79062306a36Sopenharmony_ci			 */
79162306a36Sopenharmony_ci			dbg_gc("indexing LEB %d freed, continue", lp.lnum);
79262306a36Sopenharmony_ci			continue;
79362306a36Sopenharmony_ci		}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci		ubifs_assert(c, ret == LEB_RETAINED);
79662306a36Sopenharmony_ci		space_after = c->leb_size - wbuf->offs - wbuf->used;
79762306a36Sopenharmony_ci		dbg_gc("LEB %d retained, freed %d bytes", lp.lnum,
79862306a36Sopenharmony_ci		       space_after - space_before);
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci		if (space_after > space_before) {
80162306a36Sopenharmony_ci			/* GC makes progress, keep working */
80262306a36Sopenharmony_ci			min_space >>= 1;
80362306a36Sopenharmony_ci			if (min_space < c->dead_wm)
80462306a36Sopenharmony_ci				min_space = c->dead_wm;
80562306a36Sopenharmony_ci			continue;
80662306a36Sopenharmony_ci		}
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci		dbg_gc("did not make progress");
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci		/*
81162306a36Sopenharmony_ci		 * GC moved an LEB bud have not done any progress. This means
81262306a36Sopenharmony_ci		 * that the previous GC head LEB contained too few free space
81362306a36Sopenharmony_ci		 * and the LEB which was GC'ed contained only large nodes which
81462306a36Sopenharmony_ci		 * did not fit that space.
81562306a36Sopenharmony_ci		 *
81662306a36Sopenharmony_ci		 * We can do 2 things:
81762306a36Sopenharmony_ci		 * 1. pick another LEB in a hope it'll contain a small node
81862306a36Sopenharmony_ci		 *    which will fit the space we have at the end of current GC
81962306a36Sopenharmony_ci		 *    head LEB, but there is no guarantee, so we try this out
82062306a36Sopenharmony_ci		 *    unless we have already been working for too long;
82162306a36Sopenharmony_ci		 * 2. request an LEB with more dirty space, which will force
82262306a36Sopenharmony_ci		 *    'ubifs_find_dirty_leb()' to start scanning the lprops
82362306a36Sopenharmony_ci		 *    table, instead of just picking one from the heap
82462306a36Sopenharmony_ci		 *    (previously it already picked the dirtiest LEB).
82562306a36Sopenharmony_ci		 */
82662306a36Sopenharmony_ci		if (i < SOFT_LEBS_LIMIT) {
82762306a36Sopenharmony_ci			dbg_gc("try again");
82862306a36Sopenharmony_ci			continue;
82962306a36Sopenharmony_ci		}
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci		min_space <<= 1;
83262306a36Sopenharmony_ci		if (min_space > c->dark_wm)
83362306a36Sopenharmony_ci			min_space = c->dark_wm;
83462306a36Sopenharmony_ci		dbg_gc("set min. space to %d", min_space);
83562306a36Sopenharmony_ci	}
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	if (ret == -ENOSPC && !list_empty(&c->idx_gc)) {
83862306a36Sopenharmony_ci		dbg_gc("no space, some index LEBs GC'ed, -EAGAIN");
83962306a36Sopenharmony_ci		ubifs_commit_required(c);
84062306a36Sopenharmony_ci		ret = -EAGAIN;
84162306a36Sopenharmony_ci	}
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci	err = ubifs_wbuf_sync_nolock(wbuf);
84462306a36Sopenharmony_ci	if (!err)
84562306a36Sopenharmony_ci		err = ubifs_leb_unmap(c, c->gc_lnum);
84662306a36Sopenharmony_ci	if (err) {
84762306a36Sopenharmony_ci		ret = err;
84862306a36Sopenharmony_ci		goto out;
84962306a36Sopenharmony_ci	}
85062306a36Sopenharmony_ciout_unlock:
85162306a36Sopenharmony_ci	mutex_unlock(&wbuf->io_mutex);
85262306a36Sopenharmony_ci	return ret;
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ciout:
85562306a36Sopenharmony_ci	ubifs_assert(c, ret < 0);
85662306a36Sopenharmony_ci	ubifs_assert(c, ret != -ENOSPC && ret != -EAGAIN);
85762306a36Sopenharmony_ci	ubifs_wbuf_sync_nolock(wbuf);
85862306a36Sopenharmony_ci	ubifs_ro_mode(c, ret);
85962306a36Sopenharmony_ci	mutex_unlock(&wbuf->io_mutex);
86062306a36Sopenharmony_ci	if (lp.lnum != -1)
86162306a36Sopenharmony_ci		ubifs_return_leb(c, lp.lnum);
86262306a36Sopenharmony_ci	return ret;
86362306a36Sopenharmony_ci}
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci/**
86662306a36Sopenharmony_ci * ubifs_gc_start_commit - garbage collection at start of commit.
86762306a36Sopenharmony_ci * @c: UBIFS file-system description object
86862306a36Sopenharmony_ci *
86962306a36Sopenharmony_ci * If a LEB has only dirty and free space, then we may safely unmap it and make
87062306a36Sopenharmony_ci * it free.  Note, we cannot do this with indexing LEBs because dirty space may
87162306a36Sopenharmony_ci * correspond index nodes that are required for recovery.  In that case, the
87262306a36Sopenharmony_ci * LEB cannot be unmapped until after the next commit.
87362306a36Sopenharmony_ci *
87462306a36Sopenharmony_ci * This function returns %0 upon success and a negative error code upon failure.
87562306a36Sopenharmony_ci */
87662306a36Sopenharmony_ciint ubifs_gc_start_commit(struct ubifs_info *c)
87762306a36Sopenharmony_ci{
87862306a36Sopenharmony_ci	struct ubifs_gced_idx_leb *idx_gc;
87962306a36Sopenharmony_ci	const struct ubifs_lprops *lp;
88062306a36Sopenharmony_ci	int err = 0, flags;
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci	ubifs_get_lprops(c);
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci	/*
88562306a36Sopenharmony_ci	 * Unmap (non-index) freeable LEBs. Note that recovery requires that all
88662306a36Sopenharmony_ci	 * wbufs are sync'd before this, which is done in 'do_commit()'.
88762306a36Sopenharmony_ci	 */
88862306a36Sopenharmony_ci	while (1) {
88962306a36Sopenharmony_ci		lp = ubifs_fast_find_freeable(c);
89062306a36Sopenharmony_ci		if (!lp)
89162306a36Sopenharmony_ci			break;
89262306a36Sopenharmony_ci		ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
89362306a36Sopenharmony_ci		ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
89462306a36Sopenharmony_ci		err = ubifs_leb_unmap(c, lp->lnum);
89562306a36Sopenharmony_ci		if (err)
89662306a36Sopenharmony_ci			goto out;
89762306a36Sopenharmony_ci		lp = ubifs_change_lp(c, lp, c->leb_size, 0, lp->flags, 0);
89862306a36Sopenharmony_ci		if (IS_ERR(lp)) {
89962306a36Sopenharmony_ci			err = PTR_ERR(lp);
90062306a36Sopenharmony_ci			goto out;
90162306a36Sopenharmony_ci		}
90262306a36Sopenharmony_ci		ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
90362306a36Sopenharmony_ci		ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
90462306a36Sopenharmony_ci	}
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci	/* Mark GC'd index LEBs OK to unmap after this commit finishes */
90762306a36Sopenharmony_ci	list_for_each_entry(idx_gc, &c->idx_gc, list)
90862306a36Sopenharmony_ci		idx_gc->unmap = 1;
90962306a36Sopenharmony_ci
91062306a36Sopenharmony_ci	/* Record index freeable LEBs for unmapping after commit */
91162306a36Sopenharmony_ci	while (1) {
91262306a36Sopenharmony_ci		lp = ubifs_fast_find_frdi_idx(c);
91362306a36Sopenharmony_ci		if (IS_ERR(lp)) {
91462306a36Sopenharmony_ci			err = PTR_ERR(lp);
91562306a36Sopenharmony_ci			goto out;
91662306a36Sopenharmony_ci		}
91762306a36Sopenharmony_ci		if (!lp)
91862306a36Sopenharmony_ci			break;
91962306a36Sopenharmony_ci		idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS);
92062306a36Sopenharmony_ci		if (!idx_gc) {
92162306a36Sopenharmony_ci			err = -ENOMEM;
92262306a36Sopenharmony_ci			goto out;
92362306a36Sopenharmony_ci		}
92462306a36Sopenharmony_ci		ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
92562306a36Sopenharmony_ci		ubifs_assert(c, lp->flags & LPROPS_INDEX);
92662306a36Sopenharmony_ci		/* Don't release the LEB until after the next commit */
92762306a36Sopenharmony_ci		flags = (lp->flags | LPROPS_TAKEN) ^ LPROPS_INDEX;
92862306a36Sopenharmony_ci		lp = ubifs_change_lp(c, lp, c->leb_size, 0, flags, 1);
92962306a36Sopenharmony_ci		if (IS_ERR(lp)) {
93062306a36Sopenharmony_ci			err = PTR_ERR(lp);
93162306a36Sopenharmony_ci			kfree(idx_gc);
93262306a36Sopenharmony_ci			goto out;
93362306a36Sopenharmony_ci		}
93462306a36Sopenharmony_ci		ubifs_assert(c, lp->flags & LPROPS_TAKEN);
93562306a36Sopenharmony_ci		ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
93662306a36Sopenharmony_ci		idx_gc->lnum = lp->lnum;
93762306a36Sopenharmony_ci		idx_gc->unmap = 1;
93862306a36Sopenharmony_ci		list_add(&idx_gc->list, &c->idx_gc);
93962306a36Sopenharmony_ci	}
94062306a36Sopenharmony_ciout:
94162306a36Sopenharmony_ci	ubifs_release_lprops(c);
94262306a36Sopenharmony_ci	return err;
94362306a36Sopenharmony_ci}
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci/**
94662306a36Sopenharmony_ci * ubifs_gc_end_commit - garbage collection at end of commit.
94762306a36Sopenharmony_ci * @c: UBIFS file-system description object
94862306a36Sopenharmony_ci *
94962306a36Sopenharmony_ci * This function completes out-of-place garbage collection of index LEBs.
95062306a36Sopenharmony_ci */
95162306a36Sopenharmony_ciint ubifs_gc_end_commit(struct ubifs_info *c)
95262306a36Sopenharmony_ci{
95362306a36Sopenharmony_ci	struct ubifs_gced_idx_leb *idx_gc, *tmp;
95462306a36Sopenharmony_ci	struct ubifs_wbuf *wbuf;
95562306a36Sopenharmony_ci	int err = 0;
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci	wbuf = &c->jheads[GCHD].wbuf;
95862306a36Sopenharmony_ci	mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
95962306a36Sopenharmony_ci	list_for_each_entry_safe(idx_gc, tmp, &c->idx_gc, list)
96062306a36Sopenharmony_ci		if (idx_gc->unmap) {
96162306a36Sopenharmony_ci			dbg_gc("LEB %d", idx_gc->lnum);
96262306a36Sopenharmony_ci			err = ubifs_leb_unmap(c, idx_gc->lnum);
96362306a36Sopenharmony_ci			if (err)
96462306a36Sopenharmony_ci				goto out;
96562306a36Sopenharmony_ci			err = ubifs_change_one_lp(c, idx_gc->lnum, LPROPS_NC,
96662306a36Sopenharmony_ci					  LPROPS_NC, 0, LPROPS_TAKEN, -1);
96762306a36Sopenharmony_ci			if (err)
96862306a36Sopenharmony_ci				goto out;
96962306a36Sopenharmony_ci			list_del(&idx_gc->list);
97062306a36Sopenharmony_ci			kfree(idx_gc);
97162306a36Sopenharmony_ci		}
97262306a36Sopenharmony_ciout:
97362306a36Sopenharmony_ci	mutex_unlock(&wbuf->io_mutex);
97462306a36Sopenharmony_ci	return err;
97562306a36Sopenharmony_ci}
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci/**
97862306a36Sopenharmony_ci * ubifs_destroy_idx_gc - destroy idx_gc list.
97962306a36Sopenharmony_ci * @c: UBIFS file-system description object
98062306a36Sopenharmony_ci *
98162306a36Sopenharmony_ci * This function destroys the @c->idx_gc list. It is called when unmounting
98262306a36Sopenharmony_ci * so locks are not needed. Returns zero in case of success and a negative
98362306a36Sopenharmony_ci * error code in case of failure.
98462306a36Sopenharmony_ci */
98562306a36Sopenharmony_civoid ubifs_destroy_idx_gc(struct ubifs_info *c)
98662306a36Sopenharmony_ci{
98762306a36Sopenharmony_ci	while (!list_empty(&c->idx_gc)) {
98862306a36Sopenharmony_ci		struct ubifs_gced_idx_leb *idx_gc;
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci		idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb,
99162306a36Sopenharmony_ci				    list);
99262306a36Sopenharmony_ci		c->idx_gc_cnt -= 1;
99362306a36Sopenharmony_ci		list_del(&idx_gc->list);
99462306a36Sopenharmony_ci		kfree(idx_gc);
99562306a36Sopenharmony_ci	}
99662306a36Sopenharmony_ci}
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci/**
99962306a36Sopenharmony_ci * ubifs_get_idx_gc_leb - get a LEB from GC'd index LEB list.
100062306a36Sopenharmony_ci * @c: UBIFS file-system description object
100162306a36Sopenharmony_ci *
100262306a36Sopenharmony_ci * Called during start commit so locks are not needed.
100362306a36Sopenharmony_ci */
100462306a36Sopenharmony_ciint ubifs_get_idx_gc_leb(struct ubifs_info *c)
100562306a36Sopenharmony_ci{
100662306a36Sopenharmony_ci	struct ubifs_gced_idx_leb *idx_gc;
100762306a36Sopenharmony_ci	int lnum;
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	if (list_empty(&c->idx_gc))
101062306a36Sopenharmony_ci		return -ENOSPC;
101162306a36Sopenharmony_ci	idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb, list);
101262306a36Sopenharmony_ci	lnum = idx_gc->lnum;
101362306a36Sopenharmony_ci	/* c->idx_gc_cnt is updated by the caller when lprops are updated */
101462306a36Sopenharmony_ci	list_del(&idx_gc->list);
101562306a36Sopenharmony_ci	kfree(idx_gc);
101662306a36Sopenharmony_ci	return lnum;
101762306a36Sopenharmony_ci}
1018