Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb08d8ff authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6

* 'linux-next' of git://git.infradead.org/ubifs-2.6: (52 commits)
  UBIFS: switch to dynamic printks
  UBIFS: fix kernel-doc comments
  UBIFS: fix extremely rare mount failure
  UBIFS: simplify LEB recovery function further
  UBIFS: always cleanup the recovered LEB
  UBIFS: clean up LEB recovery function
  UBIFS: fix-up free space on mount if flag is set
  UBIFS: add the fixup function
  UBIFS: add a superblock flag for free space fix-up
  UBIFS: share the next_log_lnum helper
  UBIFS: expect corruption only in last journal head LEBs
  UBIFS: synchronize write-buffer before switching to the next bud
  UBIFS: remove BUG statement
  UBIFS: change bud replay function conventions
  UBIFS: substitute the replay tree with a replay list
  UBIFS: simplify replay
  UBIFS: store free and dirty space in the bud replay entry
  UBIFS: remove unnecessary stack variable
  UBIFS: double check that buds are replied in order
  UBIFS: make 2 functions static
  ...
parents 9f22aae0 56e46742
Loading
Loading
Loading
Loading
+2 −24
Original line number Diff line number Diff line
@@ -115,28 +115,8 @@ ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs
Module Parameters for Debugging
===============================

When UBIFS has been compiled with debugging enabled, there are 3 module
When UBIFS has been compiled with debugging enabled, there are 2 module
parameters that are available to control aspects of testing and debugging.
The parameters are unsigned integers where each bit controls an option.
The parameters are:

debug_msgs	Selects which debug messages to display, as follows:

		Message Type				Flag value

		General messages			1
		Journal messages			2
		Mount messages				4
		Commit messages				8
		LEB search messages			16
		Budgeting messages			32
		Garbage collection messages		64
		Tree Node Cache (TNC) messages		128
		LEB properties (lprops) messages	256
		Input/output messages			512
		Log messages				1024
		Scan messages				2048
		Recovery messages			4096

debug_chks	Selects extra checks that UBIFS can do while running:

@@ -154,11 +134,9 @@ debug_tsts Selects a mode of testing, as follows:

		Test mode				Flag value

		Force in-the-gaps method		2
		Failure mode for recovery testing	4

For example, set debug_msgs to 5 to display General messages and Mount
messages.
For example, set debug_chks to 3 to enable general and TNC checks.


