Skip to content

Commit

Permalink
Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6
Browse files Browse the repository at this point in the history
* '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
  • Loading branch information
torvalds committed Sep 21, 2009
2 parents 0b887ef + 7cce2f4 commit 33e6c1a
Show file tree
Hide file tree
Showing 22 changed files with 345 additions and 181 deletions.
2 changes: 1 addition & 1 deletion fs/ubifs/budget.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion fs/ubifs/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
112 changes: 105 additions & 7 deletions fs/ubifs/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions fs/ubifs/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */

Expand Down Expand Up @@ -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) ({})
Expand Down Expand Up @@ -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
Expand Down
62 changes: 30 additions & 32 deletions fs/ubifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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).
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion fs/ubifs/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
* We scan the entire LEB even though we only really need to scan up to
* (c->leb_size - lp->free).
*/
sleb = ubifs_scan(c, lnum, 0, c->sbuf);
sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0);
if (IS_ERR(sleb))
return PTR_ERR(sleb);

Expand Down
29 changes: 15 additions & 14 deletions fs/ubifs/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer)
{
struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer);

dbg_io("jhead %d", wbuf->jhead);
dbg_io("jhead %s", dbg_jhead(wbuf->jhead));
wbuf->need_sync = 1;
wbuf->c->need_wbuf_sync = 1;
ubifs_wake_up_bgt(wbuf->c);
Expand All @@ -314,7 +314,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf)

if (wbuf->no_timer)
return;
dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead,
dbg_io("set timer for jhead %s, %llu-%llu millisecs",
dbg_jhead(wbuf->jhead),
div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC),
div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta,
USEC_PER_SEC));
Expand Down Expand Up @@ -351,8 +352,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
/* Write-buffer is empty or not seeked */
return 0;

dbg_io("LEB %d:%d, %d bytes, jhead %d",
wbuf->lnum, wbuf->offs, wbuf->used, wbuf->jhead);
dbg_io("LEB %d:%d, %d bytes, jhead %s",
wbuf->lnum, wbuf->offs, wbuf->used, dbg_jhead(wbuf->jhead));
ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY));
ubifs_assert(!(wbuf->avail & 7));
ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size);
Expand Down Expand Up @@ -401,7 +402,7 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
{
const struct ubifs_info *c = wbuf->c;

dbg_io("LEB %d:%d, jhead %d", lnum, offs, wbuf->jhead);
dbg_io("LEB %d:%d, jhead %s", lnum, offs, dbg_jhead(wbuf->jhead));
ubifs_assert(lnum >= 0 && lnum < c->leb_cnt);
ubifs_assert(offs >= 0 && offs <= c->leb_size);
ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7));
Expand Down Expand Up @@ -508,9 +509,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
struct ubifs_info *c = wbuf->c;
int err, written, n, aligned_len = ALIGN(len, 8), offs;

dbg_io("%d bytes (%s) to jhead %d wbuf at LEB %d:%d", len,
dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->jhead,
wbuf->lnum, wbuf->offs + wbuf->used);
dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len,
dbg_ntype(((struct ubifs_ch *)buf)->node_type),
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs + wbuf->used);
ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt);
ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0);
ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size);
Expand All @@ -535,8 +536,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
memcpy(wbuf->buf + wbuf->used, buf, len);

if (aligned_len == wbuf->avail) {
dbg_io("flush jhead %d wbuf to LEB %d:%d",
wbuf->jhead, wbuf->lnum, wbuf->offs);
dbg_io("flush jhead %s wbuf to LEB %d:%d",
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf,
wbuf->offs, c->min_io_size,
wbuf->dtype);
Expand Down Expand Up @@ -564,8 +565,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
* minimal I/O unit. We have to fill and flush write-buffer and switch
* to the next min. I/O unit.
*/
dbg_io("flush jhead %d wbuf to LEB %d:%d",
wbuf->jhead, wbuf->lnum, wbuf->offs);
dbg_io("flush jhead %s wbuf to LEB %d:%d",
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail);
err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs,
c->min_io_size, wbuf->dtype);
Expand Down Expand Up @@ -698,8 +699,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
int err, rlen, overlap;
struct ubifs_ch *ch = buf;

dbg_io("LEB %d:%d, %s, length %d, jhead %d", lnum, offs,
dbg_ntype(type), len, wbuf->jhead);
dbg_io("LEB %d:%d, %s, length %d, jhead %s", lnum, offs,
dbg_ntype(type), len, dbg_jhead(wbuf->jhead));
ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
ubifs_assert(!(offs & 7) && offs < c->leb_size);
ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
Expand Down
Loading

0 comments on commit 33e6c1a

Please sign in to comment.