summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ubifs/debug.c52
-rw-r--r--fs/ubifs/debug.h22
2 files changed, 39 insertions, 35 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 1e880cedefa4..b801af7837e9 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2548,39 +2548,36 @@ static int simple_rand(void)
return (next >> 16) & 32767;
}
-static int do_fail(struct ubifs_info *c, int lnum, int write)
+static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
{
struct ubifs_debug_info *d = c->dbg;
ubifs_assert(dbg_is_tst_rcvry(c));
- if (d->failure_mode)
- return 1;
-
- if (!d->fail_cnt) {
- /* First call - decide delay to failure */
+ if (!d->pc_cnt) {
+ /* First call - decide delay to the power cut */
if (chance(1, 2)) {
unsigned int delay = 1 << (simple_rand() >> 11);
if (chance(1, 2)) {
- d->fail_delay = 1;
- d->fail_timeout = jiffies +
+ d->pc_delay = 1;
+ d->pc_timeout = jiffies +
msecs_to_jiffies(delay);
ubifs_warn("failing after %ums", delay);
} else {
- d->fail_delay = 2;
- d->fail_cnt_max = delay;
+ d->pc_delay = 2;
+ d->pc_cnt_max = delay;
ubifs_warn("failing after %u calls", delay);
}
}
- d->fail_cnt += 1;
+ d->pc_cnt += 1;
}
/* Determine if failure delay has expired */
- if (d->fail_delay == 1) {
- if (time_before(jiffies, d->fail_timeout))
+ if (d->pc_delay == 1) {
+ if (time_before(jiffies, d->pc_timeout))
return 0;
- } else if (d->fail_delay == 2)
- if (d->fail_cnt++ < d->fail_cnt_max)
+ } else if (d->pc_delay == 2)
+ if (d->pc_cnt++ < d->pc_cnt_max)
return 0;
if (lnum == UBIFS_SB_LNUM) {
if (write) {
@@ -2638,7 +2635,7 @@ static int do_fail(struct ubifs_info *c, int lnum, int write)
ubifs_warn("failing in bud LEB %d commit not running", lnum);
}
- d->failure_mode = 1;
+ d->pc_happened = 1;
dump_stack();
return 1;
}
@@ -2658,9 +2655,10 @@ int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
{
int err, failing;
- if (c->dbg->failure_mode)
+ if (c->dbg->pc_happened)
return -EROFS;
- failing = do_fail(c, lnum, 1);
+
+ failing = power_cut_emulated(c, lnum, 1);
if (failing)
cut_data(buf, len);
err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
@@ -2676,12 +2674,14 @@ int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf,
{
int err;
- if (do_fail(c, lnum, 1))
+ if (c->dbg->pc_happened)
+ return -EROFS;
+ if (power_cut_emulated(c, lnum, 1))
return -EROFS;
err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
if (err)
return err;
- if (do_fail(c, lnum, 1))
+ if (power_cut_emulated(c, lnum, 1))
return -EROFS;
return 0;
}
@@ -2690,12 +2690,14 @@ int dbg_leb_unmap(struct ubifs_info *c, int lnum)
{
int err;
- if (do_fail(c, lnum, 0))
+ if (c->dbg->pc_happened)
+ return -EROFS;
+ if (power_cut_emulated(c, lnum, 0))
return -EROFS;
err = ubi_leb_unmap(c->ubi, lnum);
if (err)
return err;
- if (do_fail(c, lnum, 0))
+ if (power_cut_emulated(c, lnum, 0))
return -EROFS;
return 0;
}
@@ -2704,12 +2706,14 @@ int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype)
{
int err;
- if (do_fail(c, lnum, 0))
+ if (c->dbg->pc_happened)
+ return -EROFS;
+ if (power_cut_emulated(c, lnum, 0))
return -EROFS;
err = ubi_leb_map(c->ubi, lnum, dtype);
if (err)
return err;
- if (do_fail(c, lnum, 0))
+ if (power_cut_emulated(c, lnum, 0))
return -EROFS;
return 0;
}
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 0ab3757ef0e3..45174b534377 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -44,11 +44,11 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
* @old_zroot_level: old index root level - used by 'dbg_check_old_index()'
* @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()'
*
- * @failure_mode: failure mode for recovery testing
- * @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
- * @fail_timeout: time in jiffies when delay of failure mode expires
- * @fail_cnt: current number of calls to failure mode I/O functions
- * @fail_cnt_max: number of calls by which to delay failure mode
+ * @pc_happened: non-zero if an emulated power cut happened
+ * @pc_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
+ * @pc_timeout: time in jiffies when delay of failure mode expires
+ * @pc_cnt: current number of calls to failure mode I/O functions
+ * @pc_cnt_max: number of calls by which to delay failure mode
*
* @chk_lpt_sz: used by LPT tree size checker
* @chk_lpt_sz2: used by LPT tree size checker
@@ -87,11 +87,11 @@ struct ubifs_debug_info {
int old_zroot_level;
unsigned long long old_zroot_sqnum;
- int failure_mode;
- int fail_delay;
- unsigned long fail_timeout;
- unsigned int fail_cnt;
- unsigned int fail_cnt_max;
+ int pc_happened;
+ int pc_delay;
+ unsigned long pc_timeout;
+ unsigned int pc_cnt;
+ unsigned int pc_cnt_max;
long long chk_lpt_sz;
long long chk_lpt_sz2;
@@ -246,7 +246,7 @@ static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
}
static inline int dbg_is_power_cut(const struct ubifs_info *c)
{
- return !!c->dbg->failure_mode;
+ return !!c->dbg->pc_happened;
}
int ubifs_debugging_init(struct ubifs_info *c);