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: (25 commits)
  UBIFS: clean-up commentaries
  UBIFS: save 128KiB or more RAM
  UBIFS: allocate orphans scan buffer on demand
  UBIFS: allocate lpt dump buffer on demand
  UBIFS: allocate ltab checking buffer on demand
  UBIFS: allocate scanning buffer on demand
  UBIFS: allocate dump buffer on demand
  UBIFS: do not check data crc by default
  UBIFS: simplify UBIFS Kconfig menu
  UBIFS: print max. index node size
  UBIFS: handle allocation failures in UBIFS write path
  UBIFS: use max_write_size during recovery
  UBIFS: use max_write_size for write-buffers
  UBIFS: introduce write-buffer size field
  UBI: incorporate LEB offset information
  UBIFS: incorporate maximum write size
  UBI: provide LEB offset information
  UBI: incorporate maximum write size
  UBIFS: fix LEB number in printk
  UBIFS: restrict world-writable debugfs files
  ...
  • Loading branch information
torvalds committed Mar 18, 2011
2 parents fd57ed0 + 5d630e4 commit 8f627a8
Show file tree
Hide file tree
Showing 19 changed files with 490 additions and 176 deletions.
4 changes: 2 additions & 2 deletions Documentation/filesystems/ubifs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ Mount options
bulk_read read more in one go to take advantage of flash
media that read faster sequentially
no_bulk_read (*) do not bulk-read
no_chk_data_crc skip checking of CRCs on data nodes in order to
no_chk_data_crc (*) skip checking of CRCs on data nodes in order to
improve read performance. Use this option only
if the flash media is highly reliable. The effect
of this option is that corruption of the contents
of a file can go unnoticed.
chk_data_crc (*) do not skip checking CRCs on data nodes
chk_data_crc do not skip checking CRCs on data nodes
compr=none override default compressor and set it to "none"
compr=lzo override default compressor and set it to "lzo"
compr=zlib override default compressor and set it to "zlib"
Expand Down
14 changes: 14 additions & 0 deletions drivers/mtd/ubi/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -690,11 +690,25 @@ static int io_init(struct ubi_device *ubi)
ubi_assert(ubi->hdrs_min_io_size <= ubi->min_io_size);
ubi_assert(ubi->min_io_size % ubi->hdrs_min_io_size == 0);

ubi->max_write_size = ubi->mtd->writebufsize;
/*
* Maximum write size has to be greater or equivalent to min. I/O
* size, and be multiple of min. I/O size.
*/
if (ubi->max_write_size < ubi->min_io_size ||
ubi->max_write_size % ubi->min_io_size ||
!is_power_of_2(ubi->max_write_size)) {
ubi_err("bad write buffer size %d for %d min. I/O unit",
ubi->max_write_size, ubi->min_io_size);
return -EINVAL;
}

/* Calculate default aligned sizes of EC and VID headers */
ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);

