Merge branch 'for-linus' of git://git.infradead.org/ubifs-2.6
* 'for-linus' of git://git.infradead.org/ubifs-2.6: UBI: do not select KALLSYMS_ALL UBI: do not compare array with NULL UBI: check if we are in RO mode in the erase routine UBIFS: fix debugging failure in dbg_check_space_info UBIFS: fix error path in dbg_debugfs_init_fs UBIFS: unify error path dbg_debugfs_init_fs UBIFS: do not select KALLSYMS_ALL UBIFS: fix assertion warnings UBIFS: fix oops on error path in read_pnode UBIFS: do not read flash unnecessarily
This commit is contained in:
commit
ccfeef0ff7
|
@ -56,7 +56,7 @@ config MTD_UBI_DEBUG
|
||||||
bool "UBI debugging"
|
bool "UBI debugging"
|
||||||
depends on SYSFS
|
depends on SYSFS
|
||||||
select DEBUG_FS
|
select DEBUG_FS
|
||||||
select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL
|
select KALLSYMS
|
||||||
help
|
help
|
||||||
This option enables UBI debugging.
|
This option enables UBI debugging.
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,12 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum)
|
||||||
wait_queue_head_t wq;
|
wait_queue_head_t wq;
|
||||||
|
|
||||||
dbg_io("erase PEB %d", pnum);
|
dbg_io("erase PEB %d", pnum);
|
||||||
|
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
|
||||||
|
|
||||||
|
if (ubi->ro_mode) {
|
||||||
|
ubi_err("read-only mode");
|
||||||
|
return -EROFS;
|
||||||
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
init_waitqueue_head(&wq);
|
init_waitqueue_head(&wq);
|
||||||
|
@ -390,7 +396,7 @@ retry:
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (ubi_dbg_is_erase_failure() && !err) {
|
if (ubi_dbg_is_erase_failure()) {
|
||||||
dbg_err("cannot erase PEB %d (emulated)", pnum);
|
dbg_err("cannot erase PEB %d (emulated)", pnum);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
|
@ -790,11 +790,6 @@ static int paranoid_check_volume(struct ubi_device *ubi, int vol_id)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vol->name) {
|
|
||||||
ubi_err("NULL volume name");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = strnlen(vol->name, vol->name_len + 1);
|
n = strnlen(vol->name, vol->name_len + 1);
|
||||||
if (n != vol->name_len) {
|
if (n != vol->name_len) {
|
||||||
ubi_err("bad name_len %lld", n);
|
ubi_err("bad name_len %lld", n);
|
||||||
|
|
|
@ -47,7 +47,7 @@ config UBIFS_FS_DEBUG
|
||||||
bool "Enable debugging support"
|
bool "Enable debugging support"
|
||||||
depends on UBIFS_FS
|
depends on UBIFS_FS
|
||||||
select DEBUG_FS
|
select DEBUG_FS
|
||||||
select KALLSYMS_ALL
|
select KALLSYMS
|
||||||
help
|
help
|
||||||
This option enables UBIFS debugging support. It makes sure various
|
This option enables UBIFS debugging support. It makes sure various
|
||||||
assertions, self-checks, debugging messages and test modes are compiled
|
assertions, self-checks, debugging messages and test modes are compiled
|
||||||
|
|
|
@ -577,7 +577,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX))
|
if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX))
|
||||||
goto out;
|
return 0;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&list);
|
INIT_LIST_HEAD(&list);
|
||||||
|
|
||||||
|
|
|
@ -972,11 +972,39 @@ void dbg_dump_index(struct ubifs_info *c)
|
||||||
void dbg_save_space_info(struct ubifs_info *c)
|
void dbg_save_space_info(struct ubifs_info *c)
|
||||||
{
|
{
|
||||||
struct ubifs_debug_info *d = c->dbg;
|
struct ubifs_debug_info *d = c->dbg;
|
||||||
|
int freeable_cnt;
|
||||||
ubifs_get_lp_stats(c, &d->saved_lst);
|
|
||||||
|
|
||||||
spin_lock(&c->space_lock);
|
spin_lock(&c->space_lock);
|
||||||
|
memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use a dirty hack here and zero out @c->freeable_cnt, because it
|
||||||
|
* affects the free space calculations, and UBIFS might not know about
|
||||||
|
* all freeable eraseblocks. Indeed, we know about freeable eraseblocks
|
||||||
|
* only when we read their lprops, and we do this only lazily, upon the
|
||||||
|
* need. So at any given point of time @c->freeable_cnt might be not
|
||||||
|
* exactly accurate.
|
||||||
|
*
|
||||||
|
* Just one example about the issue we hit when we did not zero
|
||||||
|
* @c->freeable_cnt.
|
||||||
|
* 1. The file-system is mounted R/O, c->freeable_cnt is %0. We save the
|
||||||
|
* amount of free space in @d->saved_free
|
||||||
|
* 2. We re-mount R/W, which makes UBIFS to read the "lsave"
|
||||||
|
* information from flash, where we cache LEBs from various
|
||||||
|
* categories ('ubifs_remount_fs()' -> 'ubifs_lpt_init()'
|
||||||
|
* -> 'lpt_init_wr()' -> 'read_lsave()' -> 'ubifs_lpt_lookup()'
|
||||||
|
* -> 'ubifs_get_pnode()' -> 'update_cats()'
|
||||||
|
* -> 'ubifs_add_to_cat()').
|
||||||
|
* 3. Lsave contains a freeable eraseblock, and @c->freeable_cnt
|
||||||
|
* becomes %1.
|
||||||
|
* 4. We calculate the amount of free space when the re-mount is
|
||||||
|
* finished in 'dbg_check_space_info()' and it does not match
|
||||||
|
* @d->saved_free.
|
||||||
|
*/
|
||||||
|
freeable_cnt = c->freeable_cnt;
|
||||||
|
c->freeable_cnt = 0;
|
||||||
d->saved_free = ubifs_get_free_space_nolock(c);
|
d->saved_free = ubifs_get_free_space_nolock(c);
|
||||||
|
c->freeable_cnt = freeable_cnt;
|
||||||
spin_unlock(&c->space_lock);
|
spin_unlock(&c->space_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,12 +1021,15 @@ int dbg_check_space_info(struct ubifs_info *c)
|
||||||
{
|
{
|
||||||
struct ubifs_debug_info *d = c->dbg;
|
struct ubifs_debug_info *d = c->dbg;
|
||||||
struct ubifs_lp_stats lst;
|
struct ubifs_lp_stats lst;
|
||||||
long long avail, free;
|
long long free;
|
||||||
|
int freeable_cnt;
|
||||||
|
|
||||||
spin_lock(&c->space_lock);
|
spin_lock(&c->space_lock);
|
||||||
avail = ubifs_calc_available(c, c->min_idx_lebs);
|
freeable_cnt = c->freeable_cnt;
|
||||||
|
c->freeable_cnt = 0;
|
||||||
|
free = ubifs_get_free_space_nolock(c);
|
||||||
|
c->freeable_cnt = freeable_cnt;
|
||||||
spin_unlock(&c->space_lock);
|
spin_unlock(&c->space_lock);
|
||||||
free = ubifs_get_free_space(c);
|
|
||||||
|
|
||||||
if (free != d->saved_free) {
|
if (free != d->saved_free) {
|
||||||
ubifs_err("free space changed from %lld to %lld",
|
ubifs_err("free space changed from %lld to %lld",
|
||||||
|
@ -2806,40 +2837,38 @@ int dbg_debugfs_init_fs(struct ubifs_info *c)
|
||||||
struct ubifs_debug_info *d = c->dbg;
|
struct ubifs_debug_info *d = c->dbg;
|
||||||
|
|
||||||
sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id);
|
sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id);
|
||||||
d->dfs_dir = debugfs_create_dir(d->dfs_dir_name, dfs_rootdir);
|
fname = d->dfs_dir_name;
|
||||||
if (IS_ERR(d->dfs_dir)) {
|
dent = debugfs_create_dir(fname, dfs_rootdir);
|
||||||
err = PTR_ERR(d->dfs_dir);
|
if (IS_ERR_OR_NULL(dent))
|
||||||
ubifs_err("cannot create \"%s\" debugfs directory, error %d\n",
|
|
||||||
d->dfs_dir_name, err);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
d->dfs_dir = dent;
|
||||||
|
|
||||||
fname = "dump_lprops";
|
fname = "dump_lprops";
|
||||||
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
|
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
|
||||||
if (IS_ERR(dent))
|
if (IS_ERR_OR_NULL(dent))
|
||||||
goto out_remove;
|
goto out_remove;
|
||||||
d->dfs_dump_lprops = dent;
|
d->dfs_dump_lprops = dent;
|
||||||
|
|
||||||
fname = "dump_budg";
|
fname = "dump_budg";
|
||||||
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
|
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
|
||||||
if (IS_ERR(dent))
|
if (IS_ERR_OR_NULL(dent))
|
||||||
goto out_remove;
|
goto out_remove;
|
||||||
d->dfs_dump_budg = dent;
|
d->dfs_dump_budg = dent;
|
||||||
|
|
||||||
fname = "dump_tnc";
|
fname = "dump_tnc";
|
||||||
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
|
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, c, &dfs_fops);
|
||||||
if (IS_ERR(dent))
|
if (IS_ERR_OR_NULL(dent))
|
||||||
goto out_remove;
|
goto out_remove;
|
||||||
d->dfs_dump_tnc = dent;
|
d->dfs_dump_tnc = dent;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_remove:
|
out_remove:
|
||||||
err = PTR_ERR(dent);
|
|
||||||
ubifs_err("cannot create \"%s\" debugfs directory, error %d\n",
|
|
||||||
fname, err);
|
|
||||||
debugfs_remove_recursive(d->dfs_dir);
|
debugfs_remove_recursive(d->dfs_dir);
|
||||||
out:
|
out:
|
||||||
|
err = dent ? PTR_ERR(dent) : -ENODEV;
|
||||||
|
ubifs_err("cannot create \"%s\" debugfs directory, error %d\n",
|
||||||
|
fname, err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1270,10 +1270,9 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
|
||||||
lnum = branch->lnum;
|
lnum = branch->lnum;
|
||||||
offs = branch->offs;
|
offs = branch->offs;
|
||||||
pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_NOFS);
|
pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_NOFS);
|
||||||
if (!pnode) {
|
if (!pnode)
|
||||||
err = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (lnum == 0) {
|
if (lnum == 0) {
|
||||||
/*
|
/*
|
||||||
* This pnode was not written which just means that the LEB
|
* This pnode was not written which just means that the LEB
|
||||||
|
|
|
@ -1568,6 +1568,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
|
||||||
mutex_lock(&c->umount_mutex);
|
mutex_lock(&c->umount_mutex);
|
||||||
dbg_save_space_info(c);
|
dbg_save_space_info(c);
|
||||||
c->remounting_rw = 1;
|
c->remounting_rw = 1;
|
||||||
|
c->ro_mount = 0;
|
||||||
|
|
||||||
err = check_free_space(c);
|
err = check_free_space(c);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -1676,13 +1677,13 @@ static int ubifs_remount_rw(struct ubifs_info *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_gen("re-mounted read-write");
|
dbg_gen("re-mounted read-write");
|
||||||
c->ro_mount = 0;
|
|
||||||
c->remounting_rw = 0;
|
c->remounting_rw = 0;
|
||||||
err = dbg_check_space_info(c);
|
err = dbg_check_space_info(c);
|
||||||
mutex_unlock(&c->umount_mutex);
|
mutex_unlock(&c->umount_mutex);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
c->ro_mount = 1;
|
||||||
vfree(c->orph_buf);
|
vfree(c->orph_buf);
|
||||||
c->orph_buf = NULL;
|
c->orph_buf = NULL;
|
||||||
if (c->bgt) {
|
if (c->bgt) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user