References
+52 −52
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ static long long get_liability(struct ubifs_info *c)
	long long liab;

	spin_lock(&c->space_lock);
	liab = c->budg_idx_growth + c->budg_data_growth + c->budg_dd_growth;
	liab = c->bi.idx_growth + c->bi.data_growth + c->bi.dd_growth;
	spin_unlock(&c->space_lock);
	return liab;
}
@@ -180,7 +180,7 @@ int ubifs_calc_min_idx_lebs(struct ubifs_info *c)
	int idx_lebs;
	long long idx_size;

	idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx;
	idx_size = c->bi.old_idx_sz + c->bi.idx_growth + c->bi.uncommitted_idx;
	/* And make sure we have thrice the index size of space reserved */
	idx_size += idx_size << 1;
	/*
@@ -292,13 +292,13 @@ static int can_use_rp(struct ubifs_info *c)
 * budgeted index space to the size of the current index, multiplies this by 3,
 * and makes sure this does not exceed the amount of free LEBs.
 *
 * Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables:
 * Notes about @c->bi.min_idx_lebs and @c->lst.idx_lebs variables:
 * o @c->lst.idx_lebs is the number of LEBs the index currently uses. It might
 *    be large, because UBIFS does not do any index consolidation as long as
 *    there is free space. IOW, the index may take a lot of LEBs, but the LEBs
 *    will contain a lot of dirt.
 * o @c->min_idx_lebs is the number of LEBS the index presumably takes. IOW,
 *    the index may be consolidated to take up to @c->min_idx_lebs LEBs.
 * o @c->bi.min_idx_lebs is the number of LEBS the index presumably takes. IOW,
 *    the index may be consolidated to take up to @c->bi.min_idx_lebs LEBs.
 *
 * This function returns zero in case of success, and %-ENOSPC in case of
 * failure.
@@ -343,13 +343,13 @@ static int do_budget_space(struct ubifs_info *c)
	       c->lst.taken_empty_lebs;
	if (unlikely(rsvd_idx_lebs > lebs)) {
		dbg_budg("out of indexing space: min_idx_lebs %d (old %d), "
			 "rsvd_idx_lebs %d", min_idx_lebs, c->min_idx_lebs,
			 "rsvd_idx_lebs %d", min_idx_lebs, c->bi.min_idx_lebs,
			 rsvd_idx_lebs);
		return -ENOSPC;
	}

	available = ubifs_calc_available(c, min_idx_lebs);
	outstanding = c->budg_data_growth + c->budg_dd_growth;
	outstanding = c->bi.data_growth + c->bi.dd_growth;

	if (unlikely(available < outstanding)) {
		dbg_budg("out of data space: available %lld, outstanding %lld",
@@ -360,7 +360,7 @@ static int do_budget_space(struct ubifs_info *c)
	if (available - outstanding <= c->rp_size && !can_use_rp(c))
		return -ENOSPC;

	c->min_idx_lebs = min_idx_lebs;
	c->bi.min_idx_lebs = min_idx_lebs;
	return 0;
}

@@ -393,11 +393,11 @@ static int calc_data_growth(const struct ubifs_info *c,
{
	int data_growth;

	data_growth = req->new_ino  ? c->inode_budget : 0;
	data_growth = req->new_ino  ? c->bi.inode_budget : 0;
	if (req->new_page)
		data_growth += c->page_budget;
		data_growth += c->bi.page_budget;
	if (req->new_dent)
		data_growth += c->dent_budget;
		data_growth += c->bi.dent_budget;
	data_growth += req->new_ino_d;
	return data_growth;
}
@@ -413,12 +413,12 @@ static int calc_dd_growth(const struct ubifs_info *c,
{
	int dd_growth;

	dd_growth = req->dirtied_page ? c->page_budget : 0;
	dd_growth = req->dirtied_page ? c->bi.page_budget : 0;

	if (req->dirtied_ino)
		dd_growth += c->inode_budget << (req->dirtied_ino - 1);
		dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1);
	if (req->mod_dent)
		dd_growth += c->dent_budget;
		dd_growth += c->bi.dent_budget;
	dd_growth += req->dirtied_ino_d;
	return dd_growth;
}
@@ -460,19 +460,19 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)

again:
	spin_lock(&c->space_lock);
	ubifs_assert(c->budg_idx_growth >= 0);
	ubifs_assert(c->budg_data_growth >= 0);
	ubifs_assert(c->budg_dd_growth >= 0);
	ubifs_assert(c->bi.idx_growth >= 0);
	ubifs_assert(c->bi.data_growth >= 0);
	ubifs_assert(c->bi.dd_growth >= 0);

	if (unlikely(c->nospace) && (c->nospace_rp || !can_use_rp(c))) {
	if (unlikely(c->bi.nospace) && (c->bi.nospace_rp || !can_use_rp(c))) {
		dbg_budg("no space");
		spin_unlock(&c->space_lock);
		return -ENOSPC;
	}

	c->budg_idx_growth += idx_growth;
	c->budg_data_growth += data_growth;
	c->budg_dd_growth += dd_growth;
	c->bi.idx_growth += idx_growth;
	c->bi.data_growth += data_growth;
	c->bi.dd_growth += dd_growth;

	err = do_budget_space(c);
	if (likely(!err)) {
@@ -484,9 +484,9 @@ again:
	}

	/* Restore the old values */
	c->budg_idx_growth -= idx_growth;
	c->budg_data_growth -= data_growth;
	c->budg_dd_growth -= dd_growth;
	c->bi.idx_growth -= idx_growth;
	c->bi.data_growth -= data_growth;
	c->bi.dd_growth -= dd_growth;
	spin_unlock(&c->space_lock);

	if (req->fast) {
@@ -506,9 +506,9 @@ again:
			goto again;
		}
		dbg_budg("FS is full, -ENOSPC");
		c->nospace = 1;
		c->bi.nospace = 1;
		if (can_use_rp(c) || c->rp_size == 0)
			c->nospace_rp = 1;
			c->bi.nospace_rp = 1;
		smp_wmb();
	} else
		ubifs_err("cannot budget space, error %d", err);
@@ -523,8 +523,8 @@ again:
 * This function releases the space budgeted by 'ubifs_budget_space()'. Note,
 * since the index changes (which were budgeted for in @req->idx_growth) will
 * only be written to the media on commit, this function moves the index budget
 * from @c->budg_idx_growth to @c->budg_uncommitted_idx. The latter will be
 * zeroed by the commit operation.
 * from @c->bi.idx_growth to @c->bi.uncommitted_idx. The latter will be zeroed
 * by the commit operation.
 */
void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
{
@@ -553,23 +553,23 @@ void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
	if (!req->data_growth && !req->dd_growth)
		return;

	c->nospace = c->nospace_rp = 0;
	c->bi.nospace = c->bi.nospace_rp = 0;
	smp_wmb();

	spin_lock(&c->space_lock);
	c->budg_idx_growth -= req->idx_growth;
	c->budg_uncommitted_idx += req->idx_growth;
	c->budg_data_growth -= req->data_growth;
	c->budg_dd_growth -= req->dd_growth;
	c->min_idx_lebs = ubifs_calc_min_idx_lebs(c);

	ubifs_assert(c->budg_idx_growth >= 0);
	ubifs_assert(c->budg_data_growth >= 0);
	ubifs_assert(c->budg_dd_growth >= 0);
	ubifs_assert(c->min_idx_lebs < c->main_lebs);
	ubifs_assert(!(c->budg_idx_growth & 7));
	ubifs_assert(!(c->budg_data_growth & 7));
	ubifs_assert(!(c->budg_dd_growth & 7));
	c->bi.idx_growth -= req->idx_growth;
	c->bi.uncommitted_idx += req->idx_growth;
	c->bi.data_growth -= req->data_growth;
	c->bi.dd_growth -= req->dd_growth;
	c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);

	ubifs_assert(c->bi.idx_growth >= 0);
	ubifs_assert(c->bi.data_growth >= 0);
	ubifs_assert(c->bi.dd_growth >= 0);
	ubifs_assert(c->bi.min_idx_lebs < c->main_lebs);
	ubifs_assert(!(c->bi.idx_growth & 7));
	ubifs_assert(!(c->bi.data_growth & 7));
	ubifs_assert(!(c->bi.dd_growth & 7));
	spin_unlock(&c->space_lock);
}

@@ -586,13 +586,13 @@ void ubifs_convert_page_budget(struct ubifs_info *c)
{
	spin_lock(&c->space_lock);
	/* Release the index growth reservation */
	c->budg_idx_growth -= c->max_idx_node_sz << UBIFS_BLOCKS_PER_PAGE_SHIFT;
	c->bi.idx_growth -= c->max_idx_node_sz << UBIFS_BLOCKS_PER_PAGE_SHIFT;
	/* Release the data growth reservation */
	c->budg_data_growth -= c->page_budget;
	c->bi.data_growth -= c->bi.page_budget;
	/* Increase the dirty data growth reservation instead */
	c->budg_dd_growth += c->page_budget;
	c->bi.dd_growth += c->bi.page_budget;
	/* And re-calculate the indexing space reservation */
	c->min_idx_lebs = ubifs_calc_min_idx_lebs(c);
	c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
	spin_unlock(&c->space_lock);
}

@@ -612,7 +612,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c,

	memset(&req, 0, sizeof(struct ubifs_budget_req));
	/* The "no space" flags will be cleared because dd_growth is > 0 */
	req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8);
	req.dd_growth = c->bi.inode_budget + ALIGN(ui->data_len, 8);
	ubifs_release_budget(c, &req);
}

@@ -682,9 +682,9 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c)
	int rsvd_idx_lebs, lebs;
	long long available, outstanding, free;

	ubifs_assert(c->min_idx_lebs == ubifs_calc_min_idx_lebs(c));
	outstanding = c->budg_data_growth + c->budg_dd_growth;
	available = ubifs_calc_available(c, c->min_idx_lebs);
	ubifs_assert(c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
	outstanding = c->bi.data_growth + c->bi.dd_growth;
	available = ubifs_calc_available(c, c->bi.min_idx_lebs);

	/*
	 * When reporting free space to user-space, UBIFS guarantees that it is
@@ -697,8 +697,8 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c)
	 * Note, the calculations below are similar to what we have in
	 * 'do_budget_space()', so refer there for comments.
	 */
	if (c->min_idx_lebs > c->lst.idx_lebs)
		rsvd_idx_lebs = c->min_idx_lebs - c->lst.idx_lebs;
	if (c->bi.min_idx_lebs > c->lst.idx_lebs)
		rsvd_idx_lebs = c->bi.min_idx_lebs - c->lst.idx_lebs;
	else
		rsvd_idx_lebs = 0;
	lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
+1 −1
Original line number Diff line number Diff line
@@ -182,7 +182,7 @@ static int do_commit(struct ubifs_info *c)
	c->mst_node->root_len    = cpu_to_le32(zroot.len);
	c->mst_node->ihead_lnum  = cpu_to_le32(c->ihead_lnum);
	c->mst_node->ihead_offs  = cpu_to_le32(c->ihead_offs);
	c->mst_node->index_size  = cpu_to_le64(c->old_idx_sz);
	c->mst_node->index_size  = cpu_to_le64(c->bi.old_idx_sz);
	c->mst_node->lpt_lnum    = cpu_to_le32(c->lpt_lnum);
	c->mst_node->lpt_offs    = cpu_to_le32(c->lpt_offs);
	c->mst_node->nhead_lnum  = cpu_to_le32(c->nhead_lnum);
+108 −59
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@
#include <linux/moduleparam.h>
#include <linux/debugfs.h>
#include <linux/math64.h>
#include <linux/slab.h>

#ifdef CONFIG_UBIFS_FS_DEBUG

@@ -43,15 +42,12 @@ DEFINE_SPINLOCK(dbg_lock);
static char dbg_key_buf0[128];
static char dbg_key_buf1[128];

unsigned int ubifs_msg_flags;
unsigned int ubifs_chk_flags;
unsigned int ubifs_tst_flags;

module_param_named(debug_msgs, ubifs_msg_flags, uint, S_IRUGO | S_IWUSR);
module_param_named(debug_chks, ubifs_chk_flags, uint, S_IRUGO | S_IWUSR);
module_param_named(debug_tsts, ubifs_tst_flags, uint, S_IRUGO | S_IWUSR);

MODULE_PARM_DESC(debug_msgs, "Debug message type flags");
MODULE_PARM_DESC(debug_chks, "Debug check flags");
MODULE_PARM_DESC(debug_tsts, "Debug special test flags");

@@ -317,6 +313,8 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
		printk(KERN_DEBUG "\tflags          %#x\n", sup_flags);
		printk(KERN_DEBUG "\t  big_lpt      %u\n",
		       !!(sup_flags & UBIFS_FLG_BIGLPT));
		printk(KERN_DEBUG "\t  space_fixup  %u\n",
		       !!(sup_flags & UBIFS_FLG_SPACE_FIXUP));
		printk(KERN_DEBUG "\tmin_io_size    %u\n",
		       le32_to_cpu(sup->min_io_size));
		printk(KERN_DEBUG "\tleb_size       %u\n",
@@ -602,7 +600,7 @@ void dbg_dump_lstats(const struct ubifs_lp_stats *lst)
	spin_unlock(&dbg_lock);
}

void dbg_dump_budg(struct ubifs_info *c)
void dbg_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
{
	int i;
	struct rb_node *rb;
@@ -610,26 +608,42 @@ void dbg_dump_budg(struct ubifs_info *c)
	struct ubifs_gced_idx_leb *idx_gc;
	long long available, outstanding, free;

	ubifs_assert(spin_is_locked(&c->space_lock));
	spin_lock(&c->space_lock);
	spin_lock(&dbg_lock);
	printk(KERN_DEBUG "(pid %d) Budgeting info: budg_data_growth %lld, "
	       "budg_dd_growth %lld, budg_idx_growth %lld\n", current->pid,
	       c->budg_data_growth, c->budg_dd_growth, c->budg_idx_growth);
	printk(KERN_DEBUG "\tdata budget sum %lld, total budget sum %lld, "
	       "freeable_cnt %d\n", c->budg_data_growth + c->budg_dd_growth,
	       c->budg_data_growth + c->budg_dd_growth + c->budg_idx_growth,
	       c->freeable_cnt);
	printk(KERN_DEBUG "\tmin_idx_lebs %d, old_idx_sz %lld, "
	       "calc_idx_sz %lld, idx_gc_cnt %d\n", c->min_idx_lebs,
	       c->old_idx_sz, c->calc_idx_sz, c->idx_gc_cnt);
	printk(KERN_DEBUG "(pid %d) Budgeting info: data budget sum %lld, "
	       "total budget sum %lld\n", current->pid,
	       bi->data_growth + bi->dd_growth,
	       bi->data_growth + bi->dd_growth + bi->idx_growth);
	printk(KERN_DEBUG "\tbudg_data_growth %lld, budg_dd_growth %lld, "
	       "budg_idx_growth %lld\n", bi->data_growth, bi->dd_growth,
	       bi->idx_growth);
	printk(KERN_DEBUG "\tmin_idx_lebs %d, old_idx_sz %llu, "
	       "uncommitted_idx %lld\n", bi->min_idx_lebs, bi->old_idx_sz,
	       bi->uncommitted_idx);
	printk(KERN_DEBUG "\tpage_budget %d, inode_budget %d, dent_budget %d\n",
	       bi->page_budget, bi->inode_budget, bi->dent_budget);
	printk(KERN_DEBUG "\tnospace %u, nospace_rp %u\n",
	       bi->nospace, bi->nospace_rp);
	printk(KERN_DEBUG "\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n",
	       c->dark_wm, c->dead_wm, c->max_idx_node_sz);

	if (bi != &c->bi)
		/*
		 * If we are dumping saved budgeting data, do not print
		 * additional information which is about the current state, not
		 * the old one which corresponded to the saved budgeting data.
		 */
		goto out_unlock;

	printk(KERN_DEBUG "\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d\n",
	       c->freeable_cnt, c->calc_idx_sz, c->idx_gc_cnt);
	printk(KERN_DEBUG "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, "
	       "clean_zn_cnt %ld\n", atomic_long_read(&c->dirty_pg_cnt),
	       atomic_long_read(&c->dirty_zn_cnt),
	       atomic_long_read(&c->clean_zn_cnt));
	printk(KERN_DEBUG "\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n",
	       c->dark_wm, c->dead_wm, c->max_idx_node_sz);
	printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n",
	       c->gc_lnum, c->ihead_lnum);

	/* If we are in R/O mode, journal heads do not exist */
	if (c->jheads)
		for (i = 0; i < c->jhead_cnt; i++)
@@ -648,13 +662,15 @@ void dbg_dump_budg(struct ubifs_info *c)
	printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state);

	/* Print budgeting predictions */
	available = ubifs_calc_available(c, c->min_idx_lebs);
	outstanding = c->budg_data_growth + c->budg_dd_growth;
	available = ubifs_calc_available(c, c->bi.min_idx_lebs);
	outstanding = c->bi.data_growth + c->bi.dd_growth;
	free = ubifs_get_free_space_nolock(c);
	printk(KERN_DEBUG "Budgeting predictions:\n");
	printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n",
	       available, outstanding, free);
out_unlock:
	spin_unlock(&dbg_lock);
	spin_unlock(&c->space_lock);
}

void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
@@ -729,7 +745,13 @@ void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
		if (bud->lnum == lp->lnum) {
			int head = 0;
			for (i = 0; i < c->jhead_cnt; i++) {
				if (lp->lnum == c->jheads[i].wbuf.lnum) {
				/*
				 * Note, if we are in R/O mode or in the middle
				 * of mounting/re-mounting, the write-buffers do
				 * not exist.
				 */
				if (c->jheads &&
				    lp->lnum == c->jheads[i].wbuf.lnum) {
					printk(KERN_CONT ", jhead %s",
					       dbg_jhead(i));
					head = 1;
@@ -976,6 +998,8 @@ void dbg_save_space_info(struct ubifs_info *c)

	spin_lock(&c->space_lock);
	memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats));
	memcpy(&d->saved_bi, &c->bi, sizeof(struct ubifs_budg_info));
	d->saved_idx_gc_cnt = c->idx_gc_cnt;

	/*
	 * We use a dirty hack here and zero out @c->freeable_cnt, because it
@@ -1042,14 +1066,14 @@ int dbg_check_space_info(struct ubifs_info *c)
out:
	ubifs_msg("saved lprops statistics dump");
	dbg_dump_lstats(&d->saved_lst);
	ubifs_get_lp_stats(c, &lst);

	ubifs_msg("saved budgeting info dump");
	dbg_dump_budg(c, &d->saved_bi);
	ubifs_msg("saved idx_gc_cnt %d", d->saved_idx_gc_cnt);
	ubifs_msg("current lprops statistics dump");
	ubifs_get_lp_stats(c, &lst);
	dbg_dump_lstats(&lst);

	spin_lock(&c->space_lock);
	dbg_dump_budg(c);
	spin_unlock(&c->space_lock);
	ubifs_msg("current budgeting info dump");
	dbg_dump_budg(c, &c->bi);
	dump_stack();
	return -EINVAL;
}
@@ -1793,6 +1817,8 @@ static struct fsck_inode *add_inode(struct ubifs_info *c,
	struct rb_node **p, *parent = NULL;
	struct fsck_inode *fscki;
	ino_t inum = key_inum_flash(c, &ino->key);
	struct inode *inode;
	struct ubifs_inode *ui;

	p = &fsckd->inodes.rb_node;
	while (*p) {
@@ -1816,19 +1842,46 @@ static struct fsck_inode *add_inode(struct ubifs_info *c,
	if (!fscki)
		return ERR_PTR(-ENOMEM);

	inode = ilookup(c->vfs_sb, inum);

	fscki->inum = inum;
	/*
	 * If the inode is present in the VFS inode cache, use it instead of
	 * the on-flash inode which might be out-of-date. E.g., the size might
	 * be out-of-date. If we do not do this, the following may happen, for
	 * example:
	 *   1. A power cut happens
	 *   2. We mount the file-system R/O, the replay process fixes up the
	 *      inode size in the VFS cache, but on on-flash.
	 *   3. 'check_leaf()' fails because it hits a data node beyond inode
	 *      size.
	 */
	if (!inode) {
		fscki->nlink = le32_to_cpu(ino->nlink);
		fscki->size = le64_to_cpu(ino->size);
		fscki->xattr_cnt = le32_to_cpu(ino->xattr_cnt);
		fscki->xattr_sz = le32_to_cpu(ino->xattr_size);
		fscki->xattr_nms = le32_to_cpu(ino->xattr_names);
		fscki->mode = le32_to_cpu(ino->mode);
	} else {
		ui = ubifs_inode(inode);
		fscki->nlink = inode->i_nlink;
		fscki->size = inode->i_size;
		fscki->xattr_cnt = ui->xattr_cnt;
		fscki->xattr_sz = ui->xattr_size;
		fscki->xattr_nms = ui->xattr_names;
		fscki->mode = inode->i_mode;
		iput(inode);
	}

	if (S_ISDIR(fscki->mode)) {
		fscki->calc_sz = UBIFS_INO_NODE_SZ;
		fscki->calc_cnt = 2;
	}

	rb_link_node(&fscki->rb, parent, p);
	rb_insert_color(&fscki->rb, &fsckd->inodes);

	return fscki;
}

@@ -2421,7 +2474,8 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head)
		hashb = key_block(c, &sb->key);

		if (hasha > hashb) {
			ubifs_err("larger hash %u goes before %u", hasha, hashb);
			ubifs_err("larger hash %u goes before %u",
				  hasha, hashb);
			goto error_dump;
		}
	}
@@ -2437,14 +2491,12 @@ error_dump:
	return 0;
}

static int invocation_cnt;

int dbg_force_in_the_gaps(void)
{
	if (!dbg_force_in_the_gaps_enabled)
	if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
		return 0;
	/* Force in-the-gaps every 8th commit */
	return !((invocation_cnt++) & 0x7);

	return !(random32() & 7);
}

/* Failure mode for recovery testing */
@@ -2632,7 +2684,7 @@ int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
		 int len, int check)
{
	if (in_failure_mode(desc))
		return -EIO;
		return -EROFS;
	return ubi_leb_read(desc, lnum, buf, offset, len, check);
}

@@ -2642,7 +2694,7 @@ int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
	int err, failing;

	if (in_failure_mode(desc))
		return -EIO;
		return -EROFS;
	failing = do_fail(desc, lnum, 1);
	if (failing)
		cut_data(buf, len);
@@ -2650,7 +2702,7 @@ int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
	if (err)
		return err;
	if (failing)
		return -EIO;
		return -EROFS;
	return 0;
}

@@ -2660,12 +2712,12 @@ int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
	int err;

	if (do_fail(desc, lnum, 1))
		return -EIO;
		return -EROFS;
	err = ubi_leb_change(desc, lnum, buf, len, dtype);
	if (err)
		return err;
	if (do_fail(desc, lnum, 1))
		return -EIO;
		return -EROFS;
	return 0;
}

@@ -2674,12 +2726,12 @@ int dbg_leb_erase(struct ubi_volume_desc *desc, int lnum)
	int err;

	if (do_fail(desc, lnum, 0))
		return -EIO;
		return -EROFS;
	err = ubi_leb_erase(desc, lnum);
	if (err)
		return err;
	if (do_fail(desc, lnum, 0))
		return -EIO;
		return -EROFS;
	return 0;
}

@@ -2688,19 +2740,19 @@ int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum)
	int err;

	if (do_fail(desc, lnum, 0))
		return -EIO;
		return -EROFS;
	err = ubi_leb_unmap(desc, lnum);
	if (err)
		return err;
	if (do_fail(desc, lnum, 0))
		return -EIO;
		return -EROFS;
	return 0;
}

int dbg_is_mapped(struct ubi_volume_desc *desc, int lnum)
{
	if (in_failure_mode(desc))
		return -EIO;
		return -EROFS;
	return ubi_is_mapped(desc, lnum);
}

@@ -2709,12 +2761,12 @@ int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
	int err;

	if (do_fail(desc, lnum, 0))
		return -EIO;
		return -EROFS;
	err = ubi_leb_map(desc, lnum, dtype);
	if (err)
		return err;
	if (do_fail(desc, lnum, 0))
		return -EIO;
		return -EROFS;
	return 0;
}

@@ -2784,7 +2836,7 @@ void dbg_debugfs_exit(void)
static int open_debugfs_file(struct inode *inode, struct file *file)
{
	file->private_data = inode->i_private;
	return 0;
	return nonseekable_open(inode, file);
}

static ssize_t write_debugfs_file(struct file *file, const char __user *buf,
@@ -2795,18 +2847,15 @@ static ssize_t write_debugfs_file(struct file *file, const char __user *buf,

	if (file->f_path.dentry == d->dfs_dump_lprops)
		dbg_dump_lprops(c);
	else if (file->f_path.dentry == d->dfs_dump_budg) {
		spin_lock(&c->space_lock);
		dbg_dump_budg(c);
		spin_unlock(&c->space_lock);
	} else if (file->f_path.dentry == d->dfs_dump_tnc) {
	else if (file->f_path.dentry == d->dfs_dump_budg)
		dbg_dump_budg(c, &c->bi);
	else if (file->f_path.dentry == d->dfs_dump_tnc) {
		mutex_lock(&c->tnc_mutex);
		dbg_dump_tnc(c);
		mutex_unlock(&c->tnc_mutex);
	} else
		return -EINVAL;

	*ppos += count;
	return count;
}

@@ -2814,7 +2863,7 @@ static const struct file_operations dfs_fops = {
	.open = open_debugfs_file,
	.write = write_debugfs_file,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
	.llseek = no_llseek,
};

/**
+64 −114

File changed.

Preview size limit exceeded, changes collapsed.

Loading