dbg_msg("min_io_size %d", ubi->min_io_size);
dbg_msg("max_write_size %d", ubi->max_write_size);
dbg_msg("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
dbg_msg("ec_hdr_alsize %d", ubi->ec_hdr_alsize);
dbg_msg("vid_hdr_alsize %d", ubi->vid_hdr_alsize);
Expand Down
2 changes: 2 additions & 0 deletions drivers/mtd/ubi/kapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di)
{
di->ubi_num = ubi->ubi_num;
di->leb_size = ubi->leb_size;
di->leb_start = ubi->leb_start;
di->min_io_size = ubi->min_io_size;
di->max_write_size = ubi->max_write_size;
di->ro_mode = ubi->ro_mode;
di->cdev = ubi->cdev.dev;
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/mtd/ubi/ubi.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ struct ubi_wl_entry;
* @bad_allowed: whether the MTD device admits of bad physical eraseblocks or
* not
* @nor_flash: non-zero if working on top of NOR flash
* @max_write_size: maximum amount of bytes the underlying flash can write at a
* time (MTD write buffer size)
* @mtd: MTD device descriptor
*
* @peb_buf1: a buffer of PEB size used for different purposes
Expand Down Expand Up @@ -463,6 +465,7 @@ struct ubi_device {
int vid_hdr_shift;
unsigned int bad_allowed:1;
unsigned int nor_flash:1;
int max_write_size;
struct mtd_info *mtd;

void *peb_buf1;
Expand Down
23 changes: 10 additions & 13 deletions fs/ubifs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,20 @@ config UBIFS_FS_ZLIB

# Debugging-related stuff
config UBIFS_FS_DEBUG
bool "Enable debugging"
bool "Enable debugging support"
depends on UBIFS_FS
select DEBUG_FS
select KALLSYMS_ALL
help
This option enables UBIFS debugging.

config UBIFS_FS_DEBUG_MSG_LVL
int "Default message level (0 = no extra messages, 3 = lots)"
depends on UBIFS_FS_DEBUG
default "0"
help
This controls the amount of debugging messages produced by UBIFS.
If reporting bugs, please try to have available a full dump of the
messages at level 1 while the misbehaviour was occurring. Level 2
may become necessary if level 1 messages were not enough to find the
bug. Generally Level 3 should be avoided.
This option enables UBIFS debugging support. It makes sure various
assertions, self-checks, debugging messages and test modes are compiled
in (this all is compiled out otherwise). Assertions are light-weight
and this option also enables them. Self-checks, debugging messages and
test modes are switched off by default. Thus, it is safe and actually
recommended to have debugging support enabled, and it should not slow
down UBIFS. You can then further enable / disable individual debugging
features using UBIFS module parameters and the corresponding sysfs
interfaces.

config UBIFS_FS_DEBUG_CHKS
bool "Enable extra checks"
Expand Down
58 changes: 57 additions & 1 deletion fs/ubifs/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,56 @@
#include <linux/slab.h>
#include "ubifs.h"

/*
* nothing_to_commit - check if there is nothing to commit.
* @c: UBIFS file-system description object
*
* This is a helper function which checks if there is anything to commit. It is
* used as an optimization to avoid starting the commit if it is not really
* necessary. Indeed, the commit operation always assumes flash I/O (e.g.,
* writing the commit start node to the log), and it is better to avoid doing
* this unnecessarily. E.g., 'ubifs_sync_fs()' runs the commit, but if there is
* nothing to commit, it is more optimal to avoid any flash I/O.
*
* This function has to be called with @c->commit_sem locked for writing -
* this function does not take LPT/TNC locks because the @c->commit_sem
* guarantees that we have exclusive access to the TNC and LPT data structures.
*
* This function returns %1 if there is nothing to commit and %0 otherwise.
*/
static int nothing_to_commit(struct ubifs_info *c)
{
/*
* During mounting or remounting from R/O mode to R/W mode we may
* commit for various recovery-related reasons.
*/
if (c->mounting || c->remounting_rw)
return 0;

/*
* If the root TNC node is dirty, we definitely have something to
* commit.
*/
if (c->zroot.znode && test_bit(DIRTY_ZNODE, &c->zroot.znode->flags))
return 0;

/*
* Even though the TNC is clean, the LPT tree may have dirty nodes. For
* example, this may happen if the budgeting subsystem invoked GC to
* make some free space, and the GC found an LEB with only dirty and
* free space. In this case GC would just change the lprops of this
* LEB (by turning all space into free space) and unmap it.
*/
if (c->nroot && test_bit(DIRTY_CNODE, &c->nroot->flags))
return 0;

ubifs_assert(atomic_long_read(&c->dirty_zn_cnt) == 0);
ubifs_assert(c->dirty_pn_cnt == 0);
ubifs_assert(c->dirty_nn_cnt == 0);

return 1;
}

/**
* do_commit - commit the journal.
* @c: UBIFS file-system description object
Expand All @@ -70,6 +120,12 @@ static int do_commit(struct ubifs_info *c)
goto out_up;
}

if (nothing_to_commit(c)) {
up_write(&c->commit_sem);
err = 0;
goto out_cancel;
}

/* Sync all write buffers (necessary for recovery) */
for (i = 0; i < c->jhead_cnt; i++) {
err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
Expand Down Expand Up @@ -162,12 +218,12 @@ static int do_commit(struct ubifs_info *c)
if (err)
goto out;

out_cancel:
spin_lock(&c->cs_lock);
c->cmt_state = COMMIT_RESTING;
wake_up(&c->cmt_wq);
dbg_cmt("commit end");
spin_unlock(&c->cs_lock);

return 0;

out_up:
Expand Down
34 changes: 18 additions & 16 deletions fs/ubifs/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ DEFINE_SPINLOCK(dbg_lock);
static char dbg_key_buf0[128];
static char dbg_key_buf1[128];

unsigned int ubifs_msg_flags = UBIFS_MSG_FLAGS_DEFAULT;
unsigned int ubifs_chk_flags = UBIFS_CHK_FLAGS_DEFAULT;
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);
Expand Down Expand Up @@ -810,16 +810,24 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
{
struct ubifs_scan_leb *sleb;
struct ubifs_scan_node *snod;
void *buf;

if (dbg_failure_mode)
return;

printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
current->pid, lnum);
sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0);

buf = __vmalloc(c->leb_size, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL);
if (!buf) {
ubifs_err("cannot allocate memory for dumping LEB %d", lnum);
return;
}

sleb = ubifs_scan(c, lnum, 0, buf, 0);
if (IS_ERR(sleb)) {
ubifs_err("scan error %d", (int)PTR_ERR(sleb));
return;
goto out;
}

printk(KERN_DEBUG "LEB %d has %d nodes ending at %d\n", lnum,
Expand All @@ -835,6 +843,9 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
printk(KERN_DEBUG "(pid %d) finish dumping LEB %d\n",
current->pid, lnum);
ubifs_scan_destroy(sleb);

out:
vfree(buf);
return;
}

Expand Down Expand Up @@ -2690,16 +2701,8 @@ int ubifs_debugging_init(struct ubifs_info *c)
if (!c->dbg)
return -ENOMEM;

c->dbg->buf = vmalloc(c->leb_size);
if (!c->dbg->buf)
goto out;

failure_mode_init(c);
return 0;

out:
kfree(c->dbg);
return -ENOMEM;
}

