aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-06-03 09:20:03 -0400
committerArtem Bityutskiy <dedekind1@gmail.com>2011-07-04 03:54:34 -0400
commita7fa94a9fe26a4925914083a31b5387bca530eb1 (patch)
treee745f630a78b473379e9d0866a9b1be25b528677
parentd27462a518c31a4b1093ad866229f85b2b765e7e (diff)
UBIFS: improve power cut emulation testing
This patch cleans-up and improves the power cut testing: 1. Kill custom 'simple_random()' function and use 'random32()' instead. 2. Make timeout larger 3. When cutting the buffer - fill the end with random data sometimes, not only with 0xFFs. 4. Some times cut in the middle of the buffer, not always at the end. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--fs/ubifs/debug.c91
1 files changed, 50 insertions, 41 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index b801af7837e9..eef109a1a927 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -27,11 +27,12 @@
27 * various local functions of those subsystems. 27 * various local functions of those subsystems.
28 */ 28 */
29 29
30#include "ubifs.h"
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/debugfs.h> 31#include <linux/debugfs.h>
33#include <linux/math64.h> 32#include <linux/math64.h>
34#include <linux/uaccess.h> 33#include <linux/uaccess.h>
34#include <linux/random.h>
35#include "ubifs.h"
35 36
36#ifdef CONFIG_UBIFS_FS_DEBUG 37#ifdef CONFIG_UBIFS_FS_DEBUG
37 38
@@ -2535,17 +2536,10 @@ error_dump:
2535 return 0; 2536 return 0;
2536} 2537}
2537 2538
2538/* Failure mode for recovery testing */ 2539static inline int chance(unsigned int n, unsigned int out_of)
2539
2540#define chance(n, d) (simple_rand() <= (n) * 32768LL / (d))
2541
2542static unsigned int next;
2543static int simple_rand(void)
2544{ 2540{
2545 if (next == 0) 2541 return !!((random32() % out_of) + 1 <= n);
2546 next = current->pid; 2542
2547 next = next * 1103515245 + 12345;
2548 return (next >> 16) & 32767;
2549} 2543}
2550 2544
2551static int power_cut_emulated(struct ubifs_info *c, int lnum, int write) 2545static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
@@ -2557,33 +2551,37 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
2557 if (!d->pc_cnt) { 2551 if (!d->pc_cnt) {
2558 /* First call - decide delay to the power cut */ 2552 /* First call - decide delay to the power cut */
2559 if (chance(1, 2)) { 2553 if (chance(1, 2)) {
2560 unsigned int delay = 1 << (simple_rand() >> 11); 2554 unsigned long delay;
2561 2555
2562 if (chance(1, 2)) { 2556 if (chance(1, 2)) {
2563 d->pc_delay = 1; 2557 d->pc_delay = 1;
2564 d->pc_timeout = jiffies + 2558 /* Fail withing 1 minute */
2565 msecs_to_jiffies(delay); 2559 delay = random32() % 60000;
2566 ubifs_warn("failing after %ums", delay); 2560 d->pc_timeout = jiffies;
2561 d->pc_timeout += msecs_to_jiffies(delay);
2562 ubifs_warn("failing after %lums", delay);
2567 } else { 2563 } else {
2568 d->pc_delay = 2; 2564 d->pc_delay = 2;
2565 delay = random32() % 10000;
2566 /* Fail within 10000 operations */
2569 d->pc_cnt_max = delay; 2567 d->pc_cnt_max = delay;
2570 ubifs_warn("failing after %u calls", delay); 2568 ubifs_warn("failing after %lu calls", delay);
2571 } 2569 }
2572 } 2570 }
2571
2573 d->pc_cnt += 1; 2572 d->pc_cnt += 1;
2574 } 2573 }
2574
2575 /* Determine if failure delay has expired */ 2575 /* Determine if failure delay has expired */
2576 if (d->pc_delay == 1) { 2576 if (d->pc_delay == 1 && time_before(jiffies, d->pc_timeout))
2577 if (time_before(jiffies, d->pc_timeout))
2578 return 0; 2577 return 0;
2579 } else if (d->pc_delay == 2) 2578 if (d->pc_delay == 2 && d->pc_cnt++ < d->pc_cnt_max)
2580 if (d->pc_cnt++ < d->pc_cnt_max)
2581 return 0; 2579 return 0;
2580
2582 if (lnum == UBIFS_SB_LNUM) { 2581 if (lnum == UBIFS_SB_LNUM) {
2583 if (write) { 2582 if (write && chance(1, 2))
2584 if (chance(1, 2)) 2583 return 0;
2585 return 0; 2584 if (chance(19, 20))
2586 } else if (chance(19, 20))
2587 return 0; 2585 return 0;
2588 ubifs_warn("failing in super block LEB %d", lnum); 2586 ubifs_warn("failing in super block LEB %d", lnum);
2589 } else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) { 2587 } else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) {
@@ -2591,24 +2589,21 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
2591 return 0; 2589 return 0;
2592 ubifs_warn("failing in master LEB %d", lnum); 2590 ubifs_warn("failing in master LEB %d", lnum);
2593 } else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) { 2591 } else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) {
2594 if (write) { 2592 if (write && chance(99, 100))
2595 if (chance(99, 100)) 2593 return 0;
2596 return 0; 2594 if (chance(399, 400))
2597 } else if (chance(399, 400))
2598 return 0; 2595 return 0;
2599 ubifs_warn("failing in log LEB %d", lnum); 2596 ubifs_warn("failing in log LEB %d", lnum);
2600 } else if (lnum >= c->lpt_first && lnum <= c->lpt_last) { 2597 } else if (lnum >= c->lpt_first && lnum <= c->lpt_last) {
2601 if (write) { 2598 if (write && chance(7, 8))
2602 if (chance(7, 8)) 2599 return 0;
2603 return 0; 2600 if (chance(19, 20))
2604 } else if (chance(19, 20))
2605 return 0; 2601 return 0;
2606 ubifs_warn("failing in LPT LEB %d", lnum); 2602 ubifs_warn("failing in LPT LEB %d", lnum);
2607 } else if (lnum >= c->orph_first && lnum <= c->orph_last) { 2603 } else if (lnum >= c->orph_first && lnum <= c->orph_last) {
2608 if (write) { 2604 if (write && chance(1, 2))
2609 if (chance(1, 2)) 2605 return 0;
2610 return 0; 2606 if (chance(9, 10))
2611 } else if (chance(9, 10))
2612 return 0; 2607 return 0;
2613 ubifs_warn("failing in orphan LEB %d", lnum); 2608 ubifs_warn("failing in orphan LEB %d", lnum);
2614 } else if (lnum == c->ihead_lnum) { 2609 } else if (lnum == c->ihead_lnum) {
@@ -2636,18 +2631,32 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
2636 } 2631 }
2637 2632
2638 d->pc_happened = 1; 2633 d->pc_happened = 1;
2634 ubifs_warn("========== Power cut emulated ==========");
2639 dump_stack(); 2635 dump_stack();
2640 return 1; 2636 return 1;
2641} 2637}
2642 2638
2643static void cut_data(const void *buf, int len) 2639static void cut_data(const void *buf, unsigned int len)
2644{ 2640{
2645 int flen, i; 2641 unsigned int from, to, i, ffs = chance(1, 2);
2646 unsigned char *p = (void *)buf; 2642 unsigned char *p = (void *)buf;
2647 2643
2648 flen = (len * (long long)simple_rand()) >> 15; 2644 from = random32() % (len + 1);
2649 for (i = flen; i < len; i++) 2645 if (chance(1, 2))
2650 p[i] = 0xff; 2646 to = random32() % (len - from + 1);
2647 else
2648 to = len;
2649
2650 if (from < to)
2651 ubifs_warn("filled bytes %u-%u with %s", from, to - 1,
2652 ffs ? "0xFFs" : "random data");
2653
2654 if (ffs)
2655 for (i = from; i < to; i++)
2656 p[i] = 0xFF;
2657 else
2658 for (i = from; i < to; i++)
2659 p[i] = random32() % 0x100;
2651} 2660}
2652 2661
2653int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, 2662int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,