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

Commit 33e6c1a0 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:
  UBIFS: fix debugging dump
  UBIFS: improve lprops dump
  UBIFS: various minor commentary fixes
  UBIFS: improve journal head debugging prints
  UBIFS: define journal head numbers in ubifs-media.h
  UBIFS: amend commentaries
  UBIFS: check ubifs_scan error codes better
  UBIFS: do not print scary error messages needlessly
  UBIFS: add inode size debugging check
  UBIFS: constify file and inode operations
  UBIFS: remove unneeded call from ubifs_sync_fs
  UBIFS: kill BKL
  UBIFS: remove unused functions
  UBIFS: suppress compilation warning
parents 0b887ef1 7cce2f4c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -715,7 +715,7 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c)
 * ubifs_get_free_space - return amount of free space.
 * @c: UBIFS file-system description object
 *
 * This function calculates and retuns amount of free space to report to
 * This function calculates and returns amount of free space to report to
 * user-space.
 */
long long ubifs_get_free_space(struct ubifs_info *c)
+1 −1
Original line number Diff line number Diff line
@@ -510,7 +510,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
	int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt;
	int first = 1, iip;
	struct ubifs_debug_info *d = c->dbg;
	union ubifs_key lower_key, upper_key, l_key, u_key;
	union ubifs_key uninitialized_var(lower_key), upper_key, l_key, u_key;
	unsigned long long uninitialized_var(last_sqnum);
	struct ubifs_idx_node *idx;
	struct list_head list;
+105 −7
Original line number Diff line number Diff line
@@ -210,6 +210,20 @@ const char *dbg_cstate(int cmt_state)
	}
}

const char *dbg_jhead(int jhead)
{
	switch (jhead) {
	case GCHD:
		return "0 (GC)";
	case BASEHD:
		return "1 (base)";
	case DATAHD:
		return "2 (data)";
	default:
		return "unknown journal head";
	}
}

static void dump_ch(const struct ubifs_ch *ch)
{
	printk(KERN_DEBUG "\tmagic          %#x\n", le32_to_cpu(ch->magic));
@@ -623,8 +637,9 @@ void dbg_dump_budg(struct ubifs_info *c)
	/* If we are in R/O mode, journal heads do not exist */
	if (c->jheads)
		for (i = 0; i < c->jhead_cnt; i++)
			printk(KERN_DEBUG "\tjhead %d\t LEB %d\n",
			       c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum);
			printk(KERN_DEBUG "\tjhead %s\t LEB %d\n",
			       dbg_jhead(c->jheads[i].wbuf.jhead),
			       c->jheads[i].wbuf.lnum);
	for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) {
		bud = rb_entry(rb, struct ubifs_bud, rb);
		printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum);
@@ -648,9 +663,90 @@ void dbg_dump_budg(struct ubifs_info *c)

void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
{
	printk(KERN_DEBUG "LEB %d lprops: free %d, dirty %d (used %d), "
	       "flags %#x\n", lp->lnum, lp->free, lp->dirty,
	       c->leb_size - lp->free - lp->dirty, lp->flags);
	int i, spc, dark = 0, dead = 0;
	struct rb_node *rb;
	struct ubifs_bud *bud;

	spc = lp->free + lp->dirty;
	if (spc < c->dead_wm)
		dead = spc;
	else
		dark = ubifs_calc_dark(c, spc);

	if (lp->flags & LPROPS_INDEX)
		printk(KERN_DEBUG "LEB %-7d free %-8d dirty %-8d used %-8d "
		       "free + dirty %-8d flags %#x (", lp->lnum, lp->free,
		       lp->dirty, c->leb_size - spc, spc, lp->flags);
	else
		printk(KERN_DEBUG "LEB %-7d free %-8d dirty %-8d used %-8d "
		       "free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d "
		       "flags %#-4x (", lp->lnum, lp->free, lp->dirty,
		       c->leb_size - spc, spc, dark, dead,
		       (int)(spc / UBIFS_MAX_NODE_SZ), lp->flags);

	if (lp->flags & LPROPS_TAKEN) {
		if (lp->flags & LPROPS_INDEX)
			printk(KERN_CONT "index, taken");
		else
			printk(KERN_CONT "taken");
	} else {
		const char *s;

		if (lp->flags & LPROPS_INDEX) {
			switch (lp->flags & LPROPS_CAT_MASK) {
			case LPROPS_DIRTY_IDX:
				s = "dirty index";
				break;
			case LPROPS_FRDI_IDX:
				s = "freeable index";
				break;
			default:
				s = "index";
			}
		} else {
			switch (lp->flags & LPROPS_CAT_MASK) {
			case LPROPS_UNCAT:
				s = "not categorized";
				break;
			case LPROPS_DIRTY:
				s = "dirty";
				break;
			case LPROPS_FREE:
				s = "free";
				break;
			case LPROPS_EMPTY:
				s = "empty";
				break;
			case LPROPS_FREEABLE:
				s = "freeable";
				break;
			default:
				s = NULL;
				break;
			}
		}
		printk(KERN_CONT "%s", s);
	}

	for (rb = rb_first((struct rb_root *)&c->buds); rb; rb = rb_next(rb)) {
		bud = rb_entry(rb, struct ubifs_bud, rb);
		if (bud->lnum == lp->lnum) {
			int head = 0;
			for (i = 0; i < c->jhead_cnt; i++) {
				if (lp->lnum == c->jheads[i].wbuf.lnum) {
					printk(KERN_CONT ", jhead %s",
					       dbg_jhead(i));
					head = 1;
				}
			}
			if (!head)
				printk(KERN_CONT ", bud of jhead %s",
				       dbg_jhead(bud->jhead));
		}
	}
	if (lp->lnum == c->gc_lnum)
		printk(KERN_CONT ", GC LEB");
	printk(KERN_CONT ")\n");
}

void dbg_dump_lprops(struct ubifs_info *c)
@@ -724,7 +820,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)

	printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
	       current->pid, lnum);
	sleb = ubifs_scan(c, lnum, 0, c->dbg->buf);
	sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0);
	if (IS_ERR(sleb)) {
		ubifs_err("scan error %d", (int)PTR_ERR(sleb));
		return;
@@ -909,8 +1005,10 @@ int dbg_check_space_info(struct ubifs_info *c)
	ubifs_msg("saved lprops statistics dump");
	dbg_dump_lstats(&d->saved_lst);
	ubifs_get_lp_stats(c, &lst);

	ubifs_msg("current lprops statistics dump");
	dbg_dump_lstats(&d->saved_lst);
	dbg_dump_lstats(&lst);

	spin_lock(&c->space_lock);
	dbg_dump_budg(c);
	spin_unlock(&c->space_lock);
+5 −0
Original line number Diff line number Diff line
@@ -271,6 +271,7 @@ void ubifs_debugging_exit(struct ubifs_info *c);
/* Dump functions */
const char *dbg_ntype(int type);
const char *dbg_cstate(int cmt_state);
const char *dbg_jhead(int jhead);
const char *dbg_get_key_dump(const struct ubifs_info *c,
			     const union ubifs_key *key);
void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode);
@@ -321,6 +322,8 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
int dbg_check_lprops(struct ubifs_info *c);
int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
			int row, int col);
int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
			 loff_t size);

/* Force the use of in-the-gaps method for testing */

@@ -425,6 +428,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);

#define dbg_ntype(type)                        ""
#define dbg_cstate(cmt_state)                  ""
#define dbg_jhead(jhead)                       ""
#define dbg_get_key_dump(c, key)               ({})
#define dbg_dump_inode(c, inode)               ({})
#define dbg_dump_node(c, node)                 ({})
@@ -460,6 +464,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
#define dbg_check_heap(c, heap, cat, add_pos)      ({})
#define dbg_check_lprops(c)                        0
#define dbg_check_lpt_nodes(c, cnode, row, col)    0
#define dbg_check_inode_size(c, inode, size)       0
#define dbg_force_in_the_gaps_enabled              0
#define dbg_force_in_the_gaps()                    0
#define dbg_failure_mode                           0
+30 −32
Original line number Diff line number Diff line
@@ -21,34 +21,32 @@
 */

/*
 * This file implements VFS file and inode operations of regular files, device
 * This file implements VFS file and inode operations for regular files, device
 * nodes and symlinks as well as address space operations.
 *
 * UBIFS uses 2 page flags: PG_private and PG_checked. PG_private is set if the
 * page is dirty and is used for budgeting purposes - dirty pages should not be
 * budgeted. The PG_checked flag is set if full budgeting is required for the
 * page e.g., when it corresponds to a file hole or it is just beyond the file
 * size. The budgeting is done in 'ubifs_write_begin()', because it is OK to
 * fail in this function, and the budget is released in 'ubifs_write_end()'. So
 * the PG_private and PG_checked flags carry the information about how the page
 * was budgeted, to make it possible to release the budget properly.
 * UBIFS uses 2 page flags: @PG_private and @PG_checked. @PG_private is set if
 * the page is dirty and is used for optimization purposes - dirty pages are
 * not budgeted so the flag shows that 'ubifs_write_end()' should not release
 * the budget for this page. The @PG_checked flag is set if full budgeting is
 * required for the page e.g., when it corresponds to a file hole or it is
 * beyond the file size. The budgeting is done in 'ubifs_write_begin()', because
 * it is OK to fail in this function, and the budget is released in
 * 'ubifs_write_end()'. So the @PG_private and @PG_checked flags carry
 * information about how the page was budgeted, to make it possible to release
 * the budget properly.
 *
 * A thing to keep in mind: inode's 'i_mutex' is locked in most VFS operations
 * we implement. However, this is not true for '->writepage()', which might be
 * called with 'i_mutex' unlocked. For example, when pdflush is performing
 * write-back, it calls 'writepage()' with unlocked 'i_mutex', although the
 * inode has 'I_LOCK' flag in this case. At "normal" work-paths 'i_mutex' is
 * locked in '->writepage', e.g. in "sys_write -> alloc_pages -> direct reclaim
 * path'. So, in '->writepage()' we are only guaranteed that the page is
 * locked.
 * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we
 * implement. However, this is not true for 'ubifs_writepage()', which may be
 * called with @i_mutex unlocked. For example, when pdflush is doing background
 * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal"
 * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the
 * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()'
 * we are only guaranteed that the page is locked.
 *
 * Similarly, 'i_mutex' does not have to be locked in readpage(), e.g.,
 * readahead path does not have it locked ("sys_read -> generic_file_aio_read
 * -> ondemand_readahead -> readpage"). In case of readahead, 'I_LOCK' flag is
 * not set as well. However, UBIFS disables readahead.
 *
 * This, for example means that there might be 2 concurrent '->writepage()'
 * calls for the same inode, but different inode dirty pages.
 * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the
 * read-ahead path does not lock it ("sys_read -> generic_file_aio_read ->
 * ondemand_readahead -> readpage"). In case of readahead, @I_LOCK flag is not
 * set as well. However, UBIFS disables readahead.
 */

#include "ubifs.h"
@@ -449,9 +447,9 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
			/*
			 * We change whole page so no need to load it. But we
			 * have to set the @PG_checked flag to make the further
			 * code the page is new. This might be not true, but it
			 * is better to budget more that to read the page from
			 * the media.
			 * code know that the page is new. This might be not
			 * true, but it is better to budget more than to read
			 * the page from the media.
			 */
			SetPageChecked(page);
			skipped_read = 1;
@@ -497,8 +495,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
	}

	/*
	 * Whee, we aquired budgeting quickly - without involving
	 * garbage-collection, committing or forceing write-back. We return
	 * Whee, we acquired budgeting quickly - without involving
	 * garbage-collection, committing or forcing write-back. We return
	 * with @ui->ui_mutex locked if we are appending pages, and unlocked
	 * otherwise. This is an optimization (slightly hacky though).
	 */
@@ -562,7 +560,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,

		/*
		 * Return 0 to force VFS to repeat the whole operation, or the
		 * error code if 'do_readpage()' failes.
		 * error code if 'do_readpage()' fails.
		 */
		copied = do_readpage(page);
		goto out;
@@ -1175,11 +1173,11 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
	ui->ui_size = inode->i_size;
	/* Truncation changes inode [mc]time */
	inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
	/* The other attributes may be changed at the same time as well */
	/* Other attributes may be changed at the same time as well */
	do_attr_changes(inode, attr);

	err = ubifs_jnl_truncate(c, inode, old_size, new_size);
	mutex_unlock(&ui->ui_mutex);

out_budg:
	if (budgeted)
		ubifs_release_budget(c, &req);
Loading