/**
Expand All @@ -2709,7 +2712,6 @@ int ubifs_debugging_init(struct ubifs_info *c)
void ubifs_debugging_exit(struct ubifs_info *c)
{
failure_mode_exit(c);
vfree(c->dbg->buf);
kfree(c->dbg);
}

Expand Down Expand Up @@ -2813,19 +2815,19 @@ int dbg_debugfs_init_fs(struct ubifs_info *c)
}

fname = "dump_lprops";
dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
if (IS_ERR(dent))
goto out_remove;
d->dfs_dump_lprops = dent;

fname = "dump_budg";
dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
if (IS_ERR(dent))
goto out_remove;
d->dfs_dump_budg = dent;

fname = "dump_tnc";
dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
if (IS_ERR(dent))
goto out_remove;
d->dfs_dump_tnc = dent;
Expand Down
30 changes: 3 additions & 27 deletions fs/ubifs/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

/**
* ubifs_debug_info - per-FS debugging information.
* @buf: a buffer of LEB size, used for various purposes
* @old_zroot: old index root - used by 'dbg_check_old_index()'
* @old_zroot_level: old index root level - used by 'dbg_check_old_index()'
* @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()'
Expand All @@ -54,7 +53,6 @@
* dfs_dump_tnc: "dump TNC" debugfs knob
*/
struct ubifs_debug_info {
void *buf;
struct ubifs_zbranch old_zroot;
int old_zroot_level;
unsigned long long old_zroot_sqnum;
Expand Down Expand Up @@ -173,7 +171,7 @@ const char *dbg_key_str1(const struct ubifs_info *c,
#define dbg_rcvry(fmt, ...) dbg_do_msg(UBIFS_MSG_RCVRY, fmt, ##__VA_ARGS__)

/*
* Debugging message type flags (must match msg_type_names in debug.c).
* Debugging message type flags.
*
* UBIFS_MSG_GEN: general messages
* UBIFS_MSG_JNL: journal messages
Expand Down Expand Up @@ -205,14 +203,8 @@ enum {
UBIFS_MSG_RCVRY = 0x1000,
};

/* Debugging message type flags for each default debug message level */
#define UBIFS_MSG_LVL_0 0
#define UBIFS_MSG_LVL_1 0x1
#define UBIFS_MSG_LVL_2 0x7f
#define UBIFS_MSG_LVL_3 0xffff

/*
* Debugging check flags (must match chk_names in debug.c).
* Debugging check flags.
*
* UBIFS_CHK_GEN: general checks
* UBIFS_CHK_TNC: check TNC
Expand All @@ -233,7 +225,7 @@ enum {
};

/*
* Special testing flags (must match tst_names in debug.c).
* Special testing flags.
*
* UBIFS_TST_FORCE_IN_THE_GAPS: force the use of in-the-gaps method
* UBIFS_TST_RCVRY: failure mode for recovery testing
Expand All @@ -243,22 +235,6 @@ enum {
UBIFS_TST_RCVRY = 0x4,
};

#if CONFIG_UBIFS_FS_DEBUG_MSG_LVL == 1
#define UBIFS_MSG_FLAGS_DEFAULT UBIFS_MSG_LVL_1
#elif CONFIG_UBIFS_FS_DEBUG_MSG_LVL == 2
#define UBIFS_MSG_FLAGS_DEFAULT UBIFS_MSG_LVL_2
#elif CONFIG_UBIFS_FS_DEBUG_MSG_LVL == 3
#define UBIFS_MSG_FLAGS_DEFAULT UBIFS_MSG_LVL_3
#else
#define UBIFS_MSG_FLAGS_DEFAULT UBIFS_MSG_LVL_0
#endif

#ifdef CONFIG_UBIFS_FS_DEBUG_CHKS
#define UBIFS_CHK_FLAGS_DEFAULT 0xffffffff
#else
#define UBIFS_CHK_FLAGS_DEFAULT 0
#endif

extern spinlock_t dbg_lock;

extern unsigned int ubifs_msg_flags;
Expand Down
Loading

0 comments on commit 8f627a8

Please sign in to comment.