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 * Author: Adrian Hunter
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "ubifs.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/*
1362306a36Sopenharmony_ci * An orphan is an inode number whose inode node has been committed to the index
1462306a36Sopenharmony_ci * with a link count of zero. That happens when an open file is deleted
1562306a36Sopenharmony_ci * (unlinked) and then a commit is run. In the normal course of events the inode
1662306a36Sopenharmony_ci * would be deleted when the file is closed. However in the case of an unclean
1762306a36Sopenharmony_ci * unmount, orphans need to be accounted for. After an unclean unmount, the
1862306a36Sopenharmony_ci * orphans' inodes must be deleted which means either scanning the entire index
1962306a36Sopenharmony_ci * looking for them, or keeping a list on flash somewhere. This unit implements
2062306a36Sopenharmony_ci * the latter approach.
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * The orphan area is a fixed number of LEBs situated between the LPT area and
2362306a36Sopenharmony_ci * the main area. The number of orphan area LEBs is specified when the file
2462306a36Sopenharmony_ci * system is created. The minimum number is 1. The size of the orphan area
2562306a36Sopenharmony_ci * should be so that it can hold the maximum number of orphans that are expected
2662306a36Sopenharmony_ci * to ever exist at one time.
2762306a36Sopenharmony_ci *
2862306a36Sopenharmony_ci * The number of orphans that can fit in a LEB is:
2962306a36Sopenharmony_ci *
3062306a36Sopenharmony_ci *         (c->leb_size - UBIFS_ORPH_NODE_SZ) / sizeof(__le64)
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * For example: a 15872 byte LEB can fit 1980 orphans so 1 LEB may be enough.
3362306a36Sopenharmony_ci *
3462306a36Sopenharmony_ci * Orphans are accumulated in a rb-tree. When an inode's link count drops to
3562306a36Sopenharmony_ci * zero, the inode number is added to the rb-tree. It is removed from the tree
3662306a36Sopenharmony_ci * when the inode is deleted.  Any new orphans that are in the orphan tree when
3762306a36Sopenharmony_ci * the commit is run, are written to the orphan area in 1 or more orphan nodes.
3862306a36Sopenharmony_ci * If the orphan area is full, it is consolidated to make space.  There is
3962306a36Sopenharmony_ci * always enough space because validation prevents the user from creating more
4062306a36Sopenharmony_ci * than the maximum number of orphans allowed.
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic int dbg_check_orphans(struct ubifs_info *c);
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum,
4662306a36Sopenharmony_ci				       struct ubifs_orphan *parent_orphan)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	struct ubifs_orphan *orphan, *o;
4962306a36Sopenharmony_ci	struct rb_node **p, *parent = NULL;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_NOFS);
5262306a36Sopenharmony_ci	if (!orphan)
5362306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
5462306a36Sopenharmony_ci	orphan->inum = inum;
5562306a36Sopenharmony_ci	orphan->new = 1;
5662306a36Sopenharmony_ci	INIT_LIST_HEAD(&orphan->child_list);
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	spin_lock(&c->orphan_lock);
5962306a36Sopenharmony_ci	if (c->tot_orphans >= c->max_orphans) {
6062306a36Sopenharmony_ci		spin_unlock(&c->orphan_lock);
6162306a36Sopenharmony_ci		kfree(orphan);
6262306a36Sopenharmony_ci		return ERR_PTR(-ENFILE);
6362306a36Sopenharmony_ci	}
6462306a36Sopenharmony_ci	p = &c->orph_tree.rb_node;
6562306a36Sopenharmony_ci	while (*p) {
6662306a36Sopenharmony_ci		parent = *p;
6762306a36Sopenharmony_ci		o = rb_entry(parent, struct ubifs_orphan, rb);
6862306a36Sopenharmony_ci		if (inum < o->inum)
6962306a36Sopenharmony_ci			p = &(*p)->rb_left;
7062306a36Sopenharmony_ci		else if (inum > o->inum)
7162306a36Sopenharmony_ci			p = &(*p)->rb_right;
7262306a36Sopenharmony_ci		else {
7362306a36Sopenharmony_ci			ubifs_err(c, "orphaned twice");
7462306a36Sopenharmony_ci			spin_unlock(&c->orphan_lock);
7562306a36Sopenharmony_ci			kfree(orphan);
7662306a36Sopenharmony_ci			return ERR_PTR(-EINVAL);
7762306a36Sopenharmony_ci		}
7862306a36Sopenharmony_ci	}
7962306a36Sopenharmony_ci	c->tot_orphans += 1;
8062306a36Sopenharmony_ci	c->new_orphans += 1;
8162306a36Sopenharmony_ci	rb_link_node(&orphan->rb, parent, p);
8262306a36Sopenharmony_ci	rb_insert_color(&orphan->rb, &c->orph_tree);
8362306a36Sopenharmony_ci	list_add_tail(&orphan->list, &c->orph_list);
8462306a36Sopenharmony_ci	list_add_tail(&orphan->new_list, &c->orph_new);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	if (parent_orphan) {
8762306a36Sopenharmony_ci		list_add_tail(&orphan->child_list,
8862306a36Sopenharmony_ci			      &parent_orphan->child_list);
8962306a36Sopenharmony_ci	}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	spin_unlock(&c->orphan_lock);
9262306a36Sopenharmony_ci	dbg_gen("ino %lu", (unsigned long)inum);
9362306a36Sopenharmony_ci	return orphan;
9462306a36Sopenharmony_ci}
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cistatic struct ubifs_orphan *lookup_orphan(struct ubifs_info *c, ino_t inum)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	struct ubifs_orphan *o;
9962306a36Sopenharmony_ci	struct rb_node *p;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	p = c->orph_tree.rb_node;
10262306a36Sopenharmony_ci	while (p) {
10362306a36Sopenharmony_ci		o = rb_entry(p, struct ubifs_orphan, rb);
10462306a36Sopenharmony_ci		if (inum < o->inum)
10562306a36Sopenharmony_ci			p = p->rb_left;
10662306a36Sopenharmony_ci		else if (inum > o->inum)
10762306a36Sopenharmony_ci			p = p->rb_right;
10862306a36Sopenharmony_ci		else {
10962306a36Sopenharmony_ci			return o;
11062306a36Sopenharmony_ci		}
11162306a36Sopenharmony_ci	}
11262306a36Sopenharmony_ci	return NULL;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistatic void __orphan_drop(struct ubifs_info *c, struct ubifs_orphan *o)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	rb_erase(&o->rb, &c->orph_tree);
11862306a36Sopenharmony_ci	list_del(&o->list);
11962306a36Sopenharmony_ci	c->tot_orphans -= 1;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	if (o->new) {
12262306a36Sopenharmony_ci		list_del(&o->new_list);
12362306a36Sopenharmony_ci		c->new_orphans -= 1;
12462306a36Sopenharmony_ci	}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	kfree(o);
12762306a36Sopenharmony_ci}
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistatic void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph)
13062306a36Sopenharmony_ci{
13162306a36Sopenharmony_ci	if (orph->del) {
13262306a36Sopenharmony_ci		dbg_gen("deleted twice ino %lu", (unsigned long)orph->inum);
13362306a36Sopenharmony_ci		return;
13462306a36Sopenharmony_ci	}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	if (orph->cmt) {
13762306a36Sopenharmony_ci		orph->del = 1;
13862306a36Sopenharmony_ci		orph->dnext = c->orph_dnext;
13962306a36Sopenharmony_ci		c->orph_dnext = orph;
14062306a36Sopenharmony_ci		dbg_gen("delete later ino %lu", (unsigned long)orph->inum);
14162306a36Sopenharmony_ci		return;
14262306a36Sopenharmony_ci	}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	__orphan_drop(c, orph);
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci/**
14862306a36Sopenharmony_ci * ubifs_add_orphan - add an orphan.
14962306a36Sopenharmony_ci * @c: UBIFS file-system description object
15062306a36Sopenharmony_ci * @inum: orphan inode number
15162306a36Sopenharmony_ci *
15262306a36Sopenharmony_ci * Add an orphan. This function is called when an inodes link count drops to
15362306a36Sopenharmony_ci * zero.
15462306a36Sopenharmony_ci */
15562306a36Sopenharmony_ciint ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
15662306a36Sopenharmony_ci{
15762306a36Sopenharmony_ci	int err = 0;
15862306a36Sopenharmony_ci	ino_t xattr_inum;
15962306a36Sopenharmony_ci	union ubifs_key key;
16062306a36Sopenharmony_ci	struct ubifs_dent_node *xent, *pxent = NULL;
16162306a36Sopenharmony_ci	struct fscrypt_name nm = {0};
16262306a36Sopenharmony_ci	struct ubifs_orphan *xattr_orphan;
16362306a36Sopenharmony_ci	struct ubifs_orphan *orphan;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	orphan = orphan_add(c, inum, NULL);
16662306a36Sopenharmony_ci	if (IS_ERR(orphan))
16762306a36Sopenharmony_ci		return PTR_ERR(orphan);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	lowest_xent_key(c, &key, inum);
17062306a36Sopenharmony_ci	while (1) {
17162306a36Sopenharmony_ci		xent = ubifs_tnc_next_ent(c, &key, &nm);
17262306a36Sopenharmony_ci		if (IS_ERR(xent)) {
17362306a36Sopenharmony_ci			err = PTR_ERR(xent);
17462306a36Sopenharmony_ci			if (err == -ENOENT)
17562306a36Sopenharmony_ci				break;
17662306a36Sopenharmony_ci			kfree(pxent);
17762306a36Sopenharmony_ci			return err;
17862306a36Sopenharmony_ci		}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci		fname_name(&nm) = xent->name;
18162306a36Sopenharmony_ci		fname_len(&nm) = le16_to_cpu(xent->nlen);
18262306a36Sopenharmony_ci		xattr_inum = le64_to_cpu(xent->inum);
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci		xattr_orphan = orphan_add(c, xattr_inum, orphan);
18562306a36Sopenharmony_ci		if (IS_ERR(xattr_orphan)) {
18662306a36Sopenharmony_ci			kfree(pxent);
18762306a36Sopenharmony_ci			kfree(xent);
18862306a36Sopenharmony_ci			return PTR_ERR(xattr_orphan);
18962306a36Sopenharmony_ci		}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci		kfree(pxent);
19262306a36Sopenharmony_ci		pxent = xent;
19362306a36Sopenharmony_ci		key_read(c, &xent->key, &key);
19462306a36Sopenharmony_ci	}
19562306a36Sopenharmony_ci	kfree(pxent);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	return 0;
19862306a36Sopenharmony_ci}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci/**
20162306a36Sopenharmony_ci * ubifs_delete_orphan - delete an orphan.
20262306a36Sopenharmony_ci * @c: UBIFS file-system description object
20362306a36Sopenharmony_ci * @inum: orphan inode number
20462306a36Sopenharmony_ci *
20562306a36Sopenharmony_ci * Delete an orphan. This function is called when an inode is deleted.
20662306a36Sopenharmony_ci */
20762306a36Sopenharmony_civoid ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	struct ubifs_orphan *orph, *child_orph, *tmp_o;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	spin_lock(&c->orphan_lock);
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	orph = lookup_orphan(c, inum);
21462306a36Sopenharmony_ci	if (!orph) {
21562306a36Sopenharmony_ci		spin_unlock(&c->orphan_lock);
21662306a36Sopenharmony_ci		ubifs_err(c, "missing orphan ino %lu", (unsigned long)inum);
21762306a36Sopenharmony_ci		dump_stack();
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci		return;
22062306a36Sopenharmony_ci	}
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	list_for_each_entry_safe(child_orph, tmp_o, &orph->child_list, child_list) {
22362306a36Sopenharmony_ci		list_del(&child_orph->child_list);
22462306a36Sopenharmony_ci		orphan_delete(c, child_orph);
22562306a36Sopenharmony_ci	}
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	orphan_delete(c, orph);
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	spin_unlock(&c->orphan_lock);
23062306a36Sopenharmony_ci}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci/**
23362306a36Sopenharmony_ci * ubifs_orphan_start_commit - start commit of orphans.
23462306a36Sopenharmony_ci * @c: UBIFS file-system description object
23562306a36Sopenharmony_ci *
23662306a36Sopenharmony_ci * Start commit of orphans.
23762306a36Sopenharmony_ci */
23862306a36Sopenharmony_ciint ubifs_orphan_start_commit(struct ubifs_info *c)
23962306a36Sopenharmony_ci{
24062306a36Sopenharmony_ci	struct ubifs_orphan *orphan, **last;
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	spin_lock(&c->orphan_lock);
24362306a36Sopenharmony_ci	last = &c->orph_cnext;
24462306a36Sopenharmony_ci	list_for_each_entry(orphan, &c->orph_new, new_list) {
24562306a36Sopenharmony_ci		ubifs_assert(c, orphan->new);
24662306a36Sopenharmony_ci		ubifs_assert(c, !orphan->cmt);
24762306a36Sopenharmony_ci		orphan->new = 0;
24862306a36Sopenharmony_ci		orphan->cmt = 1;
24962306a36Sopenharmony_ci		*last = orphan;
25062306a36Sopenharmony_ci		last = &orphan->cnext;
25162306a36Sopenharmony_ci	}
25262306a36Sopenharmony_ci	*last = NULL;
25362306a36Sopenharmony_ci	c->cmt_orphans = c->new_orphans;
25462306a36Sopenharmony_ci	c->new_orphans = 0;
25562306a36Sopenharmony_ci	dbg_cmt("%d orphans to commit", c->cmt_orphans);
25662306a36Sopenharmony_ci	INIT_LIST_HEAD(&c->orph_new);
25762306a36Sopenharmony_ci	if (c->tot_orphans == 0)
25862306a36Sopenharmony_ci		c->no_orphs = 1;
25962306a36Sopenharmony_ci	else
26062306a36Sopenharmony_ci		c->no_orphs = 0;
26162306a36Sopenharmony_ci	spin_unlock(&c->orphan_lock);
26262306a36Sopenharmony_ci	return 0;
26362306a36Sopenharmony_ci}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci/**
26662306a36Sopenharmony_ci * avail_orphs - calculate available space.
26762306a36Sopenharmony_ci * @c: UBIFS file-system description object
26862306a36Sopenharmony_ci *
26962306a36Sopenharmony_ci * This function returns the number of orphans that can be written in the
27062306a36Sopenharmony_ci * available space.
27162306a36Sopenharmony_ci */
27262306a36Sopenharmony_cistatic int avail_orphs(struct ubifs_info *c)
27362306a36Sopenharmony_ci{
27462306a36Sopenharmony_ci	int avail_lebs, avail, gap;
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	avail_lebs = c->orph_lebs - (c->ohead_lnum - c->orph_first) - 1;
27762306a36Sopenharmony_ci	avail = avail_lebs *
27862306a36Sopenharmony_ci	       ((c->leb_size - UBIFS_ORPH_NODE_SZ) / sizeof(__le64));
27962306a36Sopenharmony_ci	gap = c->leb_size - c->ohead_offs;
28062306a36Sopenharmony_ci	if (gap >= UBIFS_ORPH_NODE_SZ + sizeof(__le64))
28162306a36Sopenharmony_ci		avail += (gap - UBIFS_ORPH_NODE_SZ) / sizeof(__le64);
28262306a36Sopenharmony_ci	return avail;
28362306a36Sopenharmony_ci}
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci/**
28662306a36Sopenharmony_ci * tot_avail_orphs - calculate total space.
28762306a36Sopenharmony_ci * @c: UBIFS file-system description object
28862306a36Sopenharmony_ci *
28962306a36Sopenharmony_ci * This function returns the number of orphans that can be written in half
29062306a36Sopenharmony_ci * the total space. That leaves half the space for adding new orphans.
29162306a36Sopenharmony_ci */
29262306a36Sopenharmony_cistatic int tot_avail_orphs(struct ubifs_info *c)
29362306a36Sopenharmony_ci{
29462306a36Sopenharmony_ci	int avail_lebs, avail;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	avail_lebs = c->orph_lebs;
29762306a36Sopenharmony_ci	avail = avail_lebs *
29862306a36Sopenharmony_ci	       ((c->leb_size - UBIFS_ORPH_NODE_SZ) / sizeof(__le64));
29962306a36Sopenharmony_ci	return avail / 2;
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/**
30362306a36Sopenharmony_ci * do_write_orph_node - write a node to the orphan head.
30462306a36Sopenharmony_ci * @c: UBIFS file-system description object
30562306a36Sopenharmony_ci * @len: length of node
30662306a36Sopenharmony_ci * @atomic: write atomically
30762306a36Sopenharmony_ci *
30862306a36Sopenharmony_ci * This function writes a node to the orphan head from the orphan buffer. If
30962306a36Sopenharmony_ci * %atomic is not zero, then the write is done atomically. On success, %0 is
31062306a36Sopenharmony_ci * returned, otherwise a negative error code is returned.
31162306a36Sopenharmony_ci */
31262306a36Sopenharmony_cistatic int do_write_orph_node(struct ubifs_info *c, int len, int atomic)
31362306a36Sopenharmony_ci{
31462306a36Sopenharmony_ci	int err = 0;
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	if (atomic) {
31762306a36Sopenharmony_ci		ubifs_assert(c, c->ohead_offs == 0);
31862306a36Sopenharmony_ci		ubifs_prepare_node(c, c->orph_buf, len, 1);
31962306a36Sopenharmony_ci		len = ALIGN(len, c->min_io_size);
32062306a36Sopenharmony_ci		err = ubifs_leb_change(c, c->ohead_lnum, c->orph_buf, len);
32162306a36Sopenharmony_ci	} else {
32262306a36Sopenharmony_ci		if (c->ohead_offs == 0) {
32362306a36Sopenharmony_ci			/* Ensure LEB has been unmapped */
32462306a36Sopenharmony_ci			err = ubifs_leb_unmap(c, c->ohead_lnum);
32562306a36Sopenharmony_ci			if (err)
32662306a36Sopenharmony_ci				return err;
32762306a36Sopenharmony_ci		}
32862306a36Sopenharmony_ci		err = ubifs_write_node(c, c->orph_buf, len, c->ohead_lnum,
32962306a36Sopenharmony_ci				       c->ohead_offs);
33062306a36Sopenharmony_ci	}
33162306a36Sopenharmony_ci	return err;
33262306a36Sopenharmony_ci}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci/**
33562306a36Sopenharmony_ci * write_orph_node - write an orphan node.
33662306a36Sopenharmony_ci * @c: UBIFS file-system description object
33762306a36Sopenharmony_ci * @atomic: write atomically
33862306a36Sopenharmony_ci *
33962306a36Sopenharmony_ci * This function builds an orphan node from the cnext list and writes it to the
34062306a36Sopenharmony_ci * orphan head. On success, %0 is returned, otherwise a negative error code
34162306a36Sopenharmony_ci * is returned.
34262306a36Sopenharmony_ci */
34362306a36Sopenharmony_cistatic int write_orph_node(struct ubifs_info *c, int atomic)
34462306a36Sopenharmony_ci{
34562306a36Sopenharmony_ci	struct ubifs_orphan *orphan, *cnext;
34662306a36Sopenharmony_ci	struct ubifs_orph_node *orph;
34762306a36Sopenharmony_ci	int gap, err, len, cnt, i;
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	ubifs_assert(c, c->cmt_orphans > 0);
35062306a36Sopenharmony_ci	gap = c->leb_size - c->ohead_offs;
35162306a36Sopenharmony_ci	if (gap < UBIFS_ORPH_NODE_SZ + sizeof(__le64)) {
35262306a36Sopenharmony_ci		c->ohead_lnum += 1;
35362306a36Sopenharmony_ci		c->ohead_offs = 0;
35462306a36Sopenharmony_ci		gap = c->leb_size;
35562306a36Sopenharmony_ci		if (c->ohead_lnum > c->orph_last) {
35662306a36Sopenharmony_ci			/*
35762306a36Sopenharmony_ci			 * We limit the number of orphans so that this should
35862306a36Sopenharmony_ci			 * never happen.
35962306a36Sopenharmony_ci			 */
36062306a36Sopenharmony_ci			ubifs_err(c, "out of space in orphan area");
36162306a36Sopenharmony_ci			return -EINVAL;
36262306a36Sopenharmony_ci		}
36362306a36Sopenharmony_ci	}
36462306a36Sopenharmony_ci	cnt = (gap - UBIFS_ORPH_NODE_SZ) / sizeof(__le64);
36562306a36Sopenharmony_ci	if (cnt > c->cmt_orphans)
36662306a36Sopenharmony_ci		cnt = c->cmt_orphans;
36762306a36Sopenharmony_ci	len = UBIFS_ORPH_NODE_SZ + cnt * sizeof(__le64);
36862306a36Sopenharmony_ci	ubifs_assert(c, c->orph_buf);
36962306a36Sopenharmony_ci	orph = c->orph_buf;
37062306a36Sopenharmony_ci	orph->ch.node_type = UBIFS_ORPH_NODE;
37162306a36Sopenharmony_ci	spin_lock(&c->orphan_lock);
37262306a36Sopenharmony_ci	cnext = c->orph_cnext;
37362306a36Sopenharmony_ci	for (i = 0; i < cnt; i++) {
37462306a36Sopenharmony_ci		orphan = cnext;
37562306a36Sopenharmony_ci		ubifs_assert(c, orphan->cmt);
37662306a36Sopenharmony_ci		orph->inos[i] = cpu_to_le64(orphan->inum);
37762306a36Sopenharmony_ci		orphan->cmt = 0;
37862306a36Sopenharmony_ci		cnext = orphan->cnext;
37962306a36Sopenharmony_ci		orphan->cnext = NULL;
38062306a36Sopenharmony_ci	}
38162306a36Sopenharmony_ci	c->orph_cnext = cnext;
38262306a36Sopenharmony_ci	c->cmt_orphans -= cnt;
38362306a36Sopenharmony_ci	spin_unlock(&c->orphan_lock);
38462306a36Sopenharmony_ci	if (c->cmt_orphans)
38562306a36Sopenharmony_ci		orph->cmt_no = cpu_to_le64(c->cmt_no);
38662306a36Sopenharmony_ci	else
38762306a36Sopenharmony_ci		/* Mark the last node of the commit */
38862306a36Sopenharmony_ci		orph->cmt_no = cpu_to_le64((c->cmt_no) | (1ULL << 63));
38962306a36Sopenharmony_ci	ubifs_assert(c, c->ohead_offs + len <= c->leb_size);
39062306a36Sopenharmony_ci	ubifs_assert(c, c->ohead_lnum >= c->orph_first);
39162306a36Sopenharmony_ci	ubifs_assert(c, c->ohead_lnum <= c->orph_last);
39262306a36Sopenharmony_ci	err = do_write_orph_node(c, len, atomic);
39362306a36Sopenharmony_ci	c->ohead_offs += ALIGN(len, c->min_io_size);
39462306a36Sopenharmony_ci	c->ohead_offs = ALIGN(c->ohead_offs, 8);
39562306a36Sopenharmony_ci	return err;
39662306a36Sopenharmony_ci}
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci/**
39962306a36Sopenharmony_ci * write_orph_nodes - write orphan nodes until there are no more to commit.
40062306a36Sopenharmony_ci * @c: UBIFS file-system description object
40162306a36Sopenharmony_ci * @atomic: write atomically
40262306a36Sopenharmony_ci *
40362306a36Sopenharmony_ci * This function writes orphan nodes for all the orphans to commit. On success,
40462306a36Sopenharmony_ci * %0 is returned, otherwise a negative error code is returned.
40562306a36Sopenharmony_ci */
40662306a36Sopenharmony_cistatic int write_orph_nodes(struct ubifs_info *c, int atomic)
40762306a36Sopenharmony_ci{
40862306a36Sopenharmony_ci	int err;
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci	while (c->cmt_orphans > 0) {
41162306a36Sopenharmony_ci		err = write_orph_node(c, atomic);
41262306a36Sopenharmony_ci		if (err)
41362306a36Sopenharmony_ci			return err;
41462306a36Sopenharmony_ci	}
41562306a36Sopenharmony_ci	if (atomic) {
41662306a36Sopenharmony_ci		int lnum;
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci		/* Unmap any unused LEBs after consolidation */
41962306a36Sopenharmony_ci		for (lnum = c->ohead_lnum + 1; lnum <= c->orph_last; lnum++) {
42062306a36Sopenharmony_ci			err = ubifs_leb_unmap(c, lnum);
42162306a36Sopenharmony_ci			if (err)
42262306a36Sopenharmony_ci				return err;
42362306a36Sopenharmony_ci		}
42462306a36Sopenharmony_ci	}
42562306a36Sopenharmony_ci	return 0;
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci/**
42962306a36Sopenharmony_ci * consolidate - consolidate the orphan area.
43062306a36Sopenharmony_ci * @c: UBIFS file-system description object
43162306a36Sopenharmony_ci *
43262306a36Sopenharmony_ci * This function enables consolidation by putting all the orphans into the list
43362306a36Sopenharmony_ci * to commit. The list is in the order that the orphans were added, and the
43462306a36Sopenharmony_ci * LEBs are written atomically in order, so at no time can orphans be lost by
43562306a36Sopenharmony_ci * an unclean unmount.
43662306a36Sopenharmony_ci *
43762306a36Sopenharmony_ci * This function returns %0 on success and a negative error code on failure.
43862306a36Sopenharmony_ci */
43962306a36Sopenharmony_cistatic int consolidate(struct ubifs_info *c)
44062306a36Sopenharmony_ci{
44162306a36Sopenharmony_ci	int tot_avail = tot_avail_orphs(c), err = 0;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	spin_lock(&c->orphan_lock);
44462306a36Sopenharmony_ci	dbg_cmt("there is space for %d orphans and there are %d",
44562306a36Sopenharmony_ci		tot_avail, c->tot_orphans);
44662306a36Sopenharmony_ci	if (c->tot_orphans - c->new_orphans <= tot_avail) {
44762306a36Sopenharmony_ci		struct ubifs_orphan *orphan, **last;
44862306a36Sopenharmony_ci		int cnt = 0;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci		/* Change the cnext list to include all non-new orphans */
45162306a36Sopenharmony_ci		last = &c->orph_cnext;
45262306a36Sopenharmony_ci		list_for_each_entry(orphan, &c->orph_list, list) {
45362306a36Sopenharmony_ci			if (orphan->new)
45462306a36Sopenharmony_ci				continue;
45562306a36Sopenharmony_ci			orphan->cmt = 1;
45662306a36Sopenharmony_ci			*last = orphan;
45762306a36Sopenharmony_ci			last = &orphan->cnext;
45862306a36Sopenharmony_ci			cnt += 1;
45962306a36Sopenharmony_ci		}
46062306a36Sopenharmony_ci		*last = NULL;
46162306a36Sopenharmony_ci		ubifs_assert(c, cnt == c->tot_orphans - c->new_orphans);
46262306a36Sopenharmony_ci		c->cmt_orphans = cnt;
46362306a36Sopenharmony_ci		c->ohead_lnum = c->orph_first;
46462306a36Sopenharmony_ci		c->ohead_offs = 0;
46562306a36Sopenharmony_ci	} else {
46662306a36Sopenharmony_ci		/*
46762306a36Sopenharmony_ci		 * We limit the number of orphans so that this should
46862306a36Sopenharmony_ci		 * never happen.
46962306a36Sopenharmony_ci		 */
47062306a36Sopenharmony_ci		ubifs_err(c, "out of space in orphan area");
47162306a36Sopenharmony_ci		err = -EINVAL;
47262306a36Sopenharmony_ci	}
47362306a36Sopenharmony_ci	spin_unlock(&c->orphan_lock);
47462306a36Sopenharmony_ci	return err;
47562306a36Sopenharmony_ci}
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci/**
47862306a36Sopenharmony_ci * commit_orphans - commit orphans.
47962306a36Sopenharmony_ci * @c: UBIFS file-system description object
48062306a36Sopenharmony_ci *
48162306a36Sopenharmony_ci * This function commits orphans to flash. On success, %0 is returned,
48262306a36Sopenharmony_ci * otherwise a negative error code is returned.
48362306a36Sopenharmony_ci */
48462306a36Sopenharmony_cistatic int commit_orphans(struct ubifs_info *c)
48562306a36Sopenharmony_ci{
48662306a36Sopenharmony_ci	int avail, atomic = 0, err;
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci	ubifs_assert(c, c->cmt_orphans > 0);
48962306a36Sopenharmony_ci	avail = avail_orphs(c);
49062306a36Sopenharmony_ci	if (avail < c->cmt_orphans) {
49162306a36Sopenharmony_ci		/* Not enough space to write new orphans, so consolidate */
49262306a36Sopenharmony_ci		err = consolidate(c);
49362306a36Sopenharmony_ci		if (err)
49462306a36Sopenharmony_ci			return err;
49562306a36Sopenharmony_ci		atomic = 1;
49662306a36Sopenharmony_ci	}
49762306a36Sopenharmony_ci	err = write_orph_nodes(c, atomic);
49862306a36Sopenharmony_ci	return err;
49962306a36Sopenharmony_ci}
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci/**
50262306a36Sopenharmony_ci * erase_deleted - erase the orphans marked for deletion.
50362306a36Sopenharmony_ci * @c: UBIFS file-system description object
50462306a36Sopenharmony_ci *
50562306a36Sopenharmony_ci * During commit, the orphans being committed cannot be deleted, so they are
50662306a36Sopenharmony_ci * marked for deletion and deleted by this function. Also, the recovery
50762306a36Sopenharmony_ci * adds killed orphans to the deletion list, and therefore they are deleted
50862306a36Sopenharmony_ci * here too.
50962306a36Sopenharmony_ci */
51062306a36Sopenharmony_cistatic void erase_deleted(struct ubifs_info *c)
51162306a36Sopenharmony_ci{
51262306a36Sopenharmony_ci	struct ubifs_orphan *orphan, *dnext;
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	spin_lock(&c->orphan_lock);
51562306a36Sopenharmony_ci	dnext = c->orph_dnext;
51662306a36Sopenharmony_ci	while (dnext) {
51762306a36Sopenharmony_ci		orphan = dnext;
51862306a36Sopenharmony_ci		dnext = orphan->dnext;
51962306a36Sopenharmony_ci		ubifs_assert(c, !orphan->new);
52062306a36Sopenharmony_ci		ubifs_assert(c, orphan->del);
52162306a36Sopenharmony_ci		rb_erase(&orphan->rb, &c->orph_tree);
52262306a36Sopenharmony_ci		list_del(&orphan->list);
52362306a36Sopenharmony_ci		c->tot_orphans -= 1;
52462306a36Sopenharmony_ci		dbg_gen("deleting orphan ino %lu", (unsigned long)orphan->inum);
52562306a36Sopenharmony_ci		kfree(orphan);
52662306a36Sopenharmony_ci	}
52762306a36Sopenharmony_ci	c->orph_dnext = NULL;
52862306a36Sopenharmony_ci	spin_unlock(&c->orphan_lock);
52962306a36Sopenharmony_ci}
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci/**
53262306a36Sopenharmony_ci * ubifs_orphan_end_commit - end commit of orphans.
53362306a36Sopenharmony_ci * @c: UBIFS file-system description object
53462306a36Sopenharmony_ci *
53562306a36Sopenharmony_ci * End commit of orphans.
53662306a36Sopenharmony_ci */
53762306a36Sopenharmony_ciint ubifs_orphan_end_commit(struct ubifs_info *c)
53862306a36Sopenharmony_ci{
53962306a36Sopenharmony_ci	int err;
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	if (c->cmt_orphans != 0) {
54262306a36Sopenharmony_ci		err = commit_orphans(c);
54362306a36Sopenharmony_ci		if (err)
54462306a36Sopenharmony_ci			return err;
54562306a36Sopenharmony_ci	}
54662306a36Sopenharmony_ci	erase_deleted(c);
54762306a36Sopenharmony_ci	err = dbg_check_orphans(c);
54862306a36Sopenharmony_ci	return err;
54962306a36Sopenharmony_ci}
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci/**
55262306a36Sopenharmony_ci * ubifs_clear_orphans - erase all LEBs used for orphans.
55362306a36Sopenharmony_ci * @c: UBIFS file-system description object
55462306a36Sopenharmony_ci *
55562306a36Sopenharmony_ci * If recovery is not required, then the orphans from the previous session
55662306a36Sopenharmony_ci * are not needed. This function locates the LEBs used to record
55762306a36Sopenharmony_ci * orphans, and un-maps them.
55862306a36Sopenharmony_ci */
55962306a36Sopenharmony_ciint ubifs_clear_orphans(struct ubifs_info *c)
56062306a36Sopenharmony_ci{
56162306a36Sopenharmony_ci	int lnum, err;
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci	for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) {
56462306a36Sopenharmony_ci		err = ubifs_leb_unmap(c, lnum);
56562306a36Sopenharmony_ci		if (err)
56662306a36Sopenharmony_ci			return err;
56762306a36Sopenharmony_ci	}
56862306a36Sopenharmony_ci	c->ohead_lnum = c->orph_first;
56962306a36Sopenharmony_ci	c->ohead_offs = 0;
57062306a36Sopenharmony_ci	return 0;
57162306a36Sopenharmony_ci}
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci/**
57462306a36Sopenharmony_ci * insert_dead_orphan - insert an orphan.
57562306a36Sopenharmony_ci * @c: UBIFS file-system description object
57662306a36Sopenharmony_ci * @inum: orphan inode number
57762306a36Sopenharmony_ci *
57862306a36Sopenharmony_ci * This function is a helper to the 'do_kill_orphans()' function. The orphan
57962306a36Sopenharmony_ci * must be kept until the next commit, so it is added to the rb-tree and the
58062306a36Sopenharmony_ci * deletion list.
58162306a36Sopenharmony_ci */
58262306a36Sopenharmony_cistatic int insert_dead_orphan(struct ubifs_info *c, ino_t inum)
58362306a36Sopenharmony_ci{
58462306a36Sopenharmony_ci	struct ubifs_orphan *orphan, *o;
58562306a36Sopenharmony_ci	struct rb_node **p, *parent = NULL;
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci	orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_KERNEL);
58862306a36Sopenharmony_ci	if (!orphan)
58962306a36Sopenharmony_ci		return -ENOMEM;
59062306a36Sopenharmony_ci	orphan->inum = inum;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	p = &c->orph_tree.rb_node;
59362306a36Sopenharmony_ci	while (*p) {
59462306a36Sopenharmony_ci		parent = *p;
59562306a36Sopenharmony_ci		o = rb_entry(parent, struct ubifs_orphan, rb);
59662306a36Sopenharmony_ci		if (inum < o->inum)
59762306a36Sopenharmony_ci			p = &(*p)->rb_left;
59862306a36Sopenharmony_ci		else if (inum > o->inum)
59962306a36Sopenharmony_ci			p = &(*p)->rb_right;
60062306a36Sopenharmony_ci		else {
60162306a36Sopenharmony_ci			/* Already added - no problem */
60262306a36Sopenharmony_ci			kfree(orphan);
60362306a36Sopenharmony_ci			return 0;
60462306a36Sopenharmony_ci		}
60562306a36Sopenharmony_ci	}
60662306a36Sopenharmony_ci	c->tot_orphans += 1;
60762306a36Sopenharmony_ci	rb_link_node(&orphan->rb, parent, p);
60862306a36Sopenharmony_ci	rb_insert_color(&orphan->rb, &c->orph_tree);
60962306a36Sopenharmony_ci	list_add_tail(&orphan->list, &c->orph_list);
61062306a36Sopenharmony_ci	orphan->del = 1;
61162306a36Sopenharmony_ci	orphan->dnext = c->orph_dnext;
61262306a36Sopenharmony_ci	c->orph_dnext = orphan;
61362306a36Sopenharmony_ci	dbg_mnt("ino %lu, new %d, tot %d", (unsigned long)inum,
61462306a36Sopenharmony_ci		c->new_orphans, c->tot_orphans);
61562306a36Sopenharmony_ci	return 0;
61662306a36Sopenharmony_ci}
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci/**
61962306a36Sopenharmony_ci * do_kill_orphans - remove orphan inodes from the index.
62062306a36Sopenharmony_ci * @c: UBIFS file-system description object
62162306a36Sopenharmony_ci * @sleb: scanned LEB
62262306a36Sopenharmony_ci * @last_cmt_no: cmt_no of last orphan node read is passed and returned here
62362306a36Sopenharmony_ci * @outofdate: whether the LEB is out of date is returned here
62462306a36Sopenharmony_ci * @last_flagged: whether the end orphan node is encountered
62562306a36Sopenharmony_ci *
62662306a36Sopenharmony_ci * This function is a helper to the 'kill_orphans()' function. It goes through
62762306a36Sopenharmony_ci * every orphan node in a LEB and for every inode number recorded, removes
62862306a36Sopenharmony_ci * all keys for that inode from the TNC.
62962306a36Sopenharmony_ci */
63062306a36Sopenharmony_cistatic int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
63162306a36Sopenharmony_ci			   unsigned long long *last_cmt_no, int *outofdate,
63262306a36Sopenharmony_ci			   int *last_flagged)
63362306a36Sopenharmony_ci{
63462306a36Sopenharmony_ci	struct ubifs_scan_node *snod;
63562306a36Sopenharmony_ci	struct ubifs_orph_node *orph;
63662306a36Sopenharmony_ci	struct ubifs_ino_node *ino = NULL;
63762306a36Sopenharmony_ci	unsigned long long cmt_no;
63862306a36Sopenharmony_ci	ino_t inum;
63962306a36Sopenharmony_ci	int i, n, err, first = 1;
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	ino = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS);
64262306a36Sopenharmony_ci	if (!ino)
64362306a36Sopenharmony_ci		return -ENOMEM;
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci	list_for_each_entry(snod, &sleb->nodes, list) {
64662306a36Sopenharmony_ci		if (snod->type != UBIFS_ORPH_NODE) {
64762306a36Sopenharmony_ci			ubifs_err(c, "invalid node type %d in orphan area at %d:%d",
64862306a36Sopenharmony_ci				  snod->type, sleb->lnum, snod->offs);
64962306a36Sopenharmony_ci			ubifs_dump_node(c, snod->node,
65062306a36Sopenharmony_ci					c->leb_size - snod->offs);
65162306a36Sopenharmony_ci			err = -EINVAL;
65262306a36Sopenharmony_ci			goto out_free;
65362306a36Sopenharmony_ci		}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci		orph = snod->node;
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci		/* Check commit number */
65862306a36Sopenharmony_ci		cmt_no = le64_to_cpu(orph->cmt_no) & LLONG_MAX;
65962306a36Sopenharmony_ci		/*
66062306a36Sopenharmony_ci		 * The commit number on the master node may be less, because
66162306a36Sopenharmony_ci		 * of a failed commit. If there are several failed commits in a
66262306a36Sopenharmony_ci		 * row, the commit number written on orphan nodes will continue
66362306a36Sopenharmony_ci		 * to increase (because the commit number is adjusted here) even
66462306a36Sopenharmony_ci		 * though the commit number on the master node stays the same
66562306a36Sopenharmony_ci		 * because the master node has not been re-written.
66662306a36Sopenharmony_ci		 */
66762306a36Sopenharmony_ci		if (cmt_no > c->cmt_no)
66862306a36Sopenharmony_ci			c->cmt_no = cmt_no;
66962306a36Sopenharmony_ci		if (cmt_no < *last_cmt_no && *last_flagged) {
67062306a36Sopenharmony_ci			/*
67162306a36Sopenharmony_ci			 * The last orphan node had a higher commit number and
67262306a36Sopenharmony_ci			 * was flagged as the last written for that commit
67362306a36Sopenharmony_ci			 * number. That makes this orphan node, out of date.
67462306a36Sopenharmony_ci			 */
67562306a36Sopenharmony_ci			if (!first) {
67662306a36Sopenharmony_ci				ubifs_err(c, "out of order commit number %llu in orphan node at %d:%d",
67762306a36Sopenharmony_ci					  cmt_no, sleb->lnum, snod->offs);
67862306a36Sopenharmony_ci				ubifs_dump_node(c, snod->node,
67962306a36Sopenharmony_ci						c->leb_size - snod->offs);
68062306a36Sopenharmony_ci				err = -EINVAL;
68162306a36Sopenharmony_ci				goto out_free;
68262306a36Sopenharmony_ci			}
68362306a36Sopenharmony_ci			dbg_rcvry("out of date LEB %d", sleb->lnum);
68462306a36Sopenharmony_ci			*outofdate = 1;
68562306a36Sopenharmony_ci			err = 0;
68662306a36Sopenharmony_ci			goto out_free;
68762306a36Sopenharmony_ci		}
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ci		if (first)
69062306a36Sopenharmony_ci			first = 0;
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci		n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3;
69362306a36Sopenharmony_ci		for (i = 0; i < n; i++) {
69462306a36Sopenharmony_ci			union ubifs_key key1, key2;
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci			inum = le64_to_cpu(orph->inos[i]);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci			ino_key_init(c, &key1, inum);
69962306a36Sopenharmony_ci			err = ubifs_tnc_lookup(c, &key1, ino);
70062306a36Sopenharmony_ci			if (err && err != -ENOENT)
70162306a36Sopenharmony_ci				goto out_free;
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci			/*
70462306a36Sopenharmony_ci			 * Check whether an inode can really get deleted.
70562306a36Sopenharmony_ci			 * linkat() with O_TMPFILE allows rebirth of an inode.
70662306a36Sopenharmony_ci			 */
70762306a36Sopenharmony_ci			if (err == 0 && ino->nlink == 0) {
70862306a36Sopenharmony_ci				dbg_rcvry("deleting orphaned inode %lu",
70962306a36Sopenharmony_ci					  (unsigned long)inum);
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci				lowest_ino_key(c, &key1, inum);
71262306a36Sopenharmony_ci				highest_ino_key(c, &key2, inum);
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci				err = ubifs_tnc_remove_range(c, &key1, &key2);
71562306a36Sopenharmony_ci				if (err)
71662306a36Sopenharmony_ci					goto out_ro;
71762306a36Sopenharmony_ci			}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci			err = insert_dead_orphan(c, inum);
72062306a36Sopenharmony_ci			if (err)
72162306a36Sopenharmony_ci				goto out_free;
72262306a36Sopenharmony_ci		}
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci		*last_cmt_no = cmt_no;
72562306a36Sopenharmony_ci		if (le64_to_cpu(orph->cmt_no) & (1ULL << 63)) {
72662306a36Sopenharmony_ci			dbg_rcvry("last orph node for commit %llu at %d:%d",
72762306a36Sopenharmony_ci				  cmt_no, sleb->lnum, snod->offs);
72862306a36Sopenharmony_ci			*last_flagged = 1;
72962306a36Sopenharmony_ci		} else
73062306a36Sopenharmony_ci			*last_flagged = 0;
73162306a36Sopenharmony_ci	}
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	err = 0;
73462306a36Sopenharmony_ciout_free:
73562306a36Sopenharmony_ci	kfree(ino);
73662306a36Sopenharmony_ci	return err;
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ciout_ro:
73962306a36Sopenharmony_ci	ubifs_ro_mode(c, err);
74062306a36Sopenharmony_ci	kfree(ino);
74162306a36Sopenharmony_ci	return err;
74262306a36Sopenharmony_ci}
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_ci/**
74562306a36Sopenharmony_ci * kill_orphans - remove all orphan inodes from the index.
74662306a36Sopenharmony_ci * @c: UBIFS file-system description object
74762306a36Sopenharmony_ci *
74862306a36Sopenharmony_ci * If recovery is required, then orphan inodes recorded during the previous
74962306a36Sopenharmony_ci * session (which ended with an unclean unmount) must be deleted from the index.
75062306a36Sopenharmony_ci * This is done by updating the TNC, but since the index is not updated until
75162306a36Sopenharmony_ci * the next commit, the LEBs where the orphan information is recorded are not
75262306a36Sopenharmony_ci * erased until the next commit.
75362306a36Sopenharmony_ci */
75462306a36Sopenharmony_cistatic int kill_orphans(struct ubifs_info *c)
75562306a36Sopenharmony_ci{
75662306a36Sopenharmony_ci	unsigned long long last_cmt_no = 0;
75762306a36Sopenharmony_ci	int lnum, err = 0, outofdate = 0, last_flagged = 0;
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	c->ohead_lnum = c->orph_first;
76062306a36Sopenharmony_ci	c->ohead_offs = 0;
76162306a36Sopenharmony_ci	/* Check no-orphans flag and skip this if no orphans */
76262306a36Sopenharmony_ci	if (c->no_orphs) {
76362306a36Sopenharmony_ci		dbg_rcvry("no orphans");
76462306a36Sopenharmony_ci		return 0;
76562306a36Sopenharmony_ci	}
76662306a36Sopenharmony_ci	/*
76762306a36Sopenharmony_ci	 * Orph nodes always start at c->orph_first and are written to each
76862306a36Sopenharmony_ci	 * successive LEB in turn. Generally unused LEBs will have been unmapped
76962306a36Sopenharmony_ci	 * but may contain out of date orphan nodes if the unmap didn't go
77062306a36Sopenharmony_ci	 * through. In addition, the last orphan node written for each commit is
77162306a36Sopenharmony_ci	 * marked (top bit of orph->cmt_no is set to 1). It is possible that
77262306a36Sopenharmony_ci	 * there are orphan nodes from the next commit (i.e. the commit did not
77362306a36Sopenharmony_ci	 * complete successfully). In that case, no orphans will have been lost
77462306a36Sopenharmony_ci	 * due to the way that orphans are written, and any orphans added will
77562306a36Sopenharmony_ci	 * be valid orphans anyway and so can be deleted.
77662306a36Sopenharmony_ci	 */
77762306a36Sopenharmony_ci	for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) {
77862306a36Sopenharmony_ci		struct ubifs_scan_leb *sleb;
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci		dbg_rcvry("LEB %d", lnum);
78162306a36Sopenharmony_ci		sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);
78262306a36Sopenharmony_ci		if (IS_ERR(sleb)) {
78362306a36Sopenharmony_ci			if (PTR_ERR(sleb) == -EUCLEAN)
78462306a36Sopenharmony_ci				sleb = ubifs_recover_leb(c, lnum, 0,
78562306a36Sopenharmony_ci							 c->sbuf, -1);
78662306a36Sopenharmony_ci			if (IS_ERR(sleb)) {
78762306a36Sopenharmony_ci				err = PTR_ERR(sleb);
78862306a36Sopenharmony_ci				break;
78962306a36Sopenharmony_ci			}
79062306a36Sopenharmony_ci		}
79162306a36Sopenharmony_ci		err = do_kill_orphans(c, sleb, &last_cmt_no, &outofdate,
79262306a36Sopenharmony_ci				      &last_flagged);
79362306a36Sopenharmony_ci		if (err || outofdate) {
79462306a36Sopenharmony_ci			ubifs_scan_destroy(sleb);
79562306a36Sopenharmony_ci			break;
79662306a36Sopenharmony_ci		}
79762306a36Sopenharmony_ci		if (sleb->endpt) {
79862306a36Sopenharmony_ci			c->ohead_lnum = lnum;
79962306a36Sopenharmony_ci			c->ohead_offs = sleb->endpt;
80062306a36Sopenharmony_ci		}
80162306a36Sopenharmony_ci		ubifs_scan_destroy(sleb);
80262306a36Sopenharmony_ci	}
80362306a36Sopenharmony_ci	return err;
80462306a36Sopenharmony_ci}
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci/**
80762306a36Sopenharmony_ci * ubifs_mount_orphans - delete orphan inodes and erase LEBs that recorded them.
80862306a36Sopenharmony_ci * @c: UBIFS file-system description object
80962306a36Sopenharmony_ci * @unclean: indicates recovery from unclean unmount
81062306a36Sopenharmony_ci * @read_only: indicates read only mount
81162306a36Sopenharmony_ci *
81262306a36Sopenharmony_ci * This function is called when mounting to erase orphans from the previous
81362306a36Sopenharmony_ci * session. If UBIFS was not unmounted cleanly, then the inodes recorded as
81462306a36Sopenharmony_ci * orphans are deleted.
81562306a36Sopenharmony_ci */
81662306a36Sopenharmony_ciint ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only)
81762306a36Sopenharmony_ci{
81862306a36Sopenharmony_ci	int err = 0;
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci	c->max_orphans = tot_avail_orphs(c);
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci	if (!read_only) {
82362306a36Sopenharmony_ci		c->orph_buf = vmalloc(c->leb_size);
82462306a36Sopenharmony_ci		if (!c->orph_buf)
82562306a36Sopenharmony_ci			return -ENOMEM;
82662306a36Sopenharmony_ci	}
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	if (unclean)
82962306a36Sopenharmony_ci		err = kill_orphans(c);
83062306a36Sopenharmony_ci	else if (!read_only)
83162306a36Sopenharmony_ci		err = ubifs_clear_orphans(c);
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci	return err;
83462306a36Sopenharmony_ci}
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci/*
83762306a36Sopenharmony_ci * Everything below is related to debugging.
83862306a36Sopenharmony_ci */
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_cistruct check_orphan {
84162306a36Sopenharmony_ci	struct rb_node rb;
84262306a36Sopenharmony_ci	ino_t inum;
84362306a36Sopenharmony_ci};
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_cistruct check_info {
84662306a36Sopenharmony_ci	unsigned long last_ino;
84762306a36Sopenharmony_ci	unsigned long tot_inos;
84862306a36Sopenharmony_ci	unsigned long missing;
84962306a36Sopenharmony_ci	unsigned long long leaf_cnt;
85062306a36Sopenharmony_ci	struct ubifs_ino_node *node;
85162306a36Sopenharmony_ci	struct rb_root root;
85262306a36Sopenharmony_ci};
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_cistatic bool dbg_find_orphan(struct ubifs_info *c, ino_t inum)
85562306a36Sopenharmony_ci{
85662306a36Sopenharmony_ci	bool found = false;
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	spin_lock(&c->orphan_lock);
85962306a36Sopenharmony_ci	found = !!lookup_orphan(c, inum);
86062306a36Sopenharmony_ci	spin_unlock(&c->orphan_lock);
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci	return found;
86362306a36Sopenharmony_ci}
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_cistatic int dbg_ins_check_orphan(struct rb_root *root, ino_t inum)
86662306a36Sopenharmony_ci{
86762306a36Sopenharmony_ci	struct check_orphan *orphan, *o;
86862306a36Sopenharmony_ci	struct rb_node **p, *parent = NULL;
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_ci	orphan = kzalloc(sizeof(struct check_orphan), GFP_NOFS);
87162306a36Sopenharmony_ci	if (!orphan)
87262306a36Sopenharmony_ci		return -ENOMEM;
87362306a36Sopenharmony_ci	orphan->inum = inum;
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci	p = &root->rb_node;
87662306a36Sopenharmony_ci	while (*p) {
87762306a36Sopenharmony_ci		parent = *p;
87862306a36Sopenharmony_ci		o = rb_entry(parent, struct check_orphan, rb);
87962306a36Sopenharmony_ci		if (inum < o->inum)
88062306a36Sopenharmony_ci			p = &(*p)->rb_left;
88162306a36Sopenharmony_ci		else if (inum > o->inum)
88262306a36Sopenharmony_ci			p = &(*p)->rb_right;
88362306a36Sopenharmony_ci		else {
88462306a36Sopenharmony_ci			kfree(orphan);
88562306a36Sopenharmony_ci			return 0;
88662306a36Sopenharmony_ci		}
88762306a36Sopenharmony_ci	}
88862306a36Sopenharmony_ci	rb_link_node(&orphan->rb, parent, p);
88962306a36Sopenharmony_ci	rb_insert_color(&orphan->rb, root);
89062306a36Sopenharmony_ci	return 0;
89162306a36Sopenharmony_ci}
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_cistatic int dbg_find_check_orphan(struct rb_root *root, ino_t inum)
89462306a36Sopenharmony_ci{
89562306a36Sopenharmony_ci	struct check_orphan *o;
89662306a36Sopenharmony_ci	struct rb_node *p;
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci	p = root->rb_node;
89962306a36Sopenharmony_ci	while (p) {
90062306a36Sopenharmony_ci		o = rb_entry(p, struct check_orphan, rb);
90162306a36Sopenharmony_ci		if (inum < o->inum)
90262306a36Sopenharmony_ci			p = p->rb_left;
90362306a36Sopenharmony_ci		else if (inum > o->inum)
90462306a36Sopenharmony_ci			p = p->rb_right;
90562306a36Sopenharmony_ci		else
90662306a36Sopenharmony_ci			return 1;
90762306a36Sopenharmony_ci	}
90862306a36Sopenharmony_ci	return 0;
90962306a36Sopenharmony_ci}
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_cistatic void dbg_free_check_tree(struct rb_root *root)
91262306a36Sopenharmony_ci{
91362306a36Sopenharmony_ci	struct check_orphan *o, *n;
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci	rbtree_postorder_for_each_entry_safe(o, n, root, rb)
91662306a36Sopenharmony_ci		kfree(o);
91762306a36Sopenharmony_ci}
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_cistatic int dbg_orphan_check(struct ubifs_info *c, struct ubifs_zbranch *zbr,
92062306a36Sopenharmony_ci			    void *priv)
92162306a36Sopenharmony_ci{
92262306a36Sopenharmony_ci	struct check_info *ci = priv;
92362306a36Sopenharmony_ci	ino_t inum;
92462306a36Sopenharmony_ci	int err;
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci	inum = key_inum(c, &zbr->key);
92762306a36Sopenharmony_ci	if (inum != ci->last_ino) {
92862306a36Sopenharmony_ci		/* Lowest node type is the inode node, so it comes first */
92962306a36Sopenharmony_ci		if (key_type(c, &zbr->key) != UBIFS_INO_KEY)
93062306a36Sopenharmony_ci			ubifs_err(c, "found orphan node ino %lu, type %d",
93162306a36Sopenharmony_ci				  (unsigned long)inum, key_type(c, &zbr->key));
93262306a36Sopenharmony_ci		ci->last_ino = inum;
93362306a36Sopenharmony_ci		ci->tot_inos += 1;
93462306a36Sopenharmony_ci		err = ubifs_tnc_read_node(c, zbr, ci->node);
93562306a36Sopenharmony_ci		if (err) {
93662306a36Sopenharmony_ci			ubifs_err(c, "node read failed, error %d", err);
93762306a36Sopenharmony_ci			return err;
93862306a36Sopenharmony_ci		}
93962306a36Sopenharmony_ci		if (ci->node->nlink == 0)
94062306a36Sopenharmony_ci			/* Must be recorded as an orphan */
94162306a36Sopenharmony_ci			if (!dbg_find_check_orphan(&ci->root, inum) &&
94262306a36Sopenharmony_ci			    !dbg_find_orphan(c, inum)) {
94362306a36Sopenharmony_ci				ubifs_err(c, "missing orphan, ino %lu",
94462306a36Sopenharmony_ci					  (unsigned long)inum);
94562306a36Sopenharmony_ci				ci->missing += 1;
94662306a36Sopenharmony_ci			}
94762306a36Sopenharmony_ci	}
94862306a36Sopenharmony_ci	ci->leaf_cnt += 1;
94962306a36Sopenharmony_ci	return 0;
95062306a36Sopenharmony_ci}
95162306a36Sopenharmony_ci
95262306a36Sopenharmony_cistatic int dbg_read_orphans(struct check_info *ci, struct ubifs_scan_leb *sleb)
95362306a36Sopenharmony_ci{
95462306a36Sopenharmony_ci	struct ubifs_scan_node *snod;
95562306a36Sopenharmony_ci	struct ubifs_orph_node *orph;
95662306a36Sopenharmony_ci	ino_t inum;
95762306a36Sopenharmony_ci	int i, n, err;
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci	list_for_each_entry(snod, &sleb->nodes, list) {
96062306a36Sopenharmony_ci		cond_resched();
96162306a36Sopenharmony_ci		if (snod->type != UBIFS_ORPH_NODE)
96262306a36Sopenharmony_ci			continue;
96362306a36Sopenharmony_ci		orph = snod->node;
96462306a36Sopenharmony_ci		n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3;
96562306a36Sopenharmony_ci		for (i = 0; i < n; i++) {
96662306a36Sopenharmony_ci			inum = le64_to_cpu(orph->inos[i]);
96762306a36Sopenharmony_ci			err = dbg_ins_check_orphan(&ci->root, inum);
96862306a36Sopenharmony_ci			if (err)
96962306a36Sopenharmony_ci				return err;
97062306a36Sopenharmony_ci		}
97162306a36Sopenharmony_ci	}
97262306a36Sopenharmony_ci	return 0;
97362306a36Sopenharmony_ci}
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_cistatic int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci)
97662306a36Sopenharmony_ci{
97762306a36Sopenharmony_ci	int lnum, err = 0;
97862306a36Sopenharmony_ci	void *buf;
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci	/* Check no-orphans flag and skip this if no orphans */
98162306a36Sopenharmony_ci	if (c->no_orphs)
98262306a36Sopenharmony_ci		return 0;
98362306a36Sopenharmony_ci
98462306a36Sopenharmony_ci	buf = __vmalloc(c->leb_size, GFP_NOFS);
98562306a36Sopenharmony_ci	if (!buf) {
98662306a36Sopenharmony_ci		ubifs_err(c, "cannot allocate memory to check orphans");
98762306a36Sopenharmony_ci		return 0;
98862306a36Sopenharmony_ci	}
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) {
99162306a36Sopenharmony_ci		struct ubifs_scan_leb *sleb;
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_ci		sleb = ubifs_scan(c, lnum, 0, buf, 0);
99462306a36Sopenharmony_ci		if (IS_ERR(sleb)) {
99562306a36Sopenharmony_ci			err = PTR_ERR(sleb);
99662306a36Sopenharmony_ci			break;
99762306a36Sopenharmony_ci		}
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci		err = dbg_read_orphans(ci, sleb);
100062306a36Sopenharmony_ci		ubifs_scan_destroy(sleb);
100162306a36Sopenharmony_ci		if (err)
100262306a36Sopenharmony_ci			break;
100362306a36Sopenharmony_ci	}
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_ci	vfree(buf);
100662306a36Sopenharmony_ci	return err;
100762306a36Sopenharmony_ci}
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_cistatic int dbg_check_orphans(struct ubifs_info *c)
101062306a36Sopenharmony_ci{
101162306a36Sopenharmony_ci	struct check_info ci;
101262306a36Sopenharmony_ci	int err;
101362306a36Sopenharmony_ci
101462306a36Sopenharmony_ci	if (!dbg_is_chk_orph(c))
101562306a36Sopenharmony_ci		return 0;
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	ci.last_ino = 0;
101862306a36Sopenharmony_ci	ci.tot_inos = 0;
101962306a36Sopenharmony_ci	ci.missing  = 0;
102062306a36Sopenharmony_ci	ci.leaf_cnt = 0;
102162306a36Sopenharmony_ci	ci.root = RB_ROOT;
102262306a36Sopenharmony_ci	ci.node = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS);
102362306a36Sopenharmony_ci	if (!ci.node) {
102462306a36Sopenharmony_ci		ubifs_err(c, "out of memory");
102562306a36Sopenharmony_ci		return -ENOMEM;
102662306a36Sopenharmony_ci	}
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci	err = dbg_scan_orphans(c, &ci);
102962306a36Sopenharmony_ci	if (err)
103062306a36Sopenharmony_ci		goto out;
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci	err = dbg_walk_index(c, &dbg_orphan_check, NULL, &ci);
103362306a36Sopenharmony_ci	if (err) {
103462306a36Sopenharmony_ci		ubifs_err(c, "cannot scan TNC, error %d", err);
103562306a36Sopenharmony_ci		goto out;
103662306a36Sopenharmony_ci	}
103762306a36Sopenharmony_ci
103862306a36Sopenharmony_ci	if (ci.missing) {
103962306a36Sopenharmony_ci		ubifs_err(c, "%lu missing orphan(s)", ci.missing);
104062306a36Sopenharmony_ci		err = -EINVAL;
104162306a36Sopenharmony_ci		goto out;
104262306a36Sopenharmony_ci	}
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_ci	dbg_cmt("last inode number is %lu", ci.last_ino);
104562306a36Sopenharmony_ci	dbg_cmt("total number of inodes is %lu", ci.tot_inos);
104662306a36Sopenharmony_ci	dbg_cmt("total number of leaf nodes is %llu", ci.leaf_cnt);
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ciout:
104962306a36Sopenharmony_ci	dbg_free_check_tree(&ci.root);
105062306a36Sopenharmony_ci	kfree(ci.node);
105162306a36Sopenharmony_ci	return err;
105262306a36Sopenharmony_ci}
1053