Commit d6138969 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'upstream-4.1-rc1' of git://git.infradead.org/linux-ubifs

Pull UBI/UBIFS updates from Richard Weinberger:
 "This pull request includes the following UBI/UBIFS changes:

   - powercut emulation for UBI
   - a huge update to UBI Fastmap
   - cleanups and bugfixes all over UBI and UBIFS"

* tag 'upstream-4.1-rc1' of git://git.infradead.org/linux-ubifs: (50 commits)
  UBI: power cut emulation for testing
  UBIFS: fix output format of INUM_WATERMARK
  UBI: Fastmap: Fall back to scanning mode after ECC error
  UBI: Fastmap: Remove is_fm_block()
  UBI: Fastmap: Add blank line after declarations
  UBI: Fastmap: Remove else after return.
  UBI: Fastmap: Introduce may_reserve_for_fm()
  UBI: Fastmap: Introduce ubi_fastmap_init()
  UBI: Fastmap: Wire up WL accessor functions
  UBI: Add accessor functions for WL data structures
  UBI: Move fastmap specific functions out of wl.c
  UBI: Fastmap: Add new module parameter fm_debug
  UBI: Fastmap: Make self_check_eba() depend on fastmap self checking
  UBI: Fastmap: Add self check to detect absent PEBs
  UBI: Fix stale pointers in ubi->lookuptbl
  UBI: Fastmap: Enhance fastmap checking
  UBI: Add initial support for fastmap self checks
  UBI: Fastmap: Rework fastmap error paths
  UBI: Fastmap: Prepare for variable sized fastmaps
  UBI: Fastmap: Locking updates
  ...
parents fa927894 50269067
...@@ -410,7 +410,7 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, ...@@ -410,7 +410,7 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
second_is_newer = !second_is_newer; second_is_newer = !second_is_newer;
} else { } else {
dbg_bld("PEB %d CRC is OK", pnum); dbg_bld("PEB %d CRC is OK", pnum);
bitflips = !!err; bitflips |= !!err;
} }
mutex_unlock(&ubi->buf_mutex); mutex_unlock(&ubi->buf_mutex);
...@@ -1301,6 +1301,30 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -1301,6 +1301,30 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
return err; return err;
} }
static struct ubi_attach_info *alloc_ai(void)
{
struct ubi_attach_info *ai;
ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
if (!ai)
return ai;
INIT_LIST_HEAD(&ai->corr);
INIT_LIST_HEAD(&ai->free);
INIT_LIST_HEAD(&ai->erase);
INIT_LIST_HEAD(&ai->alien);
ai->volumes = RB_ROOT;
ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache",
sizeof(struct ubi_ainf_peb),
0, 0, NULL);
if (!ai->aeb_slab_cache) {
kfree(ai);
ai = NULL;
}
return ai;
}
#ifdef CONFIG_MTD_UBI_FASTMAP #ifdef CONFIG_MTD_UBI_FASTMAP
/** /**
...@@ -1313,7 +1337,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -1313,7 +1337,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
* UBI_NO_FASTMAP denotes that no fastmap was found. * UBI_NO_FASTMAP denotes that no fastmap was found.
* UBI_BAD_FASTMAP denotes that the found fastmap was invalid. * UBI_BAD_FASTMAP denotes that the found fastmap was invalid.
*/ */
static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai)
{ {
int err, pnum, fm_anchor = -1; int err, pnum, fm_anchor = -1;
unsigned long long max_sqnum = 0; unsigned long long max_sqnum = 0;
...@@ -1334,7 +1358,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1334,7 +1358,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
cond_resched(); cond_resched();
dbg_gen("process PEB %d", pnum); dbg_gen("process PEB %d", pnum);
err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum); err = scan_peb(ubi, *ai, pnum, &vol_id, &sqnum);
if (err < 0) if (err < 0)
goto out_vidh; goto out_vidh;
...@@ -1350,7 +1374,12 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1350,7 +1374,12 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
if (fm_anchor < 0) if (fm_anchor < 0)
return UBI_NO_FASTMAP; return UBI_NO_FASTMAP;
return ubi_scan_fastmap(ubi, ai, fm_anchor); destroy_ai(*ai);
*ai = alloc_ai();
if (!*ai)
return -ENOMEM;
return ubi_scan_fastmap(ubi, *ai, fm_anchor);
out_vidh: out_vidh:
ubi_free_vid_hdr(ubi, vidh); ubi_free_vid_hdr(ubi, vidh);
...@@ -1362,30 +1391,6 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1362,30 +1391,6 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
#endif #endif
static struct ubi_attach_info *alloc_ai(const char *slab_name)
{
struct ubi_attach_info *ai;
ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
if (!ai)
return ai;
INIT_LIST_HEAD(&ai->corr);
INIT_LIST_HEAD(&ai->free);
INIT_LIST_HEAD(&ai->erase);
INIT_LIST_HEAD(&ai->alien);
ai->volumes = RB_ROOT;
ai->aeb_slab_cache = kmem_cache_create(slab_name,
sizeof(struct ubi_ainf_peb),
0, 0, NULL);
if (!ai->aeb_slab_cache) {
kfree(ai);
ai = NULL;
}
return ai;
}
/** /**
* ubi_attach - attach an MTD device. * ubi_attach - attach an MTD device.
* @ubi: UBI device descriptor * @ubi: UBI device descriptor
...@@ -1399,7 +1404,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) ...@@ -1399,7 +1404,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
int err; int err;
struct ubi_attach_info *ai; struct ubi_attach_info *ai;
ai = alloc_ai("ubi_aeb_slab_cache"); ai = alloc_ai();
if (!ai) if (!ai)
return -ENOMEM; return -ENOMEM;
...@@ -1413,11 +1418,11 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) ...@@ -1413,11 +1418,11 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
if (force_scan) if (force_scan)
err = scan_all(ubi, ai, 0); err = scan_all(ubi, ai, 0);
else { else {
err = scan_fast(ubi, ai); err = scan_fast(ubi, &ai);
if (err > 0) { if (err > 0 || mtd_is_eccerr(err)) {
if (err != UBI_NO_FASTMAP) { if (err != UBI_NO_FASTMAP) {
destroy_ai(ai); destroy_ai(ai);
ai = alloc_ai("ubi_aeb_slab_cache2"); ai = alloc_ai();
if (!ai) if (!ai)
return -ENOMEM; return -ENOMEM;
...@@ -1453,10 +1458,10 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) ...@@ -1453,10 +1458,10 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
goto out_wl; goto out_wl;
#ifdef CONFIG_MTD_UBI_FASTMAP #ifdef CONFIG_MTD_UBI_FASTMAP
if (ubi->fm && ubi_dbg_chk_gen(ubi)) { if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) {
struct ubi_attach_info *scan_ai; struct ubi_attach_info *scan_ai;
scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache"); scan_ai = alloc_ai();
if (!scan_ai) { if (!scan_ai) {
err = -ENOMEM; err = -ENOMEM;
goto out_wl; goto out_wl;
......
...@@ -81,6 +81,7 @@ static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES]; ...@@ -81,6 +81,7 @@ static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES];
#ifdef CONFIG_MTD_UBI_FASTMAP #ifdef CONFIG_MTD_UBI_FASTMAP
/* UBI module parameter to enable fastmap automatically on non-fastmap images */ /* UBI module parameter to enable fastmap automatically on non-fastmap images */
static bool fm_autoconvert; static bool fm_autoconvert;
static bool fm_debug;
#endif #endif
/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
struct class *ubi_class; struct class *ubi_class;
...@@ -154,23 +155,22 @@ static struct device_attribute dev_mtd_num = ...@@ -154,23 +155,22 @@ static struct device_attribute dev_mtd_num =
*/ */
int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype) int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype)
{ {
int ret;
struct ubi_notification nt; struct ubi_notification nt;
ubi_do_get_device_info(ubi, &nt.di); ubi_do_get_device_info(ubi, &nt.di);
ubi_do_get_volume_info(ubi, vol, &nt.vi); ubi_do_get_volume_info(ubi, vol, &nt.vi);
#ifdef CONFIG_MTD_UBI_FASTMAP
switch (ntype) { switch (ntype) {
case UBI_VOLUME_ADDED: case UBI_VOLUME_ADDED:
case UBI_VOLUME_REMOVED: case UBI_VOLUME_REMOVED:
case UBI_VOLUME_RESIZED: case UBI_VOLUME_RESIZED:
case UBI_VOLUME_RENAMED: case UBI_VOLUME_RENAMED:
if (ubi_update_fastmap(ubi)) { ret = ubi_update_fastmap(ubi);
ubi_err(ubi, "Unable to update fastmap!"); if (ret)
ubi_ro_mode(ubi); ubi_msg(ubi, "Unable to write a new fastmap: %i", ret);
}
} }
#endif
return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt); return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt);
} }
...@@ -950,8 +950,10 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ...@@ -950,8 +950,10 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE) if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE)
ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE; ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE;
ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE; ubi->fm_wl_pool.max_size = ubi->fm_pool.max_size / 2;
ubi->fm_disabled = !fm_autoconvert; ubi->fm_disabled = !fm_autoconvert;
if (fm_debug)
ubi_enable_dbg_chk_fastmap(ubi);
if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd)
<= UBI_FM_MAX_START) { <= UBI_FM_MAX_START) {
...@@ -970,8 +972,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ...@@ -970,8 +972,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
mutex_init(&ubi->ckvol_mutex); mutex_init(&ubi->ckvol_mutex);
mutex_init(&ubi->device_mutex); mutex_init(&ubi->device_mutex);
spin_lock_init(&ubi->volumes_lock); spin_lock_init(&ubi->volumes_lock);
mutex_init(&ubi->fm_mutex); init_rwsem(&ubi->fm_protect);
init_rwsem(&ubi->fm_sem); init_rwsem(&ubi->fm_eba_sem);
ubi_msg(ubi, "attaching mtd%d", mtd->index); ubi_msg(ubi, "attaching mtd%d", mtd->index);
...@@ -1115,8 +1117,11 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ...@@ -1115,8 +1117,11 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
ubi_msg(ubi, "detaching mtd%d", ubi->mtd->index); ubi_msg(ubi, "detaching mtd%d", ubi->mtd->index);
#ifdef CONFIG_MTD_UBI_FASTMAP #ifdef CONFIG_MTD_UBI_FASTMAP
/* If we don't write a new fastmap at detach time we lose all /* If we don't write a new fastmap at detach time we lose all
* EC updates that have been made since the last written fastmap. */ * EC updates that have been made since the last written fastmap.
ubi_update_fastmap(ubi); * In case of fastmap debugging we omit the update to simulate an
* unclean shutdown. */
if (!ubi_dbg_chk_fastmap(ubi))
ubi_update_fastmap(ubi);
#endif #endif
/* /*
* Before freeing anything, we have to stop the background thread to * Before freeing anything, we have to stop the background thread to
...@@ -1501,6 +1506,8 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa ...@@ -1501,6 +1506,8 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa
#ifdef CONFIG_MTD_UBI_FASTMAP #ifdef CONFIG_MTD_UBI_FASTMAP
module_param(fm_autoconvert, bool, 0644); module_param(fm_autoconvert, bool, 0644);
MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap.");
module_param(fm_debug, bool, 0);
MODULE_PARM_DESC(fm_debug, "Set this parameter to enable fastmap debugging by default. Warning, this will make fastmap slow!");
#endif #endif
MODULE_VERSION(__stringify(UBI_VERSION)); MODULE_VERSION(__stringify(UBI_VERSION));
MODULE_DESCRIPTION("UBI - Unsorted Block Images"); MODULE_DESCRIPTION("UBI - Unsorted Block Images");
......
...@@ -455,7 +455,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, ...@@ -455,7 +455,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
/* Validate the request */ /* Validate the request */
err = -EINVAL; err = -EINVAL;
if (req.lnum < 0 || req.lnum >= vol->reserved_pebs || if (req.lnum < 0 || req.lnum >= vol->reserved_pebs ||
req.bytes < 0 || req.lnum >= vol->usable_leb_size) req.bytes < 0 || req.bytes > vol->usable_leb_size)
break; break;
err = get_exclusive(desc); err = get_exclusive(desc);
......
...@@ -263,7 +263,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf, ...@@ -263,7 +263,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
struct dentry *dent = file->f_path.dentry; struct dentry *dent = file->f_path.dentry;
struct ubi_device *ubi; struct ubi_device *ubi;
struct ubi_debug_info *d; struct ubi_debug_info *d;
char buf[3]; char buf[8];
int val; int val;
ubi = ubi_get_device(ubi_num); ubi = ubi_get_device(ubi_num);
...@@ -275,12 +275,30 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf, ...@@ -275,12 +275,30 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
val = d->chk_gen; val = d->chk_gen;
else if (dent == d->dfs_chk_io) else if (dent == d->dfs_chk_io)
val = d->chk_io; val = d->chk_io;
else if (dent == d->dfs_chk_fastmap)
val = d->chk_fastmap;
else if (dent == d->dfs_disable_bgt) else if (dent == d->dfs_disable_bgt)
val = d->disable_bgt; val = d->disable_bgt;
else if (dent == d->dfs_emulate_bitflips) else if (dent == d->dfs_emulate_bitflips)
val = d->emulate_bitflips; val = d->emulate_bitflips;
else if (dent == d->dfs_emulate_io_failures) else if (dent == d->dfs_emulate_io_failures)
val = d->emulate_io_failures; val = d->emulate_io_failures;
else if (dent == d->dfs_emulate_power_cut) {
snprintf(buf, sizeof(buf), "%u\n", d->emulate_power_cut);
count = simple_read_from_buffer(user_buf, count, ppos,
buf, strlen(buf));
goto out;
} else if (dent == d->dfs_power_cut_min) {
snprintf(buf, sizeof(buf), "%u\n", d->power_cut_min);
count = simple_read_from_buffer(user_buf, count, ppos,
buf, strlen(buf));
goto out;
} else if (dent == d->dfs_power_cut_max) {
snprintf(buf, sizeof(buf), "%u\n", d->power_cut_max);
count = simple_read_from_buffer(user_buf, count, ppos,
buf, strlen(buf));
goto out;
}
else { else {
count = -EINVAL; count = -EINVAL;
goto out; goto out;
...@@ -309,7 +327,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, ...@@ -309,7 +327,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
struct ubi_device *ubi; struct ubi_device *ubi;
struct ubi_debug_info *d; struct ubi_debug_info *d;
size_t buf_size; size_t buf_size;
char buf[8]; char buf[8] = {0};
int val; int val;
ubi = ubi_get_device(ubi_num); ubi = ubi_get_device(ubi_num);
...@@ -323,6 +341,21 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, ...@@ -323,6 +341,21 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
goto out; goto out;
} }
if (dent == d->dfs_power_cut_min) {
if (kstrtouint(buf, 0, &d->power_cut_min) != 0)
count = -EINVAL;
goto out;
} else if (dent == d->dfs_power_cut_max) {
if (kstrtouint(buf, 0, &d->power_cut_max) != 0)
count = -EINVAL;
goto out;
} else if (dent == d->dfs_emulate_power_cut) {
if (kstrtoint(buf, 0, &val) != 0)
count = -EINVAL;
d->emulate_power_cut = val;
goto out;
}
if (buf[0] == '1') if (buf[0] == '1')
val = 1; val = 1;
else if (buf[0] == '0') else if (buf[0] == '0')
...@@ -336,6 +369,8 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, ...@@ -336,6 +369,8 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
d->chk_gen = val; d->chk_gen = val;
else if (dent == d->dfs_chk_io) else if (dent == d->dfs_chk_io)
d->chk_io = val; d->chk_io = val;
else if (dent == d->dfs_chk_fastmap)
d->chk_fastmap = val;
else if (dent == d->dfs_disable_bgt) else if (dent == d->dfs_disable_bgt)
d->disable_bgt = val; d->disable_bgt = val;
else if (dent == d->dfs_emulate_bitflips) else if (dent == d->dfs_emulate_bitflips)
...@@ -406,6 +441,13 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) ...@@ -406,6 +441,13 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
goto out_remove; goto out_remove;
d->dfs_chk_io = dent; d->dfs_chk_io = dent;
fname = "chk_fastmap";
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
&dfs_fops);
if (IS_ERR_OR_NULL(dent))
goto out_remove;
d->dfs_chk_fastmap = dent;
fname = "tst_disable_bgt"; fname = "tst_disable_bgt";
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
&dfs_fops); &dfs_fops);
...@@ -427,6 +469,27 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) ...@@ -427,6 +469,27 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
goto out_remove; goto out_remove;
d->dfs_emulate_io_failures = dent; d->dfs_emulate_io_failures = dent;
fname = "tst_emulate_power_cut";
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
&dfs_fops);
if (IS_ERR_OR_NULL(dent))
goto out_remove;
d->dfs_emulate_power_cut = dent;
fname = "tst_emulate_power_cut_min";
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
&dfs_fops);
if (IS_ERR_OR_NULL(dent))
goto out_remove;
d->dfs_power_cut_min = dent;
fname = "tst_emulate_power_cut_max";
dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
&dfs_fops);
if (IS_ERR_OR_NULL(dent))
goto out_remove;
d->dfs_power_cut_max = dent;
return 0; return 0;
out_remove: out_remove:
...@@ -447,3 +510,36 @@ void ubi_debugfs_exit_dev(struct ubi_device *ubi) ...@@ -447,3 +510,36 @@ void ubi_debugfs_exit_dev(struct ubi_device *ubi)
if (IS_ENABLED(CONFIG_DEBUG_FS)) if (IS_ENABLED(CONFIG_DEBUG_FS))
debugfs_remove_recursive(ubi->dbg.dfs_dir); debugfs_remove_recursive(ubi->dbg.dfs_dir);
} }
/**
* ubi_dbg_power_cut - emulate a power cut if it is time to do so
* @ubi: UBI device description object
* @caller: Flags set to indicate from where the function is being called
*
* Returns non-zero if a power cut was emulated, zero if not.
*/
int ubi_dbg_power_cut(struct ubi_device *ubi, int caller)
{
unsigned int range;
if ((ubi->dbg.emulate_power_cut & caller) == 0)
return 0;
if (ubi->dbg.power_cut_counter == 0) {
ubi->dbg.power_cut_counter = ubi->dbg.power_cut_min;
if (ubi->dbg.power_cut_max > ubi->dbg.power_cut_min) {
range = ubi->dbg.power_cut_max - ubi->dbg.power_cut_min;
ubi->dbg.power_cut_counter += prandom_u32() % range;
}
return 0;
}
ubi->dbg.power_cut_counter--;
if (ubi->dbg.power_cut_counter)
return 0;
ubi_msg(ubi, "XXXXXXXXXXXXXXX emulating a power cut XXXXXXXXXXXXXXXX");
ubi_ro_mode(ubi);
return 1;
}
...@@ -127,4 +127,16 @@ static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi) ...@@ -127,4 +127,16 @@ static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi)
{ {
return ubi->dbg.chk_gen; return ubi->dbg.chk_gen;
} }
static inline int ubi_dbg_chk_fastmap(const struct ubi_device *ubi)
{
return ubi->dbg.chk_fastmap;
}
static inline void ubi_enable_dbg_chk_fastmap(struct ubi_device *ubi)
{
ubi->dbg.chk_fastmap = 1;
}
int ubi_dbg_power_cut(struct ubi_device *ubi, int caller);
#endif /* !__UBI_DEBUG_H__ */ #endif /* !__UBI_DEBUG_H__ */
...@@ -340,9 +340,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -340,9 +340,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum);
down_read(&ubi->fm_sem); down_read(&ubi->fm_eba_sem);
vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED;
up_read(&ubi->fm_sem); up_read(&ubi->fm_eba_sem);
err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0); err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0);
out_unlock: out_unlock:
...@@ -567,6 +567,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, ...@@ -567,6 +567,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
new_pnum = ubi_wl_get_peb(ubi); new_pnum = ubi_wl_get_peb(ubi);
if (new_pnum < 0) { if (new_pnum < 0) {
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
up_read(&ubi->fm_eba_sem);
return new_pnum; return new_pnum;
} }
...@@ -577,13 +578,16 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, ...@@ -577,13 +578,16 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
if (err && err != UBI_IO_BITFLIPS) { if (err && err != UBI_IO_BITFLIPS) {
if (err > 0) if (err > 0)
err = -EIO; err = -EIO;
up_read(&ubi->fm_eba_sem);
goto out_put; goto out_put;
} }
vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
if (err) if (err) {
up_read(&ubi->fm_eba_sem);
goto write_error; goto write_error;
}
data_size = offset + len; data_size = offset + len;
mutex_lock(&ubi->buf_mutex); mutex_lock(&ubi->buf_mutex);
...@@ -592,8 +596,10 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, ...@@ -592,8 +596,10 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
/* Read everything before the area where the write failure happened */ /* Read everything before the area where the write failure happened */
if (offset > 0) { if (offset > 0) {
err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, offset); err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, offset);
if (err && err != UBI_IO_BITFLIPS) if (err && err != UBI_IO_BITFLIPS) {
up_read(&ubi->fm_eba_sem);
goto out_unlock; goto out_unlock;
}
} }
memcpy(ubi->peb_buf + offset, buf, len); memcpy(ubi->peb_buf + offset, buf, len);
...@@ -601,15 +607,15 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, ...@@ -601,15 +607,15 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size);
if (err) { if (err) {
mutex_unlock(&ubi->buf_mutex); mutex_unlock(&ubi->buf_mutex);
up_read(&ubi->fm_eba_sem);
goto write_error; goto write_error;
} }
mutex_unlock(&ubi->buf_mutex); mutex_unlock(&ubi->buf_mutex);
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = new_pnum; vol->eba_tbl[lnum] = new_pnum;
up_read(&ubi->fm_sem); up_read(&ubi->fm_eba_sem);
ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
ubi_msg(ubi, "data was successfully recovered"); ubi_msg(ubi, "data was successfully recovered");
...@@ -704,6 +710,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, ...@@ -704,6 +710,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
if (pnum < 0) { if (pnum < 0) {
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
leb_write_unlock(ubi, vol_id, lnum); leb_write_unlock(ubi, vol_id, lnum);
up_read(&ubi->fm_eba_sem);
return pnum; return pnum;
} }
...@@ -714,6 +721,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, ...@@ -714,6 +721,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
if (err) { if (err) {
ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d",
vol_id, lnum, pnum); vol_id, lnum, pnum);
up_read(&ubi->fm_eba_sem);
goto write_error; goto write_error;
} }
...@@ -722,13 +730,13 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, ...@@ -722,13 +730,13 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
if (err) { if (err) {
ubi_warn(ubi, "failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", ubi_warn(ubi, "failed to write %d bytes at offset %d of LEB %d:%d, PEB %d",
len, offset, vol_id, lnum, pnum); len, offset, vol_id, lnum, pnum);
up_read(&ubi->fm_eba_sem);
goto write_error; goto write_error;
} }
} }
down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = pnum; vol->eba_tbl[lnum] = pnum;
up_read(&ubi->fm_sem); up_read(&ubi->fm_eba_sem);
leb_write_unlock(ubi, vol_id, lnum); leb_write_unlock(ubi, vol_id, lnum);
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
...@@ -825,6 +833,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -825,6 +833,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
if (pnum < 0) { if (pnum < 0) {
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
leb_write_unlock(ubi, vol_id, lnum); leb_write_unlock(ubi, vol_id, lnum);
up_read(&ubi->fm_eba_sem);
return pnum; return pnum;
} }
...@@ -835,6 +844,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -835,6 +844,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
if (err) { if (err) {
ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d",
vol_id, lnum, pnum); vol_id, lnum, pnum);
up_read(&ubi->fm_eba_sem);
goto write_error; goto write_error;
} }
...@@ -842,13 +852,13 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -842,13 +852,13 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
if (err) { if (err) {
ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", ubi_warn(ubi, "failed to write %d bytes of data to PEB %d",
len, pnum); len, pnum);
up_read(&ubi->fm_eba_sem);
goto write_error; goto write_error;
} }
ubi_assert(vol->eba_tbl[lnum] < 0); ubi_assert(vol->eba_tbl[lnum] < 0);
down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = pnum; vol->eba_tbl[lnum] = pnum;
up_read(&ubi->fm_sem); up_read(&ubi->fm_eba_sem);
leb_write_unlock(ubi, vol_id, lnum); leb_write_unlock(ubi, vol_id, lnum);
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
...@@ -900,7 +910,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -900,7 +910,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
int lnum, const void *buf, int len) int lnum, const void *buf, int len)
{ {
int err, pnum, tries = 0, vol_id = vol->vol_id; int err, pnum, old_pnum, tries = 0, vol_id = vol->vol_id;
struct ubi_vid_hdr *vid_hdr; struct ubi_vid_hdr *vid_hdr;
uint32_t crc; uint32_t crc;
...@@ -943,6 +953,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -943,6 +953,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
pnum = ubi_wl_get_peb(ubi); pnum = ubi_wl_get_peb(ubi);
if (pnum < 0) { if (pnum < 0) {
err = pnum; err = pnum;
up_read(&ubi->fm_eba_sem);
goto out_leb_unlock; goto out_leb_unlock;
} }
...@@ -953,6 +964,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -953,6 +964,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
if (err) { if (err) {
ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d",
vol_id, lnum, pnum); vol_id, lnum, pnum);
up_read(&ubi->fm_eba_sem);
goto write_error; goto write_error;
} }
...@@ -960,19 +972,20 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -960,19 +972,20 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
if (err) { if (err) {
ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", ubi_warn(ubi, "failed to write %d bytes of data to PEB %d",
len, pnum); len, pnum);
up_read(&ubi->fm_eba_sem);
goto write_error; goto write_error;
} }
if (vol->eba_tbl[lnum] >= 0) { old_pnum = vol->eba_tbl[lnum];
err = ubi_wl_put_peb(ubi, vol_id, lnum, vol->eba_tbl[lnum], 0); vol->eba_tbl[lnum] = pnum;
up_read(&ubi->fm_eba_sem);
if (old_pnum >= 0) {
err = ubi_wl_put_peb(ubi, vol_id, lnum, old_pnum, 0);
if (err) if (err)
goto out_leb_unlock; goto out_leb_unlock;
} }
down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = pnum;
up_read(&ubi->fm_sem);
out_leb_unlock: out_leb_unlock:
leb_write_unlock(ubi, vol_id, lnum); leb_write_unlock(ubi, vol_id, lnum);
out_mutex: out_mutex:
...@@ -1218,9 +1231,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ...@@ -1218,9 +1231,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
} }
ubi_assert(vol->eba_tbl[lnum] == from); ubi_assert(vol->eba_tbl[lnum] == from);
down_read(&ubi->fm_sem); down_read(&ubi->fm_eba_sem);
vol->eba_tbl[lnum] = to; vol->eba_tbl[lnum] = to;
up_read(&ubi->fm_sem); up_read(&ubi->fm_eba_sem);
out_unlock_buf: out_unlock_buf:
mutex_unlock(&ubi->buf_mutex); mutex_unlock(&ubi->buf_mutex);
...@@ -1419,7 +1432,8 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai) ...@@ -1419,7 +1432,8 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
* during re-size. * during re-size.
*/ */
ubi_move_aeb_to_list(av, aeb, &ai->erase); ubi_move_aeb_to_list(av, aeb, &ai->erase);
vol->eba_tbl[aeb->lnum] = aeb->pnum; else
vol->eba_tbl[aeb->lnum] = aeb->pnum;
} }
} }
......
/*
* Copyright (c) 2012 Linutronix GmbH
* Copyright (c) 2014 sigma star gmbh
* Author: Richard Weinberger <richard@nod.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
*/
/**
* update_fastmap_work_fn - calls ubi_update_fastmap from a work queue
* @wrk: the work description object
*/
static void update_fastmap_work_fn(struct work_struct *wrk)
{
struct ubi_device *ubi = container_of(wrk, struct ubi_device, fm_work);
ubi_update_fastmap(ubi);
spin_lock(&ubi->wl_lock);
ubi->fm_work_scheduled = 0;
spin_unlock(&ubi->wl_lock);
}
/**
* find_anchor_wl_entry - find wear-leveling entry to used as anchor PEB.
* @root: the RB-tree where to look for
*/
static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root)
{
struct rb_node *p;
struct ubi_wl_entry *e, *victim = NULL;
int max_ec = UBI_MAX_ERASECOUNTER;
ubi_rb_for_each_entry(p, e, root, u.rb) {
if (e->pnum < UBI_FM_MAX_START && e->ec < max_ec) {
victim = e;
max_ec = e->ec;
}
}
return victim;
}
/**
* return_unused_pool_pebs - returns unused PEB to the free tree.
* @ubi: UBI device description object
* @pool: fastmap pool description object
*/
static void return_unused_pool_pebs(struct ubi_device *ubi,
struct ubi_fm_pool *pool)
{
int i;
struct ubi_wl_entry *e;
for (i = pool->used; i < pool->size; i++) {
e = ubi->lookuptbl[pool->pebs[i]];
wl_tree_add(e, &ubi->free);
ubi->free_count++;
}
}
static int anchor_pebs_avalible(struct rb_root *root)
{
struct rb_node *p;
struct ubi_wl_entry *e;
ubi_rb_for_each_entry(p, e, root, u.rb)
if (e->pnum < UBI_FM_MAX_START)
return 1;
return 0;
}
/**
* ubi_wl_get_fm_peb - find a physical erase block with a given maximal number.
* @ubi: UBI device description object
* @anchor: This PEB will be used as anchor PEB by fastmap
*
* The function returns a physical erase block with a given maximal number
* and removes it from the wl subsystem.
* Must be called with wl_lock held!
*/
struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor)
{
struct ubi_wl_entry *e = NULL;
if (!ubi->free.rb_node || (ubi->free_count - ubi->beb_rsvd_pebs < 1))
goto out;
if (anchor)
e = find_anchor_wl_entry(&ubi->free);
else
e = find_mean_wl_entry(ubi, &ubi->free);
if (!e)
goto out;
self_check_in_wl_tree(ubi, e, &ubi->free);
/* remove it from the free list,
* the wl subsystem does no longer know this erase block */
rb_erase(&e->u.rb, &ubi->free);
ubi->free_count--;
out:
return e;
}
/**
* ubi_refill_pools - refills all fastmap PEB pools.
* @ubi: UBI device description object
*/
void ubi_refill_pools(struct ubi_device *ubi)
{
struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool;
struct ubi_fm_pool *pool = &ubi->fm_pool;
struct ubi_wl_entry *e;
int enough;
spin_lock(&ubi->wl_lock);
return_unused_pool_pebs(ubi, wl_pool);
return_unused_pool_pebs(ubi, pool);
wl_pool->size = 0;
pool->size = 0;
for (;;) {
enough = 0;
if (pool->size < pool->max_size) {
if (!ubi->free.rb_node)
break;
e = wl_get_wle(ubi);
if (!e)
break;
pool->pebs[pool->size] = e->pnum;
pool->size++;
} else
enough++;
if (wl_pool->size < wl_pool->max_size) {
if (!ubi->free.rb_node ||
(ubi->free_count - ubi->beb_rsvd_pebs < 5))
break;
e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
self_check_in_wl_tree(ubi, e, &ubi->free);
rb_erase(&e->u.rb, &ubi->free);
ubi->free_count--;
wl_pool->pebs[wl_pool->size] = e->pnum;
wl_pool->size++;
} else
enough++;
if (enough == 2)
break;
}
wl_pool->used = 0;
pool->used = 0;
spin_unlock(&ubi->wl_lock);
}
/**
* ubi_wl_get_peb - get a physical eraseblock.
* @ubi: UBI device description object
*
* This function returns a physical eraseblock in case of success and a
* negative error code in case of failure.
* Returns with ubi->fm_eba_sem held in read mode!
*/
int ubi_wl_get_peb(struct ubi_device *ubi)
{
int ret, retried = 0;
struct ubi_fm_pool *pool = &ubi->fm_pool;
struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool;
again:
down_read(&ubi->fm_eba_sem);
spin_lock(&ubi->wl_lock);
/* We check here also for the WL pool because at this point we can
* refill the WL pool synchronous. */
if (pool->used == pool->size || wl_pool->used == wl_pool->size) {
spin_unlock(&ubi->wl_lock);
up_read(&ubi->fm_eba_sem);
ret = ubi_update_fastmap(ubi);
if (ret) {
ubi_msg(ubi, "Unable to write a new fastmap: %i", ret);
down_read(&ubi->fm_eba_sem);
return -ENOSPC;
}
down_read(&ubi->fm_eba_sem);
spin_lock(&ubi->wl_lock);
}
if (pool->used == pool->size) {
spin_unlock(&ubi->wl_lock);
if (retried) {
ubi_err(ubi, "Unable to get a free PEB from user WL pool");
ret = -ENOSPC;
goto out;
}
retried = 1;
up_read(&ubi->fm_eba_sem);
goto again;
}
ubi_assert(pool->used < pool->size);
ret = pool->pebs[pool->used++];
prot_queue_add(ubi, ubi->lookuptbl[ret]);
spin_unlock(&ubi->wl_lock);
out:
return ret;
}
/* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system.
*
* @ubi: UBI device description object
*/
static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
{
struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
int pnum;
if (pool->used == pool->size) {
/* We cannot update the fastmap here because this
* function is called in atomic context.
* Let's fail here and refill/update it as soon as possible. */
if (!ubi->fm_work_scheduled) {
ubi->fm_work_scheduled = 1;
schedule_work(&ubi->fm_work);
}
return NULL;
}
pnum = pool->pebs[pool->used++];
return ubi->lookuptbl[pnum];
}
/**
* ubi_ensure_anchor_pebs - schedule wear-leveling to produce an anchor PEB.
* @ubi: UBI device description object
*/
int ubi_ensure_anchor_pebs(struct ubi_device *ubi)
{
struct ubi_work *wrk;
spin_lock(&ubi->wl_lock);
if (ubi->wl_scheduled) {
spin_unlock(&ubi->wl_lock);
return 0;
}
ubi->wl_scheduled = 1;
spin_unlock(&ubi->wl_lock);
wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
if (!wrk) {
spin_lock(&ubi->wl_lock);
ubi->wl_scheduled = 0;
spin_unlock(&ubi->wl_lock);
return -ENOMEM;
}
wrk->anchor = 1;
wrk->func = &wear_leveling_worker;
schedule_ubi_work(ubi, wrk);
return 0;
}
/**
* ubi_wl_put_fm_peb - returns a PEB used in a fastmap to the wear-leveling
* sub-system.
* see: ubi_wl_put_peb()
*
* @ubi: UBI device description object
* @fm_e: physical eraseblock to return
* @lnum: the last used logical eraseblock number for the PEB
* @torture: if this physical eraseblock has to be tortured
*/
int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e,
int lnum, int torture)
{
struct ubi_wl_entry *e;
int vol_id, pnum = fm_e->pnum;
dbg_wl("PEB %d", pnum);
ubi_assert(pnum >= 0);
ubi_assert(pnum < ubi->peb_count);
spin_lock(&ubi->wl_lock);
e = ubi->lookuptbl[pnum];
/* This can happen if we recovered from a fastmap the very
* first time and writing now a new one. In this case the wl system
* has never seen any PEB used by the original fastmap.
*/
if (!e) {
e = fm_e;
ubi_assert(e->ec >= 0);
ubi->lookuptbl[pnum] = e;
}
spin_unlock(&ubi->wl_lock);
vol_id = lnum ? UBI_FM_DATA_VOLUME_ID : UBI_FM_SB_VOLUME_ID;
return schedule_erase(ubi, e, vol_id, lnum, torture);
}
/**
* ubi_is_erase_work - checks whether a work is erase work.
* @wrk: The work object to be checked
*/
int ubi_is_erase_work(struct ubi_work *wrk)
{
return wrk->func == erase_worker;
}
static void ubi_fastmap_close(struct ubi_device *ubi)
{
int i;
flush_work(&ubi->fm_work);
return_unused_pool_pebs(ubi, &ubi->fm_pool);
return_unused_pool_pebs(ubi, &ubi->fm_wl_pool);
if (ubi->fm) {
for (i = 0; i < ubi->fm->used_blocks; i++)
kfree(ubi->fm->e[i]);
}
kfree(ubi->fm);
}
/**
* may_reserve_for_fm - tests whether a PEB shall be reserved for fastmap.
* See find_mean_wl_entry()
*
* @ubi: UBI device description object
* @e: physical eraseblock to return
* @root: RB tree to test against.
*/
static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi,
struct ubi_wl_entry *e,
struct rb_root *root) {
if (e && !ubi->fm_disabled && !ubi->fm &&
e->pnum < UBI_FM_MAX_START)
e = rb_entry(rb_next(root->rb_node),
struct ubi_wl_entry, u.rb);
return e;
}
This diff is collapsed.
...@@ -859,6 +859,9 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, ...@@ -859,6 +859,9 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum,
if (err) if (err)
return err; return err;
if (ubi_dbg_power_cut(ubi, POWER_CUT_EC_WRITE))
return -EROFS;
err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize); err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize);
return err; return err;
} }
...@@ -1106,6 +1109,9 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -1106,6 +1109,9 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
if (err) if (err)
return err; return err;
if (ubi_dbg_power_cut(ubi, POWER_CUT_VID_WRITE))
return -EROFS;
p = (char *)vid_hdr - ubi->vid_hdr_shift; p = (char *)vid_hdr - ubi->vid_hdr_shift;
err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset, err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset,
ubi->vid_hdr_alsize); ubi->vid_hdr_alsize);
......
...@@ -403,8 +403,6 @@ struct ubi_vtbl_record { ...@@ -403,8 +403,6 @@ struct ubi_vtbl_record {
#define UBI_FM_MIN_POOL_SIZE 8 #define UBI_FM_MIN_POOL_SIZE 8
#define UBI_FM_MAX_POOL_SIZE 256 #define UBI_FM_MAX_POOL_SIZE 256
#define UBI_FM_WL_POOL_SIZE 25
/** /**
* struct ubi_fm_sb - UBI fastmap super block * struct ubi_fm_sb - UBI fastmap super block
* @magic: fastmap super block magic number (%UBI_FM_SB_MAGIC) * @magic: fastmap super block magic number (%UBI_FM_SB_MAGIC)
......
...@@ -151,6 +151,17 @@ enum { ...@@ -151,6 +151,17 @@ enum {
UBI_BAD_FASTMAP, UBI_BAD_FASTMAP,
}; };
/*
* Flags for emulate_power_cut in ubi_debug_info
*
* POWER_CUT_EC_WRITE: Emulate a power cut when writing an EC header
* POWER_CUT_VID_WRITE: Emulate a power cut when writing a VID header
*/
enum {
POWER_CUT_EC_WRITE = 0x01,
POWER_CUT_VID_WRITE = 0x02,
};
/** /**
* struct ubi_wl_entry - wear-leveling entry. * struct ubi_wl_entry - wear-leveling entry.
* @u.rb: link in the corresponding (free/used) RB-tree * @u.rb: link in the corresponding (free/used) RB-tree
...@@ -356,30 +367,48 @@ struct ubi_wl_entry; ...@@ -356,30 +367,48 @@ struct ubi_wl_entry;
* *
* @chk_gen: if UBI general extra checks are enabled * @chk_gen: if UBI general extra checks are enabled
* @chk_io: if UBI I/O extra checks are enabled * @chk_io: if UBI I/O extra checks are enabled
* @chk_fastmap: if UBI fastmap extra checks are enabled
* @disable_bgt: disable the background task for testing purposes * @disable_bgt: disable the background task for testing purposes
* @emulate_bitflips: emulate bit-flips for testing purposes * @emulate_bitflips: emulate bit-flips for testing purposes
* @emulate_io_failures: emulate write/erase failures for testing purposes * @emulate_io_failures: emulate write/erase failures for testing purposes
* @emulate_power_cut: emulate power cut for testing purposes
* @power_cut_counter: count down for writes left until emulated power cut
* @power_cut_min: minimum number of writes before emulating a power cut
* @power_cut_max: maximum number of writes until emulating a power cut
* @dfs_dir_name: name of debugfs directory containing files of this UBI device * @dfs_dir_name: name of debugfs directory containing files of this UBI device
* @dfs_dir: direntry object of the UBI device debugfs directory * @dfs_dir: direntry object of the UBI device debugfs directory
* @dfs_chk_gen: debugfs knob to enable UBI general extra checks * @dfs_chk_gen: debugfs knob to enable UBI general extra checks
* @dfs_chk_io: debugfs knob to enable UBI I/O extra checks * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks
* @dfs_chk_fastmap: debugfs knob to enable UBI fastmap extra checks
* @dfs_disable_bgt: debugfs knob to disable the background task * @dfs_disable_bgt: debugfs knob to disable the background task
* @dfs_emulate_bitflips: debugfs knob to emulate bit-flips * @dfs_emulate_bitflips: debugfs knob to emulate bit-flips
* @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures * @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures
* @dfs_emulate_power_cut: debugfs knob to emulate power cuts
* @dfs_power_cut_min: debugfs knob for minimum writes before power cut
* @dfs_power_cut_max: debugfs knob for maximum writes until power cut
*/ */
struct ubi_debug_info { struct ubi_debug_info {
unsigned int chk_gen:1; unsigned int chk_gen:1;
unsigned int chk_io:1; unsigned int chk_io:1;
unsigned int chk_fastmap:1;
unsigned int disable_bgt:1; unsigned int disable_bgt:1;
unsigned int emulate_bitflips:1; unsigned int emulate_bitflips:1;
unsigned int emulate_io_failures:1; unsigned int emulate_io_failures:1;
unsigned int emulate_power_cut:2;
unsigned int power_cut_counter;
unsigned int power_cut_min;
unsigned int power_cut_max;
char dfs_dir_name[UBI_DFS_DIR_LEN + 1]; char dfs_dir_name[UBI_DFS_DIR_LEN + 1];
struct dentry *dfs_dir; struct dentry *dfs_dir;
struct dentry *dfs_chk_gen; struct dentry *dfs_chk_gen;
struct dentry *dfs_chk_io; struct dentry *dfs_chk_io;
struct dentry *dfs_chk_fastmap;
struct dentry *dfs_disable_bgt; struct dentry *dfs_disable_bgt;
struct dentry *dfs_emulate_bitflips; struct dentry *dfs_emulate_bitflips;
struct dentry *dfs_emulate_io_failures; struct dentry *dfs_emulate_io_failures;
struct dentry *dfs_emulate_power_cut;
struct dentry *dfs_power_cut_min;
struct dentry *dfs_power_cut_max;
}; };
/** /**
...@@ -426,11 +455,13 @@ struct ubi_debug_info { ...@@ -426,11 +455,13 @@ struct ubi_debug_info {
* @fm_pool: in-memory data structure of the fastmap pool * @fm_pool: in-memory data structure of the fastmap pool
* @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL
* sub-system * sub-system
* @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf * @fm_protect: serializes ubi_update_fastmap(), protects @fm_buf and makes sure
* that critical sections cannot be interrupted by ubi_update_fastmap()
* @fm_buf: vmalloc()'d buffer which holds the raw fastmap * @fm_buf: vmalloc()'d buffer which holds the raw fastmap
* @fm_size: fastmap size in bytes * @fm_size: fastmap size in bytes
* @fm_sem: allows ubi_update_fastmap() to block EBA table changes * @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes
* @fm_work: fastmap work queue * @fm_work: fastmap work queue
* @fm_work_scheduled: non-zero if fastmap work was scheduled
* *
* @used: RB-tree of used physical eraseblocks * @used: RB-tree of used physical eraseblocks
* @erroneous: RB-tree of erroneous used physical eraseblocks * @erroneous: RB-tree of erroneous used physical eraseblocks
...@@ -442,7 +473,8 @@ struct ubi_debug_info { ...@@ -442,7 +473,8 @@ struct ubi_debug_info {
* @pq_head: protection queue head * @pq_head: protection queue head
* @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from, * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from,
* @move_to, @move_to_put @erase_pending, @wl_scheduled, @works, * @move_to, @move_to_put @erase_pending, @wl_scheduled, @works,
* @erroneous, and @erroneous_peb_count fields * @erroneous, @erroneous_peb_count, @fm_work_scheduled, @fm_pool,
* and @fm_wl_pool fields
* @move_mutex: serializes eraseblock moves * @move_mutex: serializes eraseblock moves
* @work_sem: used to wait for all the scheduled works to finish and prevent * @work_sem: used to wait for all the scheduled works to finish and prevent
* new works from being submitted * new works from being submitted
...@@ -479,7 +511,7 @@ struct ubi_debug_info { ...@@ -479,7 +511,7 @@ struct ubi_debug_info {
* @vid_hdr_offset: starting offset of the volume identifier header (might be * @vid_hdr_offset: starting offset of the volume identifier header (might be
* unaligned) * unaligned)
* @vid_hdr_aloffset: starting offset of the VID header aligned to * @vid_hdr_aloffset: starting offset of the VID header aligned to
* @hdrs_min_io_size * @hdrs_min_io_size
* @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset
* @bad_allowed: whether the MTD device admits of bad physical eraseblocks or * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or
* not * not
...@@ -532,11 +564,12 @@ struct ubi_device { ...@@ -532,11 +564,12 @@ struct ubi_device {
struct ubi_fastmap_layout *fm; struct ubi_fastmap_layout *fm;
struct ubi_fm_pool fm_pool; struct ubi_fm_pool fm_pool;
struct ubi_fm_pool fm_wl_pool; struct ubi_fm_pool fm_wl_pool;
struct rw_semaphore fm_sem; struct rw_semaphore fm_eba_sem;
struct mutex fm_mutex; struct rw_semaphore fm_protect;
void *fm_buf; void *fm_buf;
size_t fm_size; size_t fm_size;
struct work_struct fm_work; struct work_struct fm_work;
int fm_work_scheduled;
/* Wear-leveling sub-system's stuff */ /* Wear-leveling sub-system's stuff */
struct rb_root used; struct rb_root used;
...@@ -868,10 +901,14 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, ...@@ -868,10 +901,14 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
int pnum, const struct ubi_vid_hdr *vid_hdr); int pnum, const struct ubi_vid_hdr *vid_hdr);
/* fastmap.c */ /* fastmap.c */
#ifdef CONFIG_MTD_UBI_FASTMAP
size_t ubi_calc_fm_size(struct ubi_device *ubi); size_t ubi_calc_fm_size(struct ubi_device *ubi);
int ubi_update_fastmap(struct ubi_device *ubi); int ubi_update_fastmap(struct ubi_device *ubi);
int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
int fm_anchor); int fm_anchor);
#else
static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; }
#endif
/* block.c */ /* block.c */
#ifdef CONFIG_MTD_UBI_BLOCK #ifdef CONFIG_MTD_UBI_BLOCK
...@@ -892,6 +929,42 @@ static inline int ubiblock_remove(struct ubi_volume_info *vi) ...@@ -892,6 +929,42 @@ static inline int ubiblock_remove(struct ubi_volume_info *vi)
} }
#endif #endif
/*
* ubi_for_each_free_peb - walk the UBI free RB tree.
* @ubi: UBI device description object
* @e: a pointer to a ubi_wl_entry to use as cursor
* @pos: a pointer to RB-tree entry type to use as a loop counter
*/
#define ubi_for_each_free_peb(ubi, e, tmp_rb) \
ubi_rb_for_each_entry((tmp_rb), (e), &(ubi)->free, u.rb)
/*
* ubi_for_each_used_peb - walk the UBI used RB tree.
* @ubi: UBI device description object
* @e: a pointer to a ubi_wl_entry to use as cursor
* @pos: a pointer to RB-tree entry type to use as a loop counter
*/
#define ubi_for_each_used_peb(ubi, e, tmp_rb) \
ubi_rb_for_each_entry((tmp_rb), (e), &(ubi)->used, u.rb)
/*
* ubi_for_each_scub_peb - walk the UBI scub RB tree.
* @ubi: UBI device description object
* @e: a pointer to a ubi_wl_entry to use as cursor
* @pos: a pointer to RB-tree entry type to use as a loop counter
*/
#define ubi_for_each_scrub_peb(ubi, e, tmp_rb) \
ubi_rb_for_each_entry((tmp_rb), (e), &(ubi)->scrub, u.rb)
/*
* ubi_for_each_protected_peb - walk the UBI protection queue.
* @ubi: UBI device description object
* @i: a integer used as counter
* @e: a pointer to a ubi_wl_entry to use as cursor
*/
#define ubi_for_each_protected_peb(ubi, i, e) \
for ((i) = 0; (i) < UBI_PROT_QUEUE_LEN; (i)++) \
list_for_each_entry((e), &(ubi->pq[(i)]), u.list)
/* /*
* ubi_rb_for_each_entry - walk an RB-tree. * ubi_rb_for_each_entry - walk an RB-tree.
......
This diff is collapsed.
#ifndef UBI_WL_H
#define UBI_WL_H
#ifdef CONFIG_MTD_UBI_FASTMAP
static int anchor_pebs_avalible(struct rb_root *root);
static void update_fastmap_work_fn(struct work_struct *wrk);
static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root);
static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
static void ubi_fastmap_close(struct ubi_device *ubi);
static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count)
{
/* Reserve enough LEBs to store two fastmaps. */
*count += (ubi->fm_size / ubi->leb_size) * 2;
INIT_WORK(&ubi->fm_work, update_fastmap_work_fn);
}
static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi,
struct ubi_wl_entry *e,
struct rb_root *root);
#else /* !CONFIG_MTD_UBI_FASTMAP */
static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
static inline void ubi_fastmap_close(struct ubi_device *ubi) { }
static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count) { }
static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi,
struct ubi_wl_entry *e,
struct rb_root *root) {
return e;
}
#endif /* CONFIG_MTD_UBI_FASTMAP */
#endif /* UBI_WL_H */
...@@ -509,7 +509,7 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) ...@@ -509,7 +509,7 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
c->bi.nospace_rp = 1; c->bi.nospace_rp = 1;
smp_wmb(); smp_wmb();
} else } else
ubifs_err("cannot budget space, error %d", err); ubifs_err(c, "cannot budget space, error %d", err);
return err; return err;
} }
......
...@@ -225,7 +225,7 @@ static int do_commit(struct ubifs_info *c) ...@@ -225,7 +225,7 @@ static int do_commit(struct ubifs_info *c)
out_up: out_up:
up_write(&c->commit_sem); up_write(&c->commit_sem);
out: out:
ubifs_err("commit failed, error %d", err); ubifs_err(c, "commit failed, error %d", err);
spin_lock(&c->cs_lock); spin_lock(&c->cs_lock);
c->cmt_state = COMMIT_BROKEN; c->cmt_state = COMMIT_BROKEN;
wake_up(&c->cmt_wq); wake_up(&c->cmt_wq);
...@@ -289,7 +289,7 @@ int ubifs_bg_thread(void *info) ...@@ -289,7 +289,7 @@ int ubifs_bg_thread(void *info)
int err; int err;
struct ubifs_info *c = info; struct ubifs_info *c = info;
ubifs_msg("background thread \"%s\" started, PID %d", ubifs_msg(c, "background thread \"%s\" started, PID %d",
c->bgt_name, current->pid); c->bgt_name, current->pid);
set_freezable(); set_freezable();
...@@ -324,7 +324,7 @@ int ubifs_bg_thread(void *info) ...@@ -324,7 +324,7 @@ int ubifs_bg_thread(void *info)
cond_resched(); cond_resched();
} }
ubifs_msg("background thread \"%s\" stops", c->bgt_name); ubifs_msg(c, "background thread \"%s\" stops", c->bgt_name);
return 0; return 0;
} }
...@@ -712,13 +712,13 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) ...@@ -712,13 +712,13 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
return 0; return 0;
out_dump: out_dump:
ubifs_err("dumping index node (iip=%d)", i->iip); ubifs_err(c, "dumping index node (iip=%d)", i->iip);
ubifs_dump_node(c, idx); ubifs_dump_node(c, idx);
list_del(&i->list); list_del(&i->list);
kfree(i); kfree(i);
if (!list_empty(&list)) { if (!list_empty(&list)) {
i = list_entry(list.prev, struct idx_node, list); i = list_entry(list.prev, struct idx_node, list);
ubifs_err("dumping parent index node"); ubifs_err(c, "dumping parent index node");
ubifs_dump_node(c, &i->idx); ubifs_dump_node(c, &i->idx);
} }
out_free: out_free:
...@@ -727,7 +727,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) ...@@ -727,7 +727,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
list_del(&i->list); list_del(&i->list);
kfree(i); kfree(i);
} }
ubifs_err("failed, error %d", err); ubifs_err(c, "failed, error %d", err);
if (err > 0) if (err > 0)
err = -EINVAL; err = -EINVAL;
return err; return err;
......
...@@ -92,8 +92,8 @@ struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; ...@@ -92,8 +92,8 @@ struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
* Note, if the input buffer was not compressed, it is copied to the output * Note, if the input buffer was not compressed, it is copied to the output
* buffer and %UBIFS_COMPR_NONE is returned in @compr_type. * buffer and %UBIFS_COMPR_NONE is returned in @compr_type.
*/ */
void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, void ubifs_compress(const struct ubifs_info *c, const void *in_buf,
int *compr_type) int in_len, void *out_buf, int *out_len, int *compr_type)
{ {
int err; int err;
struct ubifs_compressor *compr = ubifs_compressors[*compr_type]; struct ubifs_compressor *compr = ubifs_compressors[*compr_type];
...@@ -112,9 +112,9 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, ...@@ -112,9 +112,9 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
if (compr->comp_mutex) if (compr->comp_mutex)
mutex_unlock(compr->comp_mutex); mutex_unlock(compr->comp_mutex);
if (unlikely(err)) { if (unlikely(err)) {
ubifs_warn("cannot compress %d bytes, compressor %s, error %d, leave data uncompressed", ubifs_warn(c, "cannot compress %d bytes, compressor %s, error %d, leave data uncompressed",
in_len, compr->name, err); in_len, compr->name, err);
goto no_compr; goto no_compr;
} }
/* /*
...@@ -144,21 +144,21 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, ...@@ -144,21 +144,21 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
* The length of the uncompressed data is returned in @out_len. This functions * The length of the uncompressed data is returned in @out_len. This functions
* returns %0 on success or a negative error code on failure. * returns %0 on success or a negative error code on failure.
*/ */
int ubifs_decompress(const void *in_buf, int in_len, void *out_buf, int ubifs_decompress(const struct ubifs_info *c, const void *in_buf,
int *out_len, int compr_type) int in_len, void *out_buf, int *out_len, int compr_type)
{ {
int err; int err;
struct ubifs_compressor *compr; struct ubifs_compressor *compr;
if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) { if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) {
ubifs_err("invalid compression type %d", compr_type); ubifs_err(c, "invalid compression type %d", compr_type);
return -EINVAL; return -EINVAL;
} }
compr = ubifs_compressors[compr_type]; compr = ubifs_compressors[compr_type];
if (unlikely(!compr->capi_name)) { if (unlikely(!compr->capi_name)) {
ubifs_err("%s compression is not compiled in", compr->name); ubifs_err(c, "%s compression is not compiled in", compr->name);
return -EINVAL; return -EINVAL;
} }
...@@ -175,7 +175,7 @@ int ubifs_decompress(const void *in_buf, int in_len, void *out_buf, ...@@ -175,7 +175,7 @@ int ubifs_decompress(const void *in_buf, int in_len, void *out_buf,
if (compr->decomp_mutex) if (compr->decomp_mutex)
mutex_unlock(compr->decomp_mutex); mutex_unlock(compr->decomp_mutex);
if (err) if (err)
ubifs_err("cannot decompress %d bytes, compressor %s, error %d", ubifs_err(c, "cannot decompress %d bytes, compressor %s, error %d",
in_len, compr->name, err); in_len, compr->name, err);
return err; return err;
...@@ -193,8 +193,8 @@ static int __init compr_init(struct ubifs_compressor *compr) ...@@ -193,8 +193,8 @@ static int __init compr_init(struct ubifs_compressor *compr)
if (compr->capi_name) { if (compr->capi_name) {
compr->cc = crypto_alloc_comp(compr->capi_name, 0, 0); compr->cc = crypto_alloc_comp(compr->capi_name, 0, 0);
if (IS_ERR(compr->cc)) { if (IS_ERR(compr->cc)) {
ubifs_err("cannot initialize compressor %s, error %ld", pr_err("UBIFS error (pid %d): cannot initialize compressor %s, error %ld",
compr->name, PTR_ERR(compr->cc)); current->pid, compr->name, PTR_ERR(compr->cc));
return PTR_ERR(compr->cc); return PTR_ERR(compr->cc);
} }
} }
......
This diff is collapsed.
...@@ -146,12 +146,12 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, ...@@ -146,12 +146,12 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
if (c->highest_inum >= INUM_WARN_WATERMARK) { if (c->highest_inum >= INUM_WARN_WATERMARK) {
if (c->highest_inum >= INUM_WATERMARK) { if (c->highest_inum >= INUM_WATERMARK) {
spin_unlock(&c->cnt_lock); spin_unlock(&c->cnt_lock);
ubifs_err("out of inode numbers"); ubifs_err(c, "out of inode numbers");
make_bad_inode(inode); make_bad_inode(inode);
iput(inode); iput(inode);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
ubifs_warn("running out of inode numbers (current %lu, max %d)", ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
(unsigned long)c->highest_inum, INUM_WATERMARK); (unsigned long)c->highest_inum, INUM_WATERMARK);
} }
...@@ -222,7 +222,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, ...@@ -222,7 +222,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
* checking. * checking.
*/ */
err = PTR_ERR(inode); err = PTR_ERR(inode);
ubifs_err("dead directory entry '%pd', error %d", ubifs_err(c, "dead directory entry '%pd', error %d",
dentry, err); dentry, err);
ubifs_ro_mode(c, err); ubifs_ro_mode(c, err);
goto out; goto out;
...@@ -272,7 +272,7 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ...@@ -272,7 +272,7 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
err = ubifs_init_security(dir, inode, &dentry->d_name); err = ubifs_init_security(dir, inode, &dentry->d_name);
if (err) if (err)
goto out_cancel; goto out_inode;
mutex_lock(&dir_ui->ui_mutex); mutex_lock(&dir_ui->ui_mutex);
dir->i_size += sz_change; dir->i_size += sz_change;
...@@ -292,11 +292,12 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ...@@ -292,11 +292,12 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
dir->i_size -= sz_change; dir->i_size -= sz_change;
dir_ui->ui_size = dir->i_size; dir_ui->ui_size = dir->i_size;
mutex_unlock(&dir_ui->ui_mutex); mutex_unlock(&dir_ui->ui_mutex);
out_inode:
make_bad_inode(inode); make_bad_inode(inode);
iput(inode); iput(inode);
out_budg: out_budg:
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
ubifs_err("cannot create regular file, error %d", err); ubifs_err(c, "cannot create regular file, error %d", err);
return err; return err;
} }
...@@ -449,7 +450,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx) ...@@ -449,7 +450,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
out: out:
if (err != -ENOENT) { if (err != -ENOENT) {
ubifs_err("cannot find next direntry, error %d", err); ubifs_err(c, "cannot find next direntry, error %d", err);
return err; return err;
} }
...@@ -732,7 +733,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ...@@ -732,7 +733,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
err = ubifs_init_security(dir, inode, &dentry->d_name); err = ubifs_init_security(dir, inode, &dentry->d_name);
if (err) if (err)
goto out_cancel; goto out_inode;
mutex_lock(&dir_ui->ui_mutex); mutex_lock(&dir_ui->ui_mutex);
insert_inode_hash(inode); insert_inode_hash(inode);
...@@ -743,7 +744,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ...@@ -743,7 +744,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
dir->i_mtime = dir->i_ctime = inode->i_ctime; dir->i_mtime = dir->i_ctime = inode->i_ctime;
err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
if (err) { if (err) {
ubifs_err("cannot create directory, error %d", err); ubifs_err(c, "cannot create directory, error %d", err);
goto out_cancel; goto out_cancel;
} }
mutex_unlock(&dir_ui->ui_mutex); mutex_unlock(&dir_ui->ui_mutex);
...@@ -757,6 +758,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ...@@ -757,6 +758,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
dir_ui->ui_size = dir->i_size; dir_ui->ui_size = dir->i_size;
drop_nlink(dir); drop_nlink(dir);
mutex_unlock(&dir_ui->ui_mutex); mutex_unlock(&dir_ui->ui_mutex);
out_inode:
make_bad_inode(inode); make_bad_inode(inode);
iput(inode); iput(inode);
out_budg: out_budg:
...@@ -816,7 +818,7 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -816,7 +818,7 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
err = ubifs_init_security(dir, inode, &dentry->d_name); err = ubifs_init_security(dir, inode, &dentry->d_name);
if (err) if (err)
goto out_cancel; goto out_inode;
mutex_lock(&dir_ui->ui_mutex); mutex_lock(&dir_ui->ui_mutex);
dir->i_size += sz_change; dir->i_size += sz_change;
...@@ -836,6 +838,7 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -836,6 +838,7 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
dir->i_size -= sz_change; dir->i_size -= sz_change;
dir_ui->ui_size = dir->i_size; dir_ui->ui_size = dir->i_size;
mutex_unlock(&dir_ui->ui_mutex); mutex_unlock(&dir_ui->ui_mutex);
out_inode:
make_bad_inode(inode); make_bad_inode(inode);
iput(inode); iput(inode);
out_budg: out_budg:
...@@ -896,7 +899,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry, ...@@ -896,7 +899,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
err = ubifs_init_security(dir, inode, &dentry->d_name); err = ubifs_init_security(dir, inode, &dentry->d_name);
if (err) if (err)
goto out_cancel; goto out_inode;
mutex_lock(&dir_ui->ui_mutex); mutex_lock(&dir_ui->ui_mutex);
dir->i_size += sz_change; dir->i_size += sz_change;
......
...@@ -79,7 +79,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block, ...@@ -79,7 +79,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
out_len = UBIFS_BLOCK_SIZE; out_len = UBIFS_BLOCK_SIZE;
err = ubifs_decompress(&dn->data, dlen, addr, &out_len, err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len,
le16_to_cpu(dn->compr_type)); le16_to_cpu(dn->compr_type));
if (err || len != out_len) if (err || len != out_len)
goto dump; goto dump;
...@@ -95,7 +95,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block, ...@@ -95,7 +95,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
return 0; return 0;
dump: dump:
ubifs_err("bad data node (block %u, inode %lu)", ubifs_err(c, "bad data node (block %u, inode %lu)",
block, inode->i_ino); block, inode->i_ino);
ubifs_dump_node(c, dn); ubifs_dump_node(c, dn);
return -EINVAL; return -EINVAL;
...@@ -160,13 +160,14 @@ static int do_readpage(struct page *page) ...@@ -160,13 +160,14 @@ static int do_readpage(struct page *page)
addr += UBIFS_BLOCK_SIZE; addr += UBIFS_BLOCK_SIZE;
} }
if (err) { if (err) {
struct ubifs_info *c = inode->i_sb->s_fs_info;
if (err == -ENOENT) { if (err == -ENOENT) {
/* Not found, so it must be a hole */ /* Not found, so it must be a hole */
SetPageChecked(page); SetPageChecked(page);
dbg_gen("hole"); dbg_gen("hole");
goto out_free; goto out_free;
} }
ubifs_err("cannot read page %lu of inode %lu, error %d", ubifs_err(c, "cannot read page %lu of inode %lu, error %d",
page->index, inode->i_ino, err); page->index, inode->i_ino, err);
goto error; goto error;
} }
...@@ -649,7 +650,7 @@ static int populate_page(struct ubifs_info *c, struct page *page, ...@@ -649,7 +650,7 @@ static int populate_page(struct ubifs_info *c, struct page *page,
dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
out_len = UBIFS_BLOCK_SIZE; out_len = UBIFS_BLOCK_SIZE;
err = ubifs_decompress(&dn->data, dlen, addr, &out_len, err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len,
le16_to_cpu(dn->compr_type)); le16_to_cpu(dn->compr_type));
if (err || len != out_len) if (err || len != out_len)
goto out_err; goto out_err;
...@@ -697,7 +698,7 @@ static int populate_page(struct ubifs_info *c, struct page *page, ...@@ -697,7 +698,7 @@ static int populate_page(struct ubifs_info *c, struct page *page,
SetPageError(page); SetPageError(page);
flush_dcache_page(page); flush_dcache_page(page);
kunmap(page); kunmap(page);
ubifs_err("bad data node (block %u, inode %lu)", ubifs_err(c, "bad data node (block %u, inode %lu)",
page_block, inode->i_ino); page_block, inode->i_ino);
return -EINVAL; return -EINVAL;
} }
...@@ -801,7 +802,7 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu, ...@@ -801,7 +802,7 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu,
return ret; return ret;
out_warn: out_warn:
ubifs_warn("ignoring error %d and skipping bulk-read", err); ubifs_warn(c, "ignoring error %d and skipping bulk-read", err);
goto out_free; goto out_free;
out_bu_off: out_bu_off:
...@@ -929,7 +930,7 @@ static int do_writepage(struct page *page, int len) ...@@ -929,7 +930,7 @@ static int do_writepage(struct page *page, int len)
} }
if (err) { if (err) {
SetPageError(page); SetPageError(page);
ubifs_err("cannot write page %lu of inode %lu, error %d", ubifs_err(c, "cannot write page %lu of inode %lu, error %d",
page->index, inode->i_ino, err); page->index, inode->i_ino, err);
ubifs_ro_mode(c, err); ubifs_ro_mode(c, err);
} }
...@@ -1484,7 +1485,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, ...@@ -1484,7 +1485,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
err = ubifs_budget_space(c, &req); err = ubifs_budget_space(c, &req);
if (unlikely(err)) { if (unlikely(err)) {
if (err == -ENOSPC) if (err == -ENOSPC)
ubifs_warn("out of space for mmapped file (inode number %lu)", ubifs_warn(c, "out of space for mmapped file (inode number %lu)",
inode->i_ino); inode->i_ino);
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
} }
......
...@@ -85,7 +85,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) ...@@ -85,7 +85,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
c->ro_error = 1; c->ro_error = 1;
c->no_chk_data_crc = 0; c->no_chk_data_crc = 0;
c->vfs_sb->s_flags |= MS_RDONLY; c->vfs_sb->s_flags |= MS_RDONLY;
ubifs_warn("switched to read-only mode, error %d", err); ubifs_warn(c, "switched to read-only mode, error %d", err);
dump_stack(); dump_stack();
} }
} }
...@@ -107,7 +107,7 @@ int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, ...@@ -107,7 +107,7 @@ int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
* @even_ebadmsg is true. * @even_ebadmsg is true.
*/ */
if (err && (err != -EBADMSG || even_ebadmsg)) { if (err && (err != -EBADMSG || even_ebadmsg)) {
ubifs_err("reading %d bytes from LEB %d:%d failed, error %d", ubifs_err(c, "reading %d bytes from LEB %d:%d failed, error %d",
len, lnum, offs, err); len, lnum, offs, err);
dump_stack(); dump_stack();
} }
...@@ -127,7 +127,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, ...@@ -127,7 +127,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
else else
err = dbg_leb_write(c, lnum, buf, offs, len); err = dbg_leb_write(c, lnum, buf, offs, len);
if (err) { if (err) {
ubifs_err("writing %d bytes to LEB %d:%d failed, error %d", ubifs_err(c, "writing %d bytes to LEB %d:%d failed, error %d",
len, lnum, offs, err); len, lnum, offs, err);
ubifs_ro_mode(c, err); ubifs_ro_mode(c, err);
dump_stack(); dump_stack();
...@@ -147,7 +147,7 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len) ...@@ -147,7 +147,7 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len)
else else
err = dbg_leb_change(c, lnum, buf, len); err = dbg_leb_change(c, lnum, buf, len);
if (err) { if (err) {
ubifs_err("changing %d bytes in LEB %d failed, error %d", ubifs_err(c, "changing %d bytes in LEB %d failed, error %d",
len, lnum, err); len, lnum, err);
ubifs_ro_mode(c, err); ubifs_ro_mode(c, err);
dump_stack(); dump_stack();
...@@ -167,7 +167,7 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum) ...@@ -167,7 +167,7 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
else else
err = dbg_leb_unmap(c, lnum); err = dbg_leb_unmap(c, lnum);
if (err) { if (err) {
ubifs_err("unmap LEB %d failed, error %d", lnum, err); ubifs_err(c, "unmap LEB %d failed, error %d", lnum, err);
ubifs_ro_mode(c, err); ubifs_ro_mode(c, err);
dump_stack(); dump_stack();
} }
...@@ -186,7 +186,7 @@ int ubifs_leb_map(struct ubifs_info *c, int lnum) ...@@ -186,7 +186,7 @@ int ubifs_leb_map(struct ubifs_info *c, int lnum)
else else
err = dbg_leb_map(c, lnum); err = dbg_leb_map(c, lnum);
if (err) { if (err) {
ubifs_err("mapping LEB %d failed, error %d", lnum, err); ubifs_err(c, "mapping LEB %d failed, error %d", lnum, err);
ubifs_ro_mode(c, err); ubifs_ro_mode(c, err);
dump_stack(); dump_stack();
} }
...@@ -199,7 +199,7 @@ int ubifs_is_mapped(const struct ubifs_info *c, int lnum) ...@@ -199,7 +199,7 @@ int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
err = ubi_is_mapped(c->ubi, lnum); err = ubi_is_mapped(c->ubi, lnum);
if (err < 0) { if (err < 0) {
ubifs_err("ubi_is_mapped failed for LEB %d, error %d", ubifs_err(c, "ubi_is_mapped failed for LEB %d, error %d",
lnum, err); lnum, err);
dump_stack(); dump_stack();
} }
...@@ -247,7 +247,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, ...@@ -247,7 +247,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
magic = le32_to_cpu(ch->magic); magic = le32_to_cpu(ch->magic);
if (magic != UBIFS_NODE_MAGIC) { if (magic != UBIFS_NODE_MAGIC) {
if (!quiet) if (!quiet)
ubifs_err("bad magic %#08x, expected %#08x", ubifs_err(c, "bad magic %#08x, expected %#08x",
magic, UBIFS_NODE_MAGIC); magic, UBIFS_NODE_MAGIC);
err = -EUCLEAN; err = -EUCLEAN;
goto out; goto out;
...@@ -256,7 +256,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, ...@@ -256,7 +256,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
type = ch->node_type; type = ch->node_type;
if (type < 0 || type >= UBIFS_NODE_TYPES_CNT) { if (type < 0 || type >= UBIFS_NODE_TYPES_CNT) {
if (!quiet) if (!quiet)
ubifs_err("bad node type %d", type); ubifs_err(c, "bad node type %d", type);
goto out; goto out;
} }
...@@ -279,7 +279,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, ...@@ -279,7 +279,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
node_crc = le32_to_cpu(ch->crc); node_crc = le32_to_cpu(ch->crc);
if (crc != node_crc) { if (crc != node_crc) {
if (!quiet) if (!quiet)
ubifs_err("bad CRC: calculated %#08x, read %#08x", ubifs_err(c, "bad CRC: calculated %#08x, read %#08x",
crc, node_crc); crc, node_crc);
err = -EUCLEAN; err = -EUCLEAN;
goto out; goto out;
...@@ -289,10 +289,10 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, ...@@ -289,10 +289,10 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
out_len: out_len:
if (!quiet) if (!quiet)
ubifs_err("bad node length %d", node_len); ubifs_err(c, "bad node length %d", node_len);
out: out:
if (!quiet) { if (!quiet) {
ubifs_err("bad node at LEB %d:%d", lnum, offs); ubifs_err(c, "bad node at LEB %d:%d", lnum, offs);
ubifs_dump_node(c, buf); ubifs_dump_node(c, buf);
dump_stack(); dump_stack();
} }
...@@ -355,11 +355,11 @@ static unsigned long long next_sqnum(struct ubifs_info *c) ...@@ -355,11 +355,11 @@ static unsigned long long next_sqnum(struct ubifs_info *c)
if (unlikely(sqnum >= SQNUM_WARN_WATERMARK)) { if (unlikely(sqnum >= SQNUM_WARN_WATERMARK)) {
if (sqnum >= SQNUM_WATERMARK) { if (sqnum >= SQNUM_WATERMARK) {
ubifs_err("sequence number overflow %llu, end of life", ubifs_err(c, "sequence number overflow %llu, end of life",
sqnum); sqnum);
ubifs_ro_mode(c, -EINVAL); ubifs_ro_mode(c, -EINVAL);
} }
ubifs_warn("running out of sequence numbers, end of life soon"); ubifs_warn(c, "running out of sequence numbers, end of life soon");
} }
return sqnum; return sqnum;
...@@ -636,7 +636,7 @@ int ubifs_bg_wbufs_sync(struct ubifs_info *c) ...@@ -636,7 +636,7 @@ int ubifs_bg_wbufs_sync(struct ubifs_info *c)
err = ubifs_wbuf_sync_nolock(wbuf); err = ubifs_wbuf_sync_nolock(wbuf);
mutex_unlock(&wbuf->io_mutex); mutex_unlock(&wbuf->io_mutex);
if (err) { if (err) {
ubifs_err("cannot sync write-buffer, error %d", err); ubifs_err(c, "cannot sync write-buffer, error %d", err);
ubifs_ro_mode(c, err); ubifs_ro_mode(c, err);
goto out_timers; goto out_timers;
} }
...@@ -833,7 +833,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) ...@@ -833,7 +833,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
return 0; return 0;
out: out:
ubifs_err("cannot write %d bytes to LEB %d:%d, error %d", ubifs_err(c, "cannot write %d bytes to LEB %d:%d, error %d",
len, wbuf->lnum, wbuf->offs, err); len, wbuf->lnum, wbuf->offs, err);
ubifs_dump_node(c, buf); ubifs_dump_node(c, buf);
dump_stack(); dump_stack();
...@@ -932,27 +932,27 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, ...@@ -932,27 +932,27 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
} }
if (type != ch->node_type) { if (type != ch->node_type) {
ubifs_err("bad node type (%d but expected %d)", ubifs_err(c, "bad node type (%d but expected %d)",
ch->node_type, type); ch->node_type, type);
goto out; goto out;
} }
err = ubifs_check_node(c, buf, lnum, offs, 0, 0); err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
if (err) { if (err) {
ubifs_err("expected node type %d", type); ubifs_err(c, "expected node type %d", type);
return err; return err;
} }
rlen = le32_to_cpu(ch->len); rlen = le32_to_cpu(ch->len);
if (rlen != len) { if (rlen != len) {
ubifs_err("bad node length %d, expected %d", rlen, len); ubifs_err(c, "bad node length %d, expected %d", rlen, len);
goto out; goto out;
} }
return 0; return 0;
out: out:
ubifs_err("bad node at LEB %d:%d", lnum, offs); ubifs_err(c, "bad node at LEB %d:%d", lnum, offs);
ubifs_dump_node(c, buf); ubifs_dump_node(c, buf);
dump_stack(); dump_stack();
return -EINVAL; return -EINVAL;
......
...@@ -138,7 +138,7 @@ static int setflags(struct inode *inode, int flags) ...@@ -138,7 +138,7 @@ static int setflags(struct inode *inode, int flags)
return err; return err;
out_unlock: out_unlock:
ubifs_err("can't modify inode %lu attributes", inode->i_ino); ubifs_err(c, "can't modify inode %lu attributes", inode->i_ino);
mutex_unlock(&ui->ui_mutex); mutex_unlock(&ui->ui_mutex);
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
return err; return err;
......
...@@ -363,11 +363,11 @@ static int make_reservation(struct ubifs_info *c, int jhead, int len) ...@@ -363,11 +363,11 @@ static int make_reservation(struct ubifs_info *c, int jhead, int len)
* This should not happen unless the journal size limitations * This should not happen unless the journal size limitations
* are too tough. * are too tough.
*/ */
ubifs_err("stuck in space allocation"); ubifs_err(c, "stuck in space allocation");
err = -ENOSPC; err = -ENOSPC;
goto out; goto out;
} else if (cmt_retries > 32) } else if (cmt_retries > 32)
ubifs_warn("too many space allocation re-tries (%d)", ubifs_warn(c, "too many space allocation re-tries (%d)",
cmt_retries); cmt_retries);
dbg_jnl("-EAGAIN, commit and retry (retried %d times)", dbg_jnl("-EAGAIN, commit and retry (retried %d times)",
...@@ -380,7 +380,7 @@ static int make_reservation(struct ubifs_info *c, int jhead, int len) ...@@ -380,7 +380,7 @@ static int make_reservation(struct ubifs_info *c, int jhead, int len)
goto again; goto again;
out: out:
ubifs_err("cannot reserve %d bytes in jhead %d, error %d", ubifs_err(c, "cannot reserve %d bytes in jhead %d, error %d",
len, jhead, err); len, jhead, err);
if (err == -ENOSPC) { if (err == -ENOSPC) {
/* This are some budgeting problems, print useful information */ /* This are some budgeting problems, print useful information */
...@@ -731,7 +731,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, ...@@ -731,7 +731,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
compr_type = ui->compr_type; compr_type = ui->compr_type;
out_len = dlen - UBIFS_DATA_NODE_SZ; out_len = dlen - UBIFS_DATA_NODE_SZ;
ubifs_compress(buf, len, &data->data, &out_len, &compr_type); ubifs_compress(c, buf, len, &data->data, &out_len, &compr_type);
ubifs_assert(out_len <= UBIFS_BLOCK_SIZE); ubifs_assert(out_len <= UBIFS_BLOCK_SIZE);
dlen = UBIFS_DATA_NODE_SZ + out_len; dlen = UBIFS_DATA_NODE_SZ + out_len;
...@@ -1100,7 +1100,8 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, ...@@ -1100,7 +1100,8 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
* This function is used when an inode is truncated and the last data node of * This function is used when an inode is truncated and the last data node of
* the inode has to be re-compressed and re-written. * the inode has to be re-compressed and re-written.
*/ */
static int recomp_data_node(struct ubifs_data_node *dn, int *new_len) static int recomp_data_node(const struct ubifs_info *c,
struct ubifs_data_node *dn, int *new_len)
{ {
void *buf; void *buf;
int err, len, compr_type, out_len; int err, len, compr_type, out_len;
...@@ -1112,11 +1113,11 @@ static int recomp_data_node(struct ubifs_data_node *dn, int *new_len) ...@@ -1112,11 +1113,11 @@ static int recomp_data_node(struct ubifs_data_node *dn, int *new_len)
len = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; len = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
compr_type = le16_to_cpu(dn->compr_type); compr_type = le16_to_cpu(dn->compr_type);
err = ubifs_decompress(&dn->data, len, buf, &out_len, compr_type); err = ubifs_decompress(c, &dn->data, len, buf, &out_len, compr_type);
if (err) if (err)
goto out; goto out;
ubifs_compress(buf, *new_len, &dn->data, &out_len, &compr_type); ubifs_compress(c, buf, *new_len, &dn->data, &out_len, &compr_type);
ubifs_assert(out_len <= UBIFS_BLOCK_SIZE); ubifs_assert(out_len <= UBIFS_BLOCK_SIZE);
dn->compr_type = cpu_to_le16(compr_type); dn->compr_type = cpu_to_le16(compr_type);
dn->size = cpu_to_le32(*new_len); dn->size = cpu_to_le32(*new_len);
...@@ -1191,7 +1192,7 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, ...@@ -1191,7 +1192,7 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
int compr_type = le16_to_cpu(dn->compr_type); int compr_type = le16_to_cpu(dn->compr_type);
if (compr_type != UBIFS_COMPR_NONE) { if (compr_type != UBIFS_COMPR_NONE) {
err = recomp_data_node(dn, &dlen); err = recomp_data_node(c, dn, &dlen);
if (err) if (err)
goto out_free; goto out_free;
} else { } else {
......
...@@ -696,7 +696,7 @@ int ubifs_consolidate_log(struct ubifs_info *c) ...@@ -696,7 +696,7 @@ int ubifs_consolidate_log(struct ubifs_info *c)
destroy_done_tree(&done_tree); destroy_done_tree(&done_tree);
vfree(buf); vfree(buf);
if (write_lnum == c->lhead_lnum) { if (write_lnum == c->lhead_lnum) {
ubifs_err("log is too full"); ubifs_err(c, "log is too full");
return -EINVAL; return -EINVAL;
} }
/* Unmap remaining LEBs */ /* Unmap remaining LEBs */
...@@ -743,7 +743,7 @@ static int dbg_check_bud_bytes(struct ubifs_info *c) ...@@ -743,7 +743,7 @@ static int dbg_check_bud_bytes(struct ubifs_info *c)
bud_bytes += c->leb_size - bud->start; bud_bytes += c->leb_size - bud->start;
if (c->bud_bytes != bud_bytes) { if (c->bud_bytes != bud_bytes) {
ubifs_err("bad bud_bytes %lld, calculated %lld", ubifs_err(c, "bad bud_bytes %lld, calculated %lld",
c->bud_bytes, bud_bytes); c->bud_bytes, bud_bytes);
err = -EINVAL; err = -EINVAL;
} }
......
...@@ -682,7 +682,7 @@ int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, ...@@ -682,7 +682,7 @@ int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty,
out: out:
ubifs_release_lprops(c); ubifs_release_lprops(c);
if (err) if (err)
ubifs_err("cannot change properties of LEB %d, error %d", ubifs_err(c, "cannot change properties of LEB %d, error %d",
lnum, err); lnum, err);
return err; return err;
} }
...@@ -721,7 +721,7 @@ int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, ...@@ -721,7 +721,7 @@ int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty,
out: out:
ubifs_release_lprops(c); ubifs_release_lprops(c);
if (err) if (err)
ubifs_err("cannot update properties of LEB %d, error %d", ubifs_err(c, "cannot update properties of LEB %d, error %d",
lnum, err); lnum, err);
return err; return err;
} }
...@@ -746,7 +746,7 @@ int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp) ...@@ -746,7 +746,7 @@ int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp)
lpp = ubifs_lpt_lookup(c, lnum); lpp = ubifs_lpt_lookup(c, lnum);
if (IS_ERR(lpp)) { if (IS_ERR(lpp)) {
err = PTR_ERR(lpp); err = PTR_ERR(lpp);
ubifs_err("cannot read properties of LEB %d, error %d", ubifs_err(c, "cannot read properties of LEB %d, error %d",
lnum, err); lnum, err);
goto out; goto out;
} }
...@@ -873,13 +873,13 @@ int dbg_check_cats(struct ubifs_info *c) ...@@ -873,13 +873,13 @@ int dbg_check_cats(struct ubifs_info *c)
list_for_each_entry(lprops, &c->empty_list, list) { list_for_each_entry(lprops, &c->empty_list, list) {
if (lprops->free != c->leb_size) { if (lprops->free != c->leb_size) {
ubifs_err("non-empty LEB %d on empty list (free %d dirty %d flags %d)", ubifs_err(c, "non-empty LEB %d on empty list (free %d dirty %d flags %d)",
lprops->lnum, lprops->free, lprops->dirty, lprops->lnum, lprops->free, lprops->dirty,
lprops->flags); lprops->flags);
return -EINVAL; return -EINVAL;
} }
if (lprops->flags & LPROPS_TAKEN) { if (lprops->flags & LPROPS_TAKEN) {
ubifs_err("taken LEB %d on empty list (free %d dirty %d flags %d)", ubifs_err(c, "taken LEB %d on empty list (free %d dirty %d flags %d)",
lprops->lnum, lprops->free, lprops->dirty, lprops->lnum, lprops->free, lprops->dirty,
lprops->flags); lprops->flags);
return -EINVAL; return -EINVAL;
...@@ -889,13 +889,13 @@ int dbg_check_cats(struct ubifs_info *c) ...@@ -889,13 +889,13 @@ int dbg_check_cats(struct ubifs_info *c)
i = 0; i = 0;
list_for_each_entry(lprops, &c->freeable_list, list) { list_for_each_entry(lprops, &c->freeable_list, list) {
if (lprops->free + lprops->dirty != c->leb_size) { if (lprops->free + lprops->dirty != c->leb_size) {
ubifs_err("non-freeable LEB %d on freeable list (free %d dirty %d flags %d)", ubifs_err(c, "non-freeable LEB %d on freeable list (free %d dirty %d flags %d)",
lprops->lnum, lprops->free, lprops->dirty, lprops->lnum, lprops->free, lprops->dirty,
lprops->flags); lprops->flags);
return -EINVAL; return -EINVAL;
} }
if (lprops->flags & LPROPS_TAKEN) { if (lprops->flags & LPROPS_TAKEN) {
ubifs_err("taken LEB %d on freeable list (free %d dirty %d flags %d)", ubifs_err(c, "taken LEB %d on freeable list (free %d dirty %d flags %d)",
lprops->lnum, lprops->free, lprops->dirty, lprops->lnum, lprops->free, lprops->dirty,
lprops->flags); lprops->flags);
return -EINVAL; return -EINVAL;
...@@ -903,7 +903,7 @@ int dbg_check_cats(struct ubifs_info *c) ...@@ -903,7 +903,7 @@ int dbg_check_cats(struct ubifs_info *c)
i += 1; i += 1;
} }
if (i != c->freeable_cnt) { if (i != c->freeable_cnt) {
ubifs_err("freeable list count %d expected %d", i, ubifs_err(c, "freeable list count %d expected %d", i,
c->freeable_cnt); c->freeable_cnt);
return -EINVAL; return -EINVAL;
} }
...@@ -912,26 +912,26 @@ int dbg_check_cats(struct ubifs_info *c) ...@@ -912,26 +912,26 @@ int dbg_check_cats(struct ubifs_info *c)
list_for_each(pos, &c->idx_gc) list_for_each(pos, &c->idx_gc)
i += 1; i += 1;
if (i != c->idx_gc_cnt) { if (i != c->idx_gc_cnt) {
ubifs_err("idx_gc list count %d expected %d", i, ubifs_err(c, "idx_gc list count %d expected %d", i,
c->idx_gc_cnt); c->idx_gc_cnt);
return -EINVAL; return -EINVAL;
} }
list_for_each_entry(lprops, &c->frdi_idx_list, list) { list_for_each_entry(lprops, &c->frdi_idx_list, list) {
if (lprops->free + lprops->dirty != c->leb_size) { if (lprops->free + lprops->dirty != c->leb_size) {
ubifs_err("non-freeable LEB %d on frdi_idx list (free %d dirty %d flags %d)", ubifs_err(c, "non-freeable LEB %d on frdi_idx list (free %d dirty %d flags %d)",
lprops->lnum, lprops->free, lprops->dirty, lprops->lnum, lprops->free, lprops->dirty,
lprops->flags); lprops->flags);
return -EINVAL; return -EINVAL;
} }
if (lprops->flags & LPROPS_TAKEN) { if (lprops->flags & LPROPS_TAKEN) {
ubifs_err("taken LEB %d on frdi_idx list (free %d dirty %d flags %d)", ubifs_err(c, "taken LEB %d on frdi_idx list (free %d dirty %d flags %d)",
lprops->lnum, lprops->free, lprops->dirty, lprops->lnum, lprops->free, lprops->dirty,
lprops->flags); lprops->flags);
return -EINVAL; return -EINVAL;
} }
if (!(lprops->flags & LPROPS_INDEX)) { if (!(lprops->flags & LPROPS_INDEX)) {
ubifs_err("non-index LEB %d on frdi_idx list (free %d dirty %d flags %d)", ubifs_err(c, "non-index LEB %d on frdi_idx list (free %d dirty %d flags %d)",
lprops->lnum, lprops->free, lprops->dirty, lprops->lnum, lprops->free, lprops->dirty,
lprops->flags); lprops->flags);
return -EINVAL; return -EINVAL;
...@@ -944,15 +944,15 @@ int dbg_check_cats(struct ubifs_info *c) ...@@ -944,15 +944,15 @@ int dbg_check_cats(struct ubifs_info *c)
for (i = 0; i < heap->cnt; i++) { for (i = 0; i < heap->cnt; i++) {
lprops = heap->arr[i]; lprops = heap->arr[i];
if (!lprops) { if (!lprops) {
ubifs_err("null ptr in LPT heap cat %d", cat); ubifs_err(c, "null ptr in LPT heap cat %d", cat);
return -EINVAL; return -EINVAL;
} }
if (lprops->hpos != i) { if (lprops->hpos != i) {
ubifs_err("bad ptr in LPT heap cat %d", cat); ubifs_err(c, "bad ptr in LPT heap cat %d", cat);
return -EINVAL; return -EINVAL;
} }
if (lprops->flags & LPROPS_TAKEN) { if (lprops->flags & LPROPS_TAKEN) {
ubifs_err("taken LEB in LPT heap cat %d", cat); ubifs_err(c, "taken LEB in LPT heap cat %d", cat);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -988,7 +988,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, ...@@ -988,7 +988,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
goto out; goto out;
} }
if (lprops != lp) { if (lprops != lp) {
ubifs_err("lprops %zx lp %zx lprops->lnum %d lp->lnum %d", ubifs_err(c, "lprops %zx lp %zx lprops->lnum %d lp->lnum %d",
(size_t)lprops, (size_t)lp, lprops->lnum, (size_t)lprops, (size_t)lp, lprops->lnum,
lp->lnum); lp->lnum);
err = 4; err = 4;
...@@ -1008,7 +1008,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, ...@@ -1008,7 +1008,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
} }
out: out:
if (err) { if (err) {
ubifs_err("failed cat %d hpos %d err %d", cat, i, err); ubifs_err(c, "failed cat %d hpos %d err %d", cat, i, err);
dump_stack(); dump_stack();
ubifs_dump_heap(c, heap, cat); ubifs_dump_heap(c, heap, cat);
} }
...@@ -1039,7 +1039,7 @@ static int scan_check_cb(struct ubifs_info *c, ...@@ -1039,7 +1039,7 @@ static int scan_check_cb(struct ubifs_info *c,
if (cat != LPROPS_UNCAT) { if (cat != LPROPS_UNCAT) {
cat = ubifs_categorize_lprops(c, lp); cat = ubifs_categorize_lprops(c, lp);
if (cat != (lp->flags & LPROPS_CAT_MASK)) { if (cat != (lp->flags & LPROPS_CAT_MASK)) {
ubifs_err("bad LEB category %d expected %d", ubifs_err(c, "bad LEB category %d expected %d",
(lp->flags & LPROPS_CAT_MASK), cat); (lp->flags & LPROPS_CAT_MASK), cat);
return -EINVAL; return -EINVAL;
} }
...@@ -1074,7 +1074,7 @@ static int scan_check_cb(struct ubifs_info *c, ...@@ -1074,7 +1074,7 @@ static int scan_check_cb(struct ubifs_info *c,
} }
} }
if (!found) { if (!found) {
ubifs_err("bad LPT list (category %d)", cat); ubifs_err(c, "bad LPT list (category %d)", cat);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -1086,7 +1086,7 @@ static int scan_check_cb(struct ubifs_info *c, ...@@ -1086,7 +1086,7 @@ static int scan_check_cb(struct ubifs_info *c,
if ((lp->hpos != -1 && heap->arr[lp->hpos]->lnum != lnum) || if ((lp->hpos != -1 && heap->arr[lp->hpos]->lnum != lnum) ||
lp != heap->arr[lp->hpos]) { lp != heap->arr[lp->hpos]) {
ubifs_err("bad LPT heap (category %d)", cat); ubifs_err(c, "bad LPT heap (category %d)", cat);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -1133,7 +1133,7 @@ static int scan_check_cb(struct ubifs_info *c, ...@@ -1133,7 +1133,7 @@ static int scan_check_cb(struct ubifs_info *c,
is_idx = (snod->type == UBIFS_IDX_NODE) ? 1 : 0; is_idx = (snod->type == UBIFS_IDX_NODE) ? 1 : 0;
if (is_idx && snod->type != UBIFS_IDX_NODE) { if (is_idx && snod->type != UBIFS_IDX_NODE) {
ubifs_err("indexing node in data LEB %d:%d", ubifs_err(c, "indexing node in data LEB %d:%d",
lnum, snod->offs); lnum, snod->offs);
goto out_destroy; goto out_destroy;
} }
...@@ -1159,7 +1159,7 @@ static int scan_check_cb(struct ubifs_info *c, ...@@ -1159,7 +1159,7 @@ static int scan_check_cb(struct ubifs_info *c,
if (free > c->leb_size || free < 0 || dirty > c->leb_size || if (free > c->leb_size || free < 0 || dirty > c->leb_size ||
dirty < 0) { dirty < 0) {
ubifs_err("bad calculated accounting for LEB %d: free %d, dirty %d", ubifs_err(c, "bad calculated accounting for LEB %d: free %d, dirty %d",
lnum, free, dirty); lnum, free, dirty);
goto out_destroy; goto out_destroy;
} }
...@@ -1206,13 +1206,13 @@ static int scan_check_cb(struct ubifs_info *c, ...@@ -1206,13 +1206,13 @@ static int scan_check_cb(struct ubifs_info *c,
/* Free but not unmapped LEB, it's fine */ /* Free but not unmapped LEB, it's fine */
is_idx = 0; is_idx = 0;
else { else {
ubifs_err("indexing node without indexing flag"); ubifs_err(c, "indexing node without indexing flag");
goto out_print; goto out_print;
} }
} }
if (!is_idx && (lp->flags & LPROPS_INDEX)) { if (!is_idx && (lp->flags & LPROPS_INDEX)) {
ubifs_err("data node with indexing flag"); ubifs_err(c, "data node with indexing flag");
goto out_print; goto out_print;
} }
...@@ -1241,7 +1241,7 @@ static int scan_check_cb(struct ubifs_info *c, ...@@ -1241,7 +1241,7 @@ static int scan_check_cb(struct ubifs_info *c,
return LPT_SCAN_CONTINUE; return LPT_SCAN_CONTINUE;
out_print: out_print:
ubifs_err("bad accounting of LEB %d: free %d, dirty %d flags %#x, should be free %d, dirty %d", ubifs_err(c, "bad accounting of LEB %d: free %d, dirty %d flags %#x, should be free %d, dirty %d",
lnum, lp->free, lp->dirty, lp->flags, free, dirty); lnum, lp->free, lp->dirty, lp->flags, free, dirty);
ubifs_dump_leb(c, lnum); ubifs_dump_leb(c, lnum);
out_destroy: out_destroy:
...@@ -1293,11 +1293,11 @@ int dbg_check_lprops(struct ubifs_info *c) ...@@ -1293,11 +1293,11 @@ int dbg_check_lprops(struct ubifs_info *c)
lst.total_free != c->lst.total_free || lst.total_free != c->lst.total_free ||
lst.total_dirty != c->lst.total_dirty || lst.total_dirty != c->lst.total_dirty ||
lst.total_used != c->lst.total_used) { lst.total_used != c->lst.total_used) {
ubifs_err("bad overall accounting"); ubifs_err(c, "bad overall accounting");
ubifs_err("calculated: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld", ubifs_err(c, "calculated: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld",
lst.empty_lebs, lst.idx_lebs, lst.total_free, lst.empty_lebs, lst.idx_lebs, lst.total_free,
lst.total_dirty, lst.total_used); lst.total_dirty, lst.total_used);
ubifs_err("read from lprops: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld", ubifs_err(c, "read from lprops: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld",
c->lst.empty_lebs, c->lst.idx_lebs, c->lst.total_free, c->lst.empty_lebs, c->lst.idx_lebs, c->lst.total_free,
c->lst.total_dirty, c->lst.total_used); c->lst.total_dirty, c->lst.total_used);
err = -EINVAL; err = -EINVAL;
...@@ -1306,10 +1306,10 @@ int dbg_check_lprops(struct ubifs_info *c) ...@@ -1306,10 +1306,10 @@ int dbg_check_lprops(struct ubifs_info *c)
if (lst.total_dead != c->lst.total_dead || if (lst.total_dead != c->lst.total_dead ||
lst.total_dark != c->lst.total_dark) { lst.total_dark != c->lst.total_dark) {
ubifs_err("bad dead/dark space accounting"); ubifs_err(c, "bad dead/dark space accounting");
ubifs_err("calculated: total_dead %lld, total_dark %lld", ubifs_err(c, "calculated: total_dead %lld, total_dark %lld",
lst.total_dead, lst.total_dark); lst.total_dead, lst.total_dark);
ubifs_err("read from lprops: total_dead %lld, total_dark %lld", ubifs_err(c, "read from lprops: total_dead %lld, total_dark %lld",
c->lst.total_dead, c->lst.total_dark); c->lst.total_dead, c->lst.total_dark);
err = -EINVAL; err = -EINVAL;
goto out; goto out;
......
...@@ -145,13 +145,13 @@ int ubifs_calc_lpt_geom(struct ubifs_info *c) ...@@ -145,13 +145,13 @@ int ubifs_calc_lpt_geom(struct ubifs_info *c)
sz = c->lpt_sz * 2; /* Must have at least 2 times the size */ sz = c->lpt_sz * 2; /* Must have at least 2 times the size */
lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size); lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size);
if (lebs_needed > c->lpt_lebs) { if (lebs_needed > c->lpt_lebs) {
ubifs_err("too few LPT LEBs"); ubifs_err(c, "too few LPT LEBs");
return -EINVAL; return -EINVAL;
} }
/* Verify that ltab fits in a single LEB (since ltab is a single node */ /* Verify that ltab fits in a single LEB (since ltab is a single node */
if (c->ltab_sz > c->leb_size) { if (c->ltab_sz > c->leb_size) {
ubifs_err("LPT ltab too big"); ubifs_err(c, "LPT ltab too big");
return -EINVAL; return -EINVAL;
} }
...@@ -213,7 +213,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, ...@@ -213,7 +213,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs,
continue; continue;
} }
if (c->ltab_sz > c->leb_size) { if (c->ltab_sz > c->leb_size) {
ubifs_err("LPT ltab too big"); ubifs_err(c, "LPT ltab too big");
return -EINVAL; return -EINVAL;
} }
*main_lebs = c->main_lebs; *main_lebs = c->main_lebs;
...@@ -911,7 +911,7 @@ static void replace_cats(struct ubifs_info *c, struct ubifs_pnode *old_pnode, ...@@ -911,7 +911,7 @@ static void replace_cats(struct ubifs_info *c, struct ubifs_pnode *old_pnode,
* *
* This function returns %0 on success and a negative error code on failure. * This function returns %0 on success and a negative error code on failure.
*/ */
static int check_lpt_crc(void *buf, int len) static int check_lpt_crc(const struct ubifs_info *c, void *buf, int len)
{ {
int pos = 0; int pos = 0;
uint8_t *addr = buf; uint8_t *addr = buf;
...@@ -921,8 +921,8 @@ static int check_lpt_crc(void *buf, int len) ...@@ -921,8 +921,8 @@ static int check_lpt_crc(void *buf, int len)
calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
len - UBIFS_LPT_CRC_BYTES); len - UBIFS_LPT_CRC_BYTES);
if (crc != calc_crc) { if (crc != calc_crc) {
ubifs_err("invalid crc in LPT node: crc %hx calc %hx", crc, ubifs_err(c, "invalid crc in LPT node: crc %hx calc %hx",
calc_crc); crc, calc_crc);
dump_stack(); dump_stack();
return -EINVAL; return -EINVAL;
} }
...@@ -938,14 +938,15 @@ static int check_lpt_crc(void *buf, int len) ...@@ -938,14 +938,15 @@ static int check_lpt_crc(void *buf, int len)
* *
* This function returns %0 on success and a negative error code on failure. * This function returns %0 on success and a negative error code on failure.
*/ */
static int check_lpt_type(uint8_t **addr, int *pos, int type) static int check_lpt_type(const struct ubifs_info *c, uint8_t **addr,
int *pos, int type)
{ {
int node_type; int node_type;
node_type = ubifs_unpack_bits(addr, pos, UBIFS_LPT_TYPE_BITS); node_type = ubifs_unpack_bits(addr, pos, UBIFS_LPT_TYPE_BITS);
if (node_type != type) { if (node_type != type) {
ubifs_err("invalid type (%d) in LPT node type %d", node_type, ubifs_err(c, "invalid type (%d) in LPT node type %d",
type); node_type, type);
dump_stack(); dump_stack();
return -EINVAL; return -EINVAL;
} }
...@@ -966,7 +967,7 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf, ...@@ -966,7 +967,7 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf,
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
int i, pos = 0, err; int i, pos = 0, err;
err = check_lpt_type(&addr, &pos, UBIFS_LPT_PNODE); err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_PNODE);
if (err) if (err)
return err; return err;
if (c->big_lpt) if (c->big_lpt)
...@@ -985,7 +986,7 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf, ...@@ -985,7 +986,7 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf,
lprops->flags = 0; lprops->flags = 0;
lprops->flags |= ubifs_categorize_lprops(c, lprops); lprops->flags |= ubifs_categorize_lprops(c, lprops);
} }
err = check_lpt_crc(buf, c->pnode_sz); err = check_lpt_crc(c, buf, c->pnode_sz);
return err; return err;
} }
...@@ -1003,7 +1004,7 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, ...@@ -1003,7 +1004,7 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
int i, pos = 0, err; int i, pos = 0, err;
err = check_lpt_type(&addr, &pos, UBIFS_LPT_NNODE); err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_NNODE);
if (err) if (err)
return err; return err;
if (c->big_lpt) if (c->big_lpt)
...@@ -1019,7 +1020,7 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, ...@@ -1019,7 +1020,7 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
nnode->nbranch[i].offs = ubifs_unpack_bits(&addr, &pos, nnode->nbranch[i].offs = ubifs_unpack_bits(&addr, &pos,
c->lpt_offs_bits); c->lpt_offs_bits);
} }
err = check_lpt_crc(buf, c->nnode_sz); err = check_lpt_crc(c, buf, c->nnode_sz);
return err; return err;
} }
...@@ -1035,7 +1036,7 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf) ...@@ -1035,7 +1036,7 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf)
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
int i, pos = 0, err; int i, pos = 0, err;
err = check_lpt_type(&addr, &pos, UBIFS_LPT_LTAB); err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_LTAB);
if (err) if (err)
return err; return err;
for (i = 0; i < c->lpt_lebs; i++) { for (i = 0; i < c->lpt_lebs; i++) {
...@@ -1051,7 +1052,7 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf) ...@@ -1051,7 +1052,7 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf)
c->ltab[i].tgc = 0; c->ltab[i].tgc = 0;
c->ltab[i].cmt = 0; c->ltab[i].cmt = 0;
} }
err = check_lpt_crc(buf, c->ltab_sz); err = check_lpt_crc(c, buf, c->ltab_sz);
return err; return err;
} }
...@@ -1067,7 +1068,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf) ...@@ -1067,7 +1068,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf)
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
int i, pos = 0, err; int i, pos = 0, err;
err = check_lpt_type(&addr, &pos, UBIFS_LPT_LSAVE); err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_LSAVE);
if (err) if (err)
return err; return err;
for (i = 0; i < c->lsave_cnt; i++) { for (i = 0; i < c->lsave_cnt; i++) {
...@@ -1077,7 +1078,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf) ...@@ -1077,7 +1078,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf)
return -EINVAL; return -EINVAL;
c->lsave[i] = lnum; c->lsave[i] = lnum;
} }
err = check_lpt_crc(buf, c->lsave_sz); err = check_lpt_crc(c, buf, c->lsave_sz);
return err; return err;
} }
...@@ -1243,7 +1244,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) ...@@ -1243,7 +1244,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
return 0; return 0;
out: out:
ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs); ubifs_err(c, "error %d reading nnode at %d:%d", err, lnum, offs);
dump_stack(); dump_stack();
kfree(nnode); kfree(nnode);
return err; return err;
...@@ -1308,10 +1309,10 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) ...@@ -1308,10 +1309,10 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
return 0; return 0;
out: out:
ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs); ubifs_err(c, "error %d reading pnode at %d:%d", err, lnum, offs);
ubifs_dump_pnode(c, pnode, parent, iip); ubifs_dump_pnode(c, pnode, parent, iip);
dump_stack(); dump_stack();
ubifs_err("calc num: %d", calc_pnode_num_from_parent(c, parent, iip)); ubifs_err(c, "calc num: %d", calc_pnode_num_from_parent(c, parent, iip));
kfree(pnode); kfree(pnode);
return err; return err;
} }
...@@ -2095,7 +2096,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, ...@@ -2095,7 +2096,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
int i; int i;
if (pnode->num != col) { if (pnode->num != col) {
ubifs_err("pnode num %d expected %d parent num %d iip %d", ubifs_err(c, "pnode num %d expected %d parent num %d iip %d",
pnode->num, col, pnode->parent->num, pnode->iip); pnode->num, col, pnode->parent->num, pnode->iip);
return -EINVAL; return -EINVAL;
} }
...@@ -2110,13 +2111,13 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, ...@@ -2110,13 +2111,13 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
if (lnum >= c->leb_cnt) if (lnum >= c->leb_cnt)
continue; continue;
if (lprops->lnum != lnum) { if (lprops->lnum != lnum) {
ubifs_err("bad LEB number %d expected %d", ubifs_err(c, "bad LEB number %d expected %d",
lprops->lnum, lnum); lprops->lnum, lnum);
return -EINVAL; return -EINVAL;
} }
if (lprops->flags & LPROPS_TAKEN) { if (lprops->flags & LPROPS_TAKEN) {
if (cat != LPROPS_UNCAT) { if (cat != LPROPS_UNCAT) {
ubifs_err("LEB %d taken but not uncat %d", ubifs_err(c, "LEB %d taken but not uncat %d",
lprops->lnum, cat); lprops->lnum, cat);
return -EINVAL; return -EINVAL;
} }
...@@ -2129,7 +2130,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, ...@@ -2129,7 +2130,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
case LPROPS_FRDI_IDX: case LPROPS_FRDI_IDX:
break; break;
default: default:
ubifs_err("LEB %d index but cat %d", ubifs_err(c, "LEB %d index but cat %d",
lprops->lnum, cat); lprops->lnum, cat);
return -EINVAL; return -EINVAL;
} }
...@@ -2142,7 +2143,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, ...@@ -2142,7 +2143,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
case LPROPS_FREEABLE: case LPROPS_FREEABLE:
break; break;
default: default:
ubifs_err("LEB %d not index but cat %d", ubifs_err(c, "LEB %d not index but cat %d",
lprops->lnum, cat); lprops->lnum, cat);
return -EINVAL; return -EINVAL;
} }
...@@ -2183,14 +2184,14 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, ...@@ -2183,14 +2184,14 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
break; break;
} }
if (!found) { if (!found) {
ubifs_err("LEB %d cat %d not found in cat heap/list", ubifs_err(c, "LEB %d cat %d not found in cat heap/list",
lprops->lnum, cat); lprops->lnum, cat);
return -EINVAL; return -EINVAL;
} }
switch (cat) { switch (cat) {
case LPROPS_EMPTY: case LPROPS_EMPTY:
if (lprops->free != c->leb_size) { if (lprops->free != c->leb_size) {
ubifs_err("LEB %d cat %d free %d dirty %d", ubifs_err(c, "LEB %d cat %d free %d dirty %d",
lprops->lnum, cat, lprops->free, lprops->lnum, cat, lprops->free,
lprops->dirty); lprops->dirty);
return -EINVAL; return -EINVAL;
...@@ -2199,7 +2200,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, ...@@ -2199,7 +2200,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
case LPROPS_FREEABLE: case LPROPS_FREEABLE:
case LPROPS_FRDI_IDX: case LPROPS_FRDI_IDX:
if (lprops->free + lprops->dirty != c->leb_size) { if (lprops->free + lprops->dirty != c->leb_size) {
ubifs_err("LEB %d cat %d free %d dirty %d", ubifs_err(c, "LEB %d cat %d free %d dirty %d",
lprops->lnum, cat, lprops->free, lprops->lnum, cat, lprops->free,
lprops->dirty); lprops->dirty);
return -EINVAL; return -EINVAL;
...@@ -2236,7 +2237,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, ...@@ -2236,7 +2237,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
/* cnode is a nnode */ /* cnode is a nnode */
num = calc_nnode_num(row, col); num = calc_nnode_num(row, col);
if (cnode->num != num) { if (cnode->num != num) {
ubifs_err("nnode num %d expected %d parent num %d iip %d", ubifs_err(c, "nnode num %d expected %d parent num %d iip %d",
cnode->num, num, cnode->num, num,
(nnode ? nnode->num : 0), cnode->iip); (nnode ? nnode->num : 0), cnode->iip);
return -EINVAL; return -EINVAL;
......
...@@ -319,7 +319,7 @@ static int layout_cnodes(struct ubifs_info *c) ...@@ -319,7 +319,7 @@ static int layout_cnodes(struct ubifs_info *c)
return 0; return 0;
no_space: no_space:
ubifs_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, done_lsave %d", ubifs_err(c, "LPT out of space at LEB %d:%d needing %d, done_ltab %d, done_lsave %d",
lnum, offs, len, done_ltab, done_lsave); lnum, offs, len, done_ltab, done_lsave);
ubifs_dump_lpt_info(c); ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c); ubifs_dump_lpt_lebs(c);
...@@ -543,7 +543,7 @@ static int write_cnodes(struct ubifs_info *c) ...@@ -543,7 +543,7 @@ static int write_cnodes(struct ubifs_info *c)
return 0; return 0;
no_space: no_space:
ubifs_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab %d, done_lsave %d", ubifs_err(c, "LPT out of space mismatch at LEB %d:%d needing %d, done_ltab %d, done_lsave %d",
lnum, offs, len, done_ltab, done_lsave); lnum, offs, len, done_ltab, done_lsave);
ubifs_dump_lpt_info(c); ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c); ubifs_dump_lpt_lebs(c);
...@@ -1638,7 +1638,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum) ...@@ -1638,7 +1638,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
if (!buf) { if (!buf) {
ubifs_err("cannot allocate memory for ltab checking"); ubifs_err(c, "cannot allocate memory for ltab checking");
return 0; return 0;
} }
...@@ -1660,18 +1660,18 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum) ...@@ -1660,18 +1660,18 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
continue; continue;
} }
if (!dbg_is_all_ff(p, len)) { if (!dbg_is_all_ff(p, len)) {
ubifs_err("invalid empty space in LEB %d at %d", ubifs_err(c, "invalid empty space in LEB %d at %d",
lnum, c->leb_size - len); lnum, c->leb_size - len);
err = -EINVAL; err = -EINVAL;
} }
i = lnum - c->lpt_first; i = lnum - c->lpt_first;
if (len != c->ltab[i].free) { if (len != c->ltab[i].free) {
ubifs_err("invalid free space in LEB %d (free %d, expected %d)", ubifs_err(c, "invalid free space in LEB %d (free %d, expected %d)",
lnum, len, c->ltab[i].free); lnum, len, c->ltab[i].free);
err = -EINVAL; err = -EINVAL;
} }
if (dirty != c->ltab[i].dirty) { if (dirty != c->ltab[i].dirty) {
ubifs_err("invalid dirty space in LEB %d (dirty %d, expected %d)", ubifs_err(c, "invalid dirty space in LEB %d (dirty %d, expected %d)",
lnum, dirty, c->ltab[i].dirty); lnum, dirty, c->ltab[i].dirty);
err = -EINVAL; err = -EINVAL;
} }
...@@ -1725,7 +1725,7 @@ int dbg_check_ltab(struct ubifs_info *c) ...@@ -1725,7 +1725,7 @@ int dbg_check_ltab(struct ubifs_info *c)
for (lnum = c->lpt_first; lnum <= c->lpt_last; lnum++) { for (lnum = c->lpt_first; lnum <= c->lpt_last; lnum++) {
err = dbg_check_ltab_lnum(c, lnum); err = dbg_check_ltab_lnum(c, lnum);
if (err) { if (err) {
ubifs_err("failed at LEB %d", lnum); ubifs_err(c, "failed at LEB %d", lnum);
return err; return err;
} }
} }
...@@ -1757,7 +1757,7 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c) ...@@ -1757,7 +1757,7 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c)
free += c->leb_size; free += c->leb_size;
} }
if (free < c->lpt_sz) { if (free < c->lpt_sz) {
ubifs_err("LPT space error: free %lld lpt_sz %lld", ubifs_err(c, "LPT space error: free %lld lpt_sz %lld",
free, c->lpt_sz); free, c->lpt_sz);
ubifs_dump_lpt_info(c); ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c); ubifs_dump_lpt_lebs(c);
...@@ -1797,12 +1797,12 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) ...@@ -1797,12 +1797,12 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
d->chk_lpt_lebs = 0; d->chk_lpt_lebs = 0;
d->chk_lpt_wastage = 0; d->chk_lpt_wastage = 0;
if (c->dirty_pn_cnt > c->pnode_cnt) { if (c->dirty_pn_cnt > c->pnode_cnt) {
ubifs_err("dirty pnodes %d exceed max %d", ubifs_err(c, "dirty pnodes %d exceed max %d",
c->dirty_pn_cnt, c->pnode_cnt); c->dirty_pn_cnt, c->pnode_cnt);
err = -EINVAL; err = -EINVAL;
} }
if (c->dirty_nn_cnt > c->nnode_cnt) { if (c->dirty_nn_cnt > c->nnode_cnt) {
ubifs_err("dirty nnodes %d exceed max %d", ubifs_err(c, "dirty nnodes %d exceed max %d",
c->dirty_nn_cnt, c->nnode_cnt); c->dirty_nn_cnt, c->nnode_cnt);
err = -EINVAL; err = -EINVAL;
} }
...@@ -1820,22 +1820,22 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) ...@@ -1820,22 +1820,22 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
chk_lpt_sz *= d->chk_lpt_lebs; chk_lpt_sz *= d->chk_lpt_lebs;
chk_lpt_sz += len - c->nhead_offs; chk_lpt_sz += len - c->nhead_offs;
if (d->chk_lpt_sz != chk_lpt_sz) { if (d->chk_lpt_sz != chk_lpt_sz) {
ubifs_err("LPT wrote %lld but space used was %lld", ubifs_err(c, "LPT wrote %lld but space used was %lld",
d->chk_lpt_sz, chk_lpt_sz); d->chk_lpt_sz, chk_lpt_sz);
err = -EINVAL; err = -EINVAL;
} }
if (d->chk_lpt_sz > c->lpt_sz) { if (d->chk_lpt_sz > c->lpt_sz) {
ubifs_err("LPT wrote %lld but lpt_sz is %lld", ubifs_err(c, "LPT wrote %lld but lpt_sz is %lld",
d->chk_lpt_sz, c->lpt_sz); d->chk_lpt_sz, c->lpt_sz);
err = -EINVAL; err = -EINVAL;
} }
if (d->chk_lpt_sz2 && d->chk_lpt_sz != d->chk_lpt_sz2) { if (d->chk_lpt_sz2 && d->chk_lpt_sz != d->chk_lpt_sz2) {
ubifs_err("LPT layout size %lld but wrote %lld", ubifs_err(c, "LPT layout size %lld but wrote %lld",
d->chk_lpt_sz, d->chk_lpt_sz2); d->chk_lpt_sz, d->chk_lpt_sz2);
err = -EINVAL; err = -EINVAL;
} }
if (d->chk_lpt_sz2 && d->new_nhead_offs != len) { if (d->chk_lpt_sz2 && d->new_nhead_offs != len) {
ubifs_err("LPT new nhead offs: expected %d was %d", ubifs_err(c, "LPT new nhead offs: expected %d was %d",
d->new_nhead_offs, len); d->new_nhead_offs, len);
err = -EINVAL; err = -EINVAL;
} }
...@@ -1845,7 +1845,7 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) ...@@ -1845,7 +1845,7 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
if (c->big_lpt) if (c->big_lpt)
lpt_sz += c->lsave_sz; lpt_sz += c->lsave_sz;
if (d->chk_lpt_sz - d->chk_lpt_wastage > lpt_sz) { if (d->chk_lpt_sz - d->chk_lpt_wastage > lpt_sz) {
ubifs_err("LPT chk_lpt_sz %lld + waste %lld exceeds %lld", ubifs_err(c, "LPT chk_lpt_sz %lld + waste %lld exceeds %lld",
d->chk_lpt_sz, d->chk_lpt_wastage, lpt_sz); d->chk_lpt_sz, d->chk_lpt_wastage, lpt_sz);
err = -EINVAL; err = -EINVAL;
} }
...@@ -1887,7 +1887,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum) ...@@ -1887,7 +1887,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
pr_err("(pid %d) start dumping LEB %d\n", current->pid, lnum); pr_err("(pid %d) start dumping LEB %d\n", current->pid, lnum);
buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
if (!buf) { if (!buf) {
ubifs_err("cannot allocate memory to dump LPT"); ubifs_err(c, "cannot allocate memory to dump LPT");
return; return;
} }
...@@ -1962,7 +1962,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum) ...@@ -1962,7 +1962,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
pr_err("LEB %d:%d, lsave len\n", lnum, offs); pr_err("LEB %d:%d, lsave len\n", lnum, offs);
break; break;
default: default:
ubifs_err("LPT node type %d not recognized", node_type); ubifs_err(c, "LPT node type %d not recognized", node_type);
goto out; goto out;
} }
......
...@@ -82,7 +82,7 @@ static int scan_for_master(struct ubifs_info *c) ...@@ -82,7 +82,7 @@ static int scan_for_master(struct ubifs_info *c)
return -EUCLEAN; return -EUCLEAN;
out_dump: out_dump:
ubifs_err("unexpected node type %d master LEB %d:%d", ubifs_err(c, "unexpected node type %d master LEB %d:%d",
snod->type, lnum, snod->offs); snod->type, lnum, snod->offs);
ubifs_scan_destroy(sleb); ubifs_scan_destroy(sleb);
return -EINVAL; return -EINVAL;
...@@ -240,7 +240,7 @@ static int validate_master(const struct ubifs_info *c) ...@@ -240,7 +240,7 @@ static int validate_master(const struct ubifs_info *c)
return 0; return 0;
out: out:
ubifs_err("bad master node at offset %d error %d", c->mst_offs, err); ubifs_err(c, "bad master node at offset %d error %d", c->mst_offs, err);
ubifs_dump_node(c, c->mst_node); ubifs_dump_node(c, c->mst_node);
return -EINVAL; return -EINVAL;
} }
...@@ -316,7 +316,7 @@ int ubifs_read_master(struct ubifs_info *c) ...@@ -316,7 +316,7 @@ int ubifs_read_master(struct ubifs_info *c)
if (c->leb_cnt < old_leb_cnt || if (c->leb_cnt < old_leb_cnt ||
c->leb_cnt < UBIFS_MIN_LEB_CNT) { c->leb_cnt < UBIFS_MIN_LEB_CNT) {
ubifs_err("bad leb_cnt on master node"); ubifs_err(c, "bad leb_cnt on master node");
ubifs_dump_node(c, c->mst_node); ubifs_dump_node(c, c->mst_node);
return -EINVAL; return -EINVAL;
} }
......
...@@ -88,7 +88,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) ...@@ -88,7 +88,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
else if (inum > o->inum) else if (inum > o->inum)
p = &(*p)->rb_right; p = &(*p)->rb_right;
else { else {
ubifs_err("orphaned twice"); ubifs_err(c, "orphaned twice");
spin_unlock(&c->orphan_lock); spin_unlock(&c->orphan_lock);
kfree(orphan); kfree(orphan);
return 0; return 0;
...@@ -155,7 +155,7 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) ...@@ -155,7 +155,7 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
} }
} }
spin_unlock(&c->orphan_lock); spin_unlock(&c->orphan_lock);
ubifs_err("missing orphan ino %lu", (unsigned long)inum); ubifs_err(c, "missing orphan ino %lu", (unsigned long)inum);
dump_stack(); dump_stack();
} }
...@@ -287,7 +287,7 @@ static int write_orph_node(struct ubifs_info *c, int atomic) ...@@ -287,7 +287,7 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
* We limit the number of orphans so that this should * We limit the number of orphans so that this should
* never happen. * never happen.
*/ */
ubifs_err("out of space in orphan area"); ubifs_err(c, "out of space in orphan area");
return -EINVAL; return -EINVAL;
} }
} }
...@@ -397,7 +397,7 @@ static int consolidate(struct ubifs_info *c) ...@@ -397,7 +397,7 @@ static int consolidate(struct ubifs_info *c)
* We limit the number of orphans so that this should * We limit the number of orphans so that this should
* never happen. * never happen.
*/ */
ubifs_err("out of space in orphan area"); ubifs_err(c, "out of space in orphan area");
err = -EINVAL; err = -EINVAL;
} }
spin_unlock(&c->orphan_lock); spin_unlock(&c->orphan_lock);
...@@ -569,7 +569,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb, ...@@ -569,7 +569,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
list_for_each_entry(snod, &sleb->nodes, list) { list_for_each_entry(snod, &sleb->nodes, list) {
if (snod->type != UBIFS_ORPH_NODE) { if (snod->type != UBIFS_ORPH_NODE) {
ubifs_err("invalid node type %d in orphan area at %d:%d", ubifs_err(c, "invalid node type %d in orphan area at %d:%d",
snod->type, sleb->lnum, snod->offs); snod->type, sleb->lnum, snod->offs);
ubifs_dump_node(c, snod->node); ubifs_dump_node(c, snod->node);
return -EINVAL; return -EINVAL;
...@@ -596,7 +596,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb, ...@@ -596,7 +596,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
* number. That makes this orphan node, out of date. * number. That makes this orphan node, out of date.
*/ */
if (!first) { if (!first) {
ubifs_err("out of order commit number %llu in orphan node at %d:%d", ubifs_err(c, "out of order commit number %llu in orphan node at %d:%d",
cmt_no, sleb->lnum, snod->offs); cmt_no, sleb->lnum, snod->offs);
ubifs_dump_node(c, snod->node); ubifs_dump_node(c, snod->node);
return -EINVAL; return -EINVAL;
...@@ -831,20 +831,20 @@ static int dbg_orphan_check(struct ubifs_info *c, struct ubifs_zbranch *zbr, ...@@ -831,20 +831,20 @@ static int dbg_orphan_check(struct ubifs_info *c, struct ubifs_zbranch *zbr,
if (inum != ci->last_ino) { if (inum != ci->last_ino) {
/* Lowest node type is the inode node, so it comes first */ /* Lowest node type is the inode node, so it comes first */
if (key_type(c, &zbr->key) != UBIFS_INO_KEY) if (key_type(c, &zbr->key) != UBIFS_INO_KEY)
ubifs_err("found orphan node ino %lu, type %d", ubifs_err(c, "found orphan node ino %lu, type %d",
(unsigned long)inum, key_type(c, &zbr->key)); (unsigned long)inum, key_type(c, &zbr->key));
ci->last_ino = inum; ci->last_ino = inum;
ci->tot_inos += 1; ci->tot_inos += 1;
err = ubifs_tnc_read_node(c, zbr, ci->node); err = ubifs_tnc_read_node(c, zbr, ci->node);
if (err) { if (err) {
ubifs_err("node read failed, error %d", err); ubifs_err(c, "node read failed, error %d", err);
return err; return err;
} }
if (ci->node->nlink == 0) if (ci->node->nlink == 0)
/* Must be recorded as an orphan */ /* Must be recorded as an orphan */
if (!dbg_find_check_orphan(&ci->root, inum) && if (!dbg_find_check_orphan(&ci->root, inum) &&
!dbg_find_orphan(c, inum)) { !dbg_find_orphan(c, inum)) {
ubifs_err("missing orphan, ino %lu", ubifs_err(c, "missing orphan, ino %lu",
(unsigned long)inum); (unsigned long)inum);
ci->missing += 1; ci->missing += 1;
} }
...@@ -887,7 +887,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci) ...@@ -887,7 +887,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci)
buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
if (!buf) { if (!buf) {
ubifs_err("cannot allocate memory to check orphans"); ubifs_err(c, "cannot allocate memory to check orphans");
return 0; return 0;
} }
...@@ -925,7 +925,7 @@ static int dbg_check_orphans(struct ubifs_info *c) ...@@ -925,7 +925,7 @@ static int dbg_check_orphans(struct ubifs_info *c)
ci.root = RB_ROOT; ci.root = RB_ROOT;
ci.node = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS); ci.node = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS);
if (!ci.node) { if (!ci.node) {
ubifs_err("out of memory"); ubifs_err(c, "out of memory");
return -ENOMEM; return -ENOMEM;
} }
...@@ -935,12 +935,12 @@ static int dbg_check_orphans(struct ubifs_info *c) ...@@ -935,12 +935,12 @@ static int dbg_check_orphans(struct ubifs_info *c)
err = dbg_walk_index(c, &dbg_orphan_check, NULL, &ci); err = dbg_walk_index(c, &dbg_orphan_check, NULL, &ci);
if (err) { if (err) {
ubifs_err("cannot scan TNC, error %d", err); ubifs_err(c, "cannot scan TNC, error %d", err);
goto out; goto out;
} }
if (ci.missing) { if (ci.missing) {
ubifs_err("%lu missing orphan(s)", ci.missing); ubifs_err(c, "%lu missing orphan(s)", ci.missing);
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
......
...@@ -305,7 +305,7 @@ int ubifs_recover_master_node(struct ubifs_info *c) ...@@ -305,7 +305,7 @@ int ubifs_recover_master_node(struct ubifs_info *c)
mst = mst2; mst = mst2;
} }
ubifs_msg("recovered master node from LEB %d", ubifs_msg(c, "recovered master node from LEB %d",
(mst == mst1 ? UBIFS_MST_LNUM : UBIFS_MST_LNUM + 1)); (mst == mst1 ? UBIFS_MST_LNUM : UBIFS_MST_LNUM + 1));
memcpy(c->mst_node, mst, UBIFS_MST_NODE_SZ); memcpy(c->mst_node, mst, UBIFS_MST_NODE_SZ);
...@@ -360,13 +360,13 @@ int ubifs_recover_master_node(struct ubifs_info *c) ...@@ -360,13 +360,13 @@ int ubifs_recover_master_node(struct ubifs_info *c)
out_err: out_err:
err = -EINVAL; err = -EINVAL;
out_free: out_free:
ubifs_err("failed to recover master node"); ubifs_err(c, "failed to recover master node");
if (mst1) { if (mst1) {
ubifs_err("dumping first master node"); ubifs_err(c, "dumping first master node");
ubifs_dump_node(c, mst1); ubifs_dump_node(c, mst1);
} }
if (mst2) { if (mst2) {
ubifs_err("dumping second master node"); ubifs_err(c, "dumping second master node");
ubifs_dump_node(c, mst2); ubifs_dump_node(c, mst2);
} }
vfree(buf2); vfree(buf2);
...@@ -682,7 +682,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, ...@@ -682,7 +682,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
ret, lnum, offs); ret, lnum, offs);
break; break;
} else { } else {
ubifs_err("unexpected return value %d", ret); ubifs_err(c, "unexpected return value %d", ret);
err = -EINVAL; err = -EINVAL;
goto error; goto error;
} }
...@@ -702,7 +702,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, ...@@ -702,7 +702,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
* See header comment for this file for more * See header comment for this file for more
* explanations about the reasons we have this check. * explanations about the reasons we have this check.
*/ */
ubifs_err("corrupt empty space LEB %d:%d, corruption starts at %d", ubifs_err(c, "corrupt empty space LEB %d:%d, corruption starts at %d",
lnum, offs, corruption); lnum, offs, corruption);
/* Make sure we dump interesting non-0xFF data */ /* Make sure we dump interesting non-0xFF data */
offs += corruption; offs += corruption;
...@@ -788,13 +788,13 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, ...@@ -788,13 +788,13 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
corrupted_rescan: corrupted_rescan:
/* Re-scan the corrupted data with verbose messages */ /* Re-scan the corrupted data with verbose messages */
ubifs_err("corruption %d", ret); ubifs_err(c, "corruption %d", ret);
ubifs_scan_a_node(c, buf, len, lnum, offs, 1); ubifs_scan_a_node(c, buf, len, lnum, offs, 1);
corrupted: corrupted:
ubifs_scanned_corruption(c, lnum, offs, buf); ubifs_scanned_corruption(c, lnum, offs, buf);
err = -EUCLEAN; err = -EUCLEAN;
error: error:
ubifs_err("LEB %d scanning failed", lnum); ubifs_err(c, "LEB %d scanning failed", lnum);
ubifs_scan_destroy(sleb); ubifs_scan_destroy(sleb);
return ERR_PTR(err); return ERR_PTR(err);
} }
...@@ -826,15 +826,15 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs, ...@@ -826,15 +826,15 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs,
goto out_free; goto out_free;
ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0); ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0);
if (ret != SCANNED_A_NODE) { if (ret != SCANNED_A_NODE) {
ubifs_err("Not a valid node"); ubifs_err(c, "Not a valid node");
goto out_err; goto out_err;
} }
if (cs_node->ch.node_type != UBIFS_CS_NODE) { if (cs_node->ch.node_type != UBIFS_CS_NODE) {
ubifs_err("Node a CS node, type is %d", cs_node->ch.node_type); ubifs_err(c, "Node a CS node, type is %d", cs_node->ch.node_type);
goto out_err; goto out_err;
} }
if (le64_to_cpu(cs_node->cmt_no) != c->cmt_no) { if (le64_to_cpu(cs_node->cmt_no) != c->cmt_no) {
ubifs_err("CS node cmt_no %llu != current cmt_no %llu", ubifs_err(c, "CS node cmt_no %llu != current cmt_no %llu",
(unsigned long long)le64_to_cpu(cs_node->cmt_no), (unsigned long long)le64_to_cpu(cs_node->cmt_no),
c->cmt_no); c->cmt_no);
goto out_err; goto out_err;
...@@ -847,7 +847,7 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs, ...@@ -847,7 +847,7 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs,
out_err: out_err:
err = -EINVAL; err = -EINVAL;
out_free: out_free:
ubifs_err("failed to get CS sqnum"); ubifs_err(c, "failed to get CS sqnum");
kfree(cs_node); kfree(cs_node);
return err; return err;
} }
...@@ -899,7 +899,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, ...@@ -899,7 +899,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
} }
} }
if (snod->sqnum > cs_sqnum) { if (snod->sqnum > cs_sqnum) {
ubifs_err("unrecoverable log corruption in LEB %d", ubifs_err(c, "unrecoverable log corruption in LEB %d",
lnum); lnum);
ubifs_scan_destroy(sleb); ubifs_scan_destroy(sleb);
return ERR_PTR(-EUCLEAN); return ERR_PTR(-EUCLEAN);
...@@ -975,11 +975,8 @@ int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf) ...@@ -975,11 +975,8 @@ int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf)
return err; return err;
dbg_rcvry("checking LPT head at %d:%d", c->nhead_lnum, c->nhead_offs); dbg_rcvry("checking LPT head at %d:%d", c->nhead_lnum, c->nhead_offs);
err = recover_head(c, c->nhead_lnum, c->nhead_offs, sbuf);
if (err)
return err;
return 0; return recover_head(c, c->nhead_lnum, c->nhead_offs, sbuf);
} }
/** /**
...@@ -1004,10 +1001,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c, ...@@ -1004,10 +1001,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c,
if (len == 0) { if (len == 0) {
/* Nothing to read, just unmap it */ /* Nothing to read, just unmap it */
err = ubifs_leb_unmap(c, lnum); return ubifs_leb_unmap(c, lnum);
if (err)
return err;
return 0;
} }
err = ubifs_leb_read(c, lnum, buf, offs, len, 0); err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
...@@ -1043,7 +1037,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c, ...@@ -1043,7 +1037,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c,
} }
if (ret == SCANNED_EMPTY_SPACE) { if (ret == SCANNED_EMPTY_SPACE) {
ubifs_err("unexpected empty space at %d:%d", ubifs_err(c, "unexpected empty space at %d:%d",
lnum, offs); lnum, offs);
return -EUCLEAN; return -EUCLEAN;
} }
...@@ -1137,7 +1131,7 @@ static int grab_empty_leb(struct ubifs_info *c) ...@@ -1137,7 +1131,7 @@ static int grab_empty_leb(struct ubifs_info *c)
*/ */
lnum = ubifs_find_free_leb_for_idx(c); lnum = ubifs_find_free_leb_for_idx(c);
if (lnum < 0) { if (lnum < 0) {
ubifs_err("could not find an empty LEB"); ubifs_err(c, "could not find an empty LEB");
ubifs_dump_lprops(c); ubifs_dump_lprops(c);
ubifs_dump_budg(c, &c->bi); ubifs_dump_budg(c, &c->bi);
return lnum; return lnum;
...@@ -1217,7 +1211,7 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c) ...@@ -1217,7 +1211,7 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
} }
mutex_unlock(&wbuf->io_mutex); mutex_unlock(&wbuf->io_mutex);
if (err < 0) { if (err < 0) {
ubifs_err("GC failed, error %d", err); ubifs_err(c, "GC failed, error %d", err);
if (err == -EAGAIN) if (err == -EAGAIN)
err = -EINVAL; err = -EINVAL;
return err; return err;
...@@ -1464,7 +1458,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e) ...@@ -1464,7 +1458,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
return 0; return 0;
out: out:
ubifs_warn("inode %lu failed to fix size %lld -> %lld error %d", ubifs_warn(c, "inode %lu failed to fix size %lld -> %lld error %d",
(unsigned long)e->inum, e->i_size, e->d_size, err); (unsigned long)e->inum, e->i_size, e->d_size, err);
return err; return err;
} }
......
...@@ -458,13 +458,13 @@ int ubifs_validate_entry(struct ubifs_info *c, ...@@ -458,13 +458,13 @@ int ubifs_validate_entry(struct ubifs_info *c,
nlen > UBIFS_MAX_NLEN || dent->name[nlen] != 0 || nlen > UBIFS_MAX_NLEN || dent->name[nlen] != 0 ||
strnlen(dent->name, nlen) != nlen || strnlen(dent->name, nlen) != nlen ||
le64_to_cpu(dent->inum) > MAX_INUM) { le64_to_cpu(dent->inum) > MAX_INUM) {
ubifs_err("bad %s node", key_type == UBIFS_DENT_KEY ? ubifs_err(c, "bad %s node", key_type == UBIFS_DENT_KEY ?
"directory entry" : "extended attribute entry"); "directory entry" : "extended attribute entry");
return -EINVAL; return -EINVAL;
} }
if (key_type != UBIFS_DENT_KEY && key_type != UBIFS_XENT_KEY) { if (key_type != UBIFS_DENT_KEY && key_type != UBIFS_XENT_KEY) {
ubifs_err("bad key type %d", key_type); ubifs_err(c, "bad key type %d", key_type);
return -EINVAL; return -EINVAL;
} }
...@@ -589,7 +589,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) ...@@ -589,7 +589,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
cond_resched(); cond_resched();
if (snod->sqnum >= SQNUM_WATERMARK) { if (snod->sqnum >= SQNUM_WATERMARK) {
ubifs_err("file system's life ended"); ubifs_err(c, "file system's life ended");
goto out_dump; goto out_dump;
} }
...@@ -647,7 +647,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) ...@@ -647,7 +647,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
if (old_size < 0 || old_size > c->max_inode_sz || if (old_size < 0 || old_size > c->max_inode_sz ||
new_size < 0 || new_size > c->max_inode_sz || new_size < 0 || new_size > c->max_inode_sz ||
old_size <= new_size) { old_size <= new_size) {
ubifs_err("bad truncation node"); ubifs_err(c, "bad truncation node");
goto out_dump; goto out_dump;
} }
...@@ -662,7 +662,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) ...@@ -662,7 +662,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
break; break;
} }
default: default:
ubifs_err("unexpected node type %d in bud LEB %d:%d", ubifs_err(c, "unexpected node type %d in bud LEB %d:%d",
snod->type, lnum, snod->offs); snod->type, lnum, snod->offs);
err = -EINVAL; err = -EINVAL;
goto out_dump; goto out_dump;
...@@ -685,7 +685,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) ...@@ -685,7 +685,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
return err; return err;
out_dump: out_dump:
ubifs_err("bad node is at LEB %d:%d", lnum, snod->offs); ubifs_err(c, "bad node is at LEB %d:%d", lnum, snod->offs);
ubifs_dump_node(c, snod->node); ubifs_dump_node(c, snod->node);
ubifs_scan_destroy(sleb); ubifs_scan_destroy(sleb);
return -EINVAL; return -EINVAL;
...@@ -805,7 +805,7 @@ static int validate_ref(struct ubifs_info *c, const struct ubifs_ref_node *ref) ...@@ -805,7 +805,7 @@ static int validate_ref(struct ubifs_info *c, const struct ubifs_ref_node *ref)
if (bud) { if (bud) {
if (bud->jhead == jhead && bud->start <= offs) if (bud->jhead == jhead && bud->start <= offs)
return 1; return 1;
ubifs_err("bud at LEB %d:%d was already referred", lnum, offs); ubifs_err(c, "bud at LEB %d:%d was already referred", lnum, offs);
return -EINVAL; return -EINVAL;
} }
...@@ -861,12 +861,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) ...@@ -861,12 +861,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
* numbers. * numbers.
*/ */
if (snod->type != UBIFS_CS_NODE) { if (snod->type != UBIFS_CS_NODE) {
ubifs_err("first log node at LEB %d:%d is not CS node", ubifs_err(c, "first log node at LEB %d:%d is not CS node",
lnum, offs); lnum, offs);
goto out_dump; goto out_dump;
} }
if (le64_to_cpu(node->cmt_no) != c->cmt_no) { if (le64_to_cpu(node->cmt_no) != c->cmt_no) {
ubifs_err("first CS node at LEB %d:%d has wrong commit number %llu expected %llu", ubifs_err(c, "first CS node at LEB %d:%d has wrong commit number %llu expected %llu",
lnum, offs, lnum, offs,
(unsigned long long)le64_to_cpu(node->cmt_no), (unsigned long long)le64_to_cpu(node->cmt_no),
c->cmt_no); c->cmt_no);
...@@ -891,7 +891,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) ...@@ -891,7 +891,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
/* Make sure the first node sits at offset zero of the LEB */ /* Make sure the first node sits at offset zero of the LEB */
if (snod->offs != 0) { if (snod->offs != 0) {
ubifs_err("first node is not at zero offset"); ubifs_err(c, "first node is not at zero offset");
goto out_dump; goto out_dump;
} }
...@@ -899,12 +899,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) ...@@ -899,12 +899,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
cond_resched(); cond_resched();
if (snod->sqnum >= SQNUM_WATERMARK) { if (snod->sqnum >= SQNUM_WATERMARK) {
ubifs_err("file system's life ended"); ubifs_err(c, "file system's life ended");
goto out_dump; goto out_dump;
} }
if (snod->sqnum < c->cs_sqnum) { if (snod->sqnum < c->cs_sqnum) {
ubifs_err("bad sqnum %llu, commit sqnum %llu", ubifs_err(c, "bad sqnum %llu, commit sqnum %llu",
snod->sqnum, c->cs_sqnum); snod->sqnum, c->cs_sqnum);
goto out_dump; goto out_dump;
} }
...@@ -934,12 +934,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) ...@@ -934,12 +934,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
case UBIFS_CS_NODE: case UBIFS_CS_NODE:
/* Make sure it sits at the beginning of LEB */ /* Make sure it sits at the beginning of LEB */
if (snod->offs != 0) { if (snod->offs != 0) {
ubifs_err("unexpected node in log"); ubifs_err(c, "unexpected node in log");
goto out_dump; goto out_dump;
} }
break; break;
default: default:
ubifs_err("unexpected node in log"); ubifs_err(c, "unexpected node in log");
goto out_dump; goto out_dump;
} }
} }
...@@ -955,7 +955,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) ...@@ -955,7 +955,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
return err; return err;
out_dump: out_dump:
ubifs_err("log error detected while replaying the log at LEB %d:%d", ubifs_err(c, "log error detected while replaying the log at LEB %d:%d",
lnum, offs + snod->offs); lnum, offs + snod->offs);
ubifs_dump_node(c, snod->node); ubifs_dump_node(c, snod->node);
ubifs_scan_destroy(sleb); ubifs_scan_destroy(sleb);
...@@ -1017,7 +1017,7 @@ int ubifs_replay_journal(struct ubifs_info *c) ...@@ -1017,7 +1017,7 @@ int ubifs_replay_journal(struct ubifs_info *c)
return free; /* Error code */ return free; /* Error code */
if (c->ihead_offs != c->leb_size - free) { if (c->ihead_offs != c->leb_size - free) {
ubifs_err("bad index head LEB %d:%d", c->ihead_lnum, ubifs_err(c, "bad index head LEB %d:%d", c->ihead_lnum,
c->ihead_offs); c->ihead_offs);
return -EINVAL; return -EINVAL;
} }
...@@ -1040,7 +1040,7 @@ int ubifs_replay_journal(struct ubifs_info *c) ...@@ -1040,7 +1040,7 @@ int ubifs_replay_journal(struct ubifs_info *c)
* someting went wrong and we cannot proceed mounting * someting went wrong and we cannot proceed mounting
* the file-system. * the file-system.
*/ */
ubifs_err("no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted", ubifs_err(c, "no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted",
lnum, 0); lnum, 0);
err = -EINVAL; err = -EINVAL;
} }
......
...@@ -335,7 +335,7 @@ static int create_default_filesystem(struct ubifs_info *c) ...@@ -335,7 +335,7 @@ static int create_default_filesystem(struct ubifs_info *c)
if (err) if (err)
return err; return err;
ubifs_msg("default file-system created"); ubifs_msg(c, "default file-system created");
return 0; return 0;
} }
...@@ -365,13 +365,13 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup) ...@@ -365,13 +365,13 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
} }
if (le32_to_cpu(sup->min_io_size) != c->min_io_size) { if (le32_to_cpu(sup->min_io_size) != c->min_io_size) {
ubifs_err("min. I/O unit mismatch: %d in superblock, %d real", ubifs_err(c, "min. I/O unit mismatch: %d in superblock, %d real",
le32_to_cpu(sup->min_io_size), c->min_io_size); le32_to_cpu(sup->min_io_size), c->min_io_size);
goto failed; goto failed;
} }
if (le32_to_cpu(sup->leb_size) != c->leb_size) { if (le32_to_cpu(sup->leb_size) != c->leb_size) {
ubifs_err("LEB size mismatch: %d in superblock, %d real", ubifs_err(c, "LEB size mismatch: %d in superblock, %d real",
le32_to_cpu(sup->leb_size), c->leb_size); le32_to_cpu(sup->leb_size), c->leb_size);
goto failed; goto failed;
} }
...@@ -393,33 +393,33 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup) ...@@ -393,33 +393,33 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
min_leb_cnt += c->lpt_lebs + c->orph_lebs + c->jhead_cnt + 6; min_leb_cnt += c->lpt_lebs + c->orph_lebs + c->jhead_cnt + 6;
if (c->leb_cnt < min_leb_cnt || c->leb_cnt > c->vi.size) { if (c->leb_cnt < min_leb_cnt || c->leb_cnt > c->vi.size) {
ubifs_err("bad LEB count: %d in superblock, %d on UBI volume, %d minimum required", ubifs_err(c, "bad LEB count: %d in superblock, %d on UBI volume, %d minimum required",
c->leb_cnt, c->vi.size, min_leb_cnt); c->leb_cnt, c->vi.size, min_leb_cnt);
goto failed; goto failed;
} }
if (c->max_leb_cnt < c->leb_cnt) { if (c->max_leb_cnt < c->leb_cnt) {
ubifs_err("max. LEB count %d less than LEB count %d", ubifs_err(c, "max. LEB count %d less than LEB count %d",
c->max_leb_cnt, c->leb_cnt); c->max_leb_cnt, c->leb_cnt);
goto failed; goto failed;
} }
if (c->main_lebs < UBIFS_MIN_MAIN_LEBS) { if (c->main_lebs < UBIFS_MIN_MAIN_LEBS) {
ubifs_err("too few main LEBs count %d, must be at least %d", ubifs_err(c, "too few main LEBs count %d, must be at least %d",
c->main_lebs, UBIFS_MIN_MAIN_LEBS); c->main_lebs, UBIFS_MIN_MAIN_LEBS);
goto failed; goto failed;
} }
max_bytes = (long long)c->leb_size * UBIFS_MIN_BUD_LEBS; max_bytes = (long long)c->leb_size * UBIFS_MIN_BUD_LEBS;
if (c->max_bud_bytes < max_bytes) { if (c->max_bud_bytes < max_bytes) {
ubifs_err("too small journal (%lld bytes), must be at least %lld bytes", ubifs_err(c, "too small journal (%lld bytes), must be at least %lld bytes",
c->max_bud_bytes, max_bytes); c->max_bud_bytes, max_bytes);
goto failed; goto failed;
} }
max_bytes = (long long)c->leb_size * c->main_lebs; max_bytes = (long long)c->leb_size * c->main_lebs;
if (c->max_bud_bytes > max_bytes) { if (c->max_bud_bytes > max_bytes) {
ubifs_err("too large journal size (%lld bytes), only %lld bytes available in the main area", ubifs_err(c, "too large journal size (%lld bytes), only %lld bytes available in the main area",
c->max_bud_bytes, max_bytes); c->max_bud_bytes, max_bytes);
goto failed; goto failed;
} }
...@@ -468,7 +468,7 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup) ...@@ -468,7 +468,7 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
return 0; return 0;
failed: failed:
ubifs_err("bad superblock, error %d", err); ubifs_err(c, "bad superblock, error %d", err);
ubifs_dump_node(c, sup); ubifs_dump_node(c, sup);
return -EINVAL; return -EINVAL;
} }
...@@ -549,12 +549,12 @@ int ubifs_read_superblock(struct ubifs_info *c) ...@@ -549,12 +549,12 @@ int ubifs_read_superblock(struct ubifs_info *c)
ubifs_assert(!c->ro_media || c->ro_mount); ubifs_assert(!c->ro_media || c->ro_mount);
if (!c->ro_mount || if (!c->ro_mount ||
c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) { c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) {
ubifs_err("on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d", ubifs_err(c, "on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d",
c->fmt_version, c->ro_compat_version, c->fmt_version, c->ro_compat_version,
UBIFS_FORMAT_VERSION, UBIFS_FORMAT_VERSION,
UBIFS_RO_COMPAT_VERSION); UBIFS_RO_COMPAT_VERSION);
if (c->ro_compat_version <= UBIFS_RO_COMPAT_VERSION) { if (c->ro_compat_version <= UBIFS_RO_COMPAT_VERSION) {
ubifs_msg("only R/O mounting is possible"); ubifs_msg(c, "only R/O mounting is possible");
err = -EROFS; err = -EROFS;
} else } else
err = -EINVAL; err = -EINVAL;
...@@ -570,7 +570,7 @@ int ubifs_read_superblock(struct ubifs_info *c) ...@@ -570,7 +570,7 @@ int ubifs_read_superblock(struct ubifs_info *c)
} }
if (c->fmt_version < 3) { if (c->fmt_version < 3) {
ubifs_err("on-flash format version %d is not supported", ubifs_err(c, "on-flash format version %d is not supported",
c->fmt_version); c->fmt_version);
err = -EINVAL; err = -EINVAL;
goto out; goto out;
...@@ -595,7 +595,7 @@ int ubifs_read_superblock(struct ubifs_info *c) ...@@ -595,7 +595,7 @@ int ubifs_read_superblock(struct ubifs_info *c)
c->key_len = UBIFS_SK_LEN; c->key_len = UBIFS_SK_LEN;
break; break;
default: default:
ubifs_err("unsupported key format"); ubifs_err(c, "unsupported key format");
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -785,7 +785,7 @@ int ubifs_fixup_free_space(struct ubifs_info *c) ...@@ -785,7 +785,7 @@ int ubifs_fixup_free_space(struct ubifs_info *c)
ubifs_assert(c->space_fixup); ubifs_assert(c->space_fixup);
ubifs_assert(!c->ro_mount); ubifs_assert(!c->ro_mount);
ubifs_msg("start fixing up free space"); ubifs_msg(c, "start fixing up free space");
err = fixup_free_space(c); err = fixup_free_space(c);
if (err) if (err)
...@@ -804,6 +804,6 @@ int ubifs_fixup_free_space(struct ubifs_info *c) ...@@ -804,6 +804,6 @@ int ubifs_fixup_free_space(struct ubifs_info *c)
if (err) if (err)
return err; return err;
ubifs_msg("free space fixup complete"); ubifs_msg(c, "free space fixup complete");
return err; return err;
} }
...@@ -100,7 +100,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, ...@@ -100,7 +100,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
if (pad_len < 0 || if (pad_len < 0 ||
offs + node_len + pad_len > c->leb_size) { offs + node_len + pad_len > c->leb_size) {
if (!quiet) { if (!quiet) {
ubifs_err("bad pad node at LEB %d:%d", ubifs_err(c, "bad pad node at LEB %d:%d",
lnum, offs); lnum, offs);
ubifs_dump_node(c, pad); ubifs_dump_node(c, pad);
} }
...@@ -110,7 +110,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, ...@@ -110,7 +110,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
/* Make the node pads to 8-byte boundary */ /* Make the node pads to 8-byte boundary */
if ((node_len + pad_len) & 7) { if ((node_len + pad_len) & 7) {
if (!quiet) if (!quiet)
ubifs_err("bad padding length %d - %d", ubifs_err(c, "bad padding length %d - %d",
offs, offs + node_len + pad_len); offs, offs + node_len + pad_len);
return SCANNED_A_BAD_PAD_NODE; return SCANNED_A_BAD_PAD_NODE;
} }
...@@ -152,7 +152,7 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum, ...@@ -152,7 +152,7 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum,
err = ubifs_leb_read(c, lnum, sbuf + offs, offs, c->leb_size - offs, 0); err = ubifs_leb_read(c, lnum, sbuf + offs, offs, c->leb_size - offs, 0);
if (err && err != -EBADMSG) { if (err && err != -EBADMSG) {
ubifs_err("cannot read %d bytes from LEB %d:%d, error %d", ubifs_err(c, "cannot read %d bytes from LEB %d:%d, error %d",
c->leb_size - offs, lnum, offs, err); c->leb_size - offs, lnum, offs, err);
kfree(sleb); kfree(sleb);
return ERR_PTR(err); return ERR_PTR(err);
...@@ -240,11 +240,11 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, ...@@ -240,11 +240,11 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,
{ {
int len; int len;
ubifs_err("corruption at LEB %d:%d", lnum, offs); ubifs_err(c, "corruption at LEB %d:%d", lnum, offs);
len = c->leb_size - offs; len = c->leb_size - offs;
if (len > 8192) if (len > 8192)
len = 8192; len = 8192;
ubifs_err("first %d bytes from LEB %d:%d", len, lnum, offs); ubifs_err(c, "first %d bytes from LEB %d:%d", len, lnum, offs);
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1);
} }
...@@ -299,16 +299,16 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, ...@@ -299,16 +299,16 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
switch (ret) { switch (ret) {
case SCANNED_GARBAGE: case SCANNED_GARBAGE:
ubifs_err("garbage"); ubifs_err(c, "garbage");
goto corrupted; goto corrupted;
case SCANNED_A_NODE: case SCANNED_A_NODE:
break; break;
case SCANNED_A_CORRUPT_NODE: case SCANNED_A_CORRUPT_NODE:
case SCANNED_A_BAD_PAD_NODE: case SCANNED_A_BAD_PAD_NODE:
ubifs_err("bad node"); ubifs_err(c, "bad node");
goto corrupted; goto corrupted;
default: default:
ubifs_err("unknown"); ubifs_err(c, "unknown");
err = -EINVAL; err = -EINVAL;
goto error; goto error;
} }
...@@ -325,7 +325,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, ...@@ -325,7 +325,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
if (offs % c->min_io_size) { if (offs % c->min_io_size) {
if (!quiet) if (!quiet)
ubifs_err("empty space starts at non-aligned offset %d", ubifs_err(c, "empty space starts at non-aligned offset %d",
offs); offs);
goto corrupted; goto corrupted;
} }
...@@ -338,7 +338,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, ...@@ -338,7 +338,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
for (; len; offs++, buf++, len--) for (; len; offs++, buf++, len--)
if (*(uint8_t *)buf != 0xff) { if (*(uint8_t *)buf != 0xff) {
if (!quiet) if (!quiet)
ubifs_err("corrupt empty space at LEB %d:%d", ubifs_err(c, "corrupt empty space at LEB %d:%d",
lnum, offs); lnum, offs);
goto corrupted; goto corrupted;
} }
...@@ -348,14 +348,14 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, ...@@ -348,14 +348,14 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
corrupted: corrupted:
if (!quiet) { if (!quiet) {
ubifs_scanned_corruption(c, lnum, offs, buf); ubifs_scanned_corruption(c, lnum, offs, buf);
ubifs_err("LEB %d scanning failed", lnum); ubifs_err(c, "LEB %d scanning failed", lnum);
} }
err = -EUCLEAN; err = -EUCLEAN;
ubifs_scan_destroy(sleb); ubifs_scan_destroy(sleb);
return ERR_PTR(err); return ERR_PTR(err);
error: error:
ubifs_err("LEB %d scanning failed, error %d", lnum, err); ubifs_err(c, "LEB %d scanning failed, error %d", lnum, err);
ubifs_scan_destroy(sleb); ubifs_scan_destroy(sleb);
return ERR_PTR(err); return ERR_PTR(err);
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment