diff options
Diffstat (limited to 'fs/ubifs/debug.c')
-rw-r--r-- | fs/ubifs/debug.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 510ffa0bbda4..0332a856a082 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -705,7 +705,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum) | |||
705 | 705 | ||
706 | printk(KERN_DEBUG "(pid %d) Dumping LEB %d\n", current->pid, lnum); | 706 | printk(KERN_DEBUG "(pid %d) Dumping LEB %d\n", current->pid, lnum); |
707 | 707 | ||
708 | sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); | 708 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf); |
709 | if (IS_ERR(sleb)) { | 709 | if (IS_ERR(sleb)) { |
710 | ubifs_err("scan error %d", (int)PTR_ERR(sleb)); | 710 | ubifs_err("scan error %d", (int)PTR_ERR(sleb)); |
711 | return; | 711 | return; |
@@ -2097,7 +2097,7 @@ static int simple_rand(void) | |||
2097 | return (next >> 16) & 32767; | 2097 | return (next >> 16) & 32767; |
2098 | } | 2098 | } |
2099 | 2099 | ||
2100 | void dbg_failure_mode_registration(struct ubifs_info *c) | 2100 | static void failure_mode_init(struct ubifs_info *c) |
2101 | { | 2101 | { |
2102 | struct failure_mode_info *fmi; | 2102 | struct failure_mode_info *fmi; |
2103 | 2103 | ||
@@ -2112,7 +2112,7 @@ void dbg_failure_mode_registration(struct ubifs_info *c) | |||
2112 | spin_unlock(&fmi_lock); | 2112 | spin_unlock(&fmi_lock); |
2113 | } | 2113 | } |
2114 | 2114 | ||
2115 | void dbg_failure_mode_deregistration(struct ubifs_info *c) | 2115 | static void failure_mode_exit(struct ubifs_info *c) |
2116 | { | 2116 | { |
2117 | struct failure_mode_info *fmi, *tmp; | 2117 | struct failure_mode_info *fmi, *tmp; |
2118 | 2118 | ||
@@ -2146,42 +2146,44 @@ static int in_failure_mode(struct ubi_volume_desc *desc) | |||
2146 | struct ubifs_info *c = dbg_find_info(desc); | 2146 | struct ubifs_info *c = dbg_find_info(desc); |
2147 | 2147 | ||
2148 | if (c && dbg_failure_mode) | 2148 | if (c && dbg_failure_mode) |
2149 | return c->failure_mode; | 2149 | return c->dbg->failure_mode; |
2150 | return 0; | 2150 | return 0; |
2151 | } | 2151 | } |
2152 | 2152 | ||
2153 | static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) | 2153 | static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) |
2154 | { | 2154 | { |
2155 | struct ubifs_info *c = dbg_find_info(desc); | 2155 | struct ubifs_info *c = dbg_find_info(desc); |
2156 | struct ubifs_debug_info *d; | ||
2156 | 2157 | ||
2157 | if (!c || !dbg_failure_mode) | 2158 | if (!c || !dbg_failure_mode) |
2158 | return 0; | 2159 | return 0; |
2159 | if (c->failure_mode) | 2160 | d = c->dbg; |
2161 | if (d->failure_mode) | ||
2160 | return 1; | 2162 | return 1; |
2161 | if (!c->fail_cnt) { | 2163 | if (!d->fail_cnt) { |
2162 | /* First call - decide delay to failure */ | 2164 | /* First call - decide delay to failure */ |
2163 | if (chance(1, 2)) { | 2165 | if (chance(1, 2)) { |
2164 | unsigned int delay = 1 << (simple_rand() >> 11); | 2166 | unsigned int delay = 1 << (simple_rand() >> 11); |
2165 | 2167 | ||
2166 | if (chance(1, 2)) { | 2168 | if (chance(1, 2)) { |
2167 | c->fail_delay = 1; | 2169 | d->fail_delay = 1; |
2168 | c->fail_timeout = jiffies + | 2170 | d->fail_timeout = jiffies + |
2169 | msecs_to_jiffies(delay); | 2171 | msecs_to_jiffies(delay); |
2170 | dbg_rcvry("failing after %ums", delay); | 2172 | dbg_rcvry("failing after %ums", delay); |
2171 | } else { | 2173 | } else { |
2172 | c->fail_delay = 2; | 2174 | d->fail_delay = 2; |
2173 | c->fail_cnt_max = delay; | 2175 | d->fail_cnt_max = delay; |
2174 | dbg_rcvry("failing after %u calls", delay); | 2176 | dbg_rcvry("failing after %u calls", delay); |
2175 | } | 2177 | } |
2176 | } | 2178 | } |
2177 | c->fail_cnt += 1; | 2179 | d->fail_cnt += 1; |
2178 | } | 2180 | } |
2179 | /* Determine if failure delay has expired */ | 2181 | /* Determine if failure delay has expired */ |
2180 | if (c->fail_delay == 1) { | 2182 | if (d->fail_delay == 1) { |
2181 | if (time_before(jiffies, c->fail_timeout)) | 2183 | if (time_before(jiffies, d->fail_timeout)) |
2182 | return 0; | 2184 | return 0; |
2183 | } else if (c->fail_delay == 2) | 2185 | } else if (d->fail_delay == 2) |
2184 | if (c->fail_cnt++ < c->fail_cnt_max) | 2186 | if (d->fail_cnt++ < d->fail_cnt_max) |
2185 | return 0; | 2187 | return 0; |
2186 | if (lnum == UBIFS_SB_LNUM) { | 2188 | if (lnum == UBIFS_SB_LNUM) { |
2187 | if (write) { | 2189 | if (write) { |
@@ -2239,7 +2241,7 @@ static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) | |||
2239 | dbg_rcvry("failing in bud LEB %d commit not running", lnum); | 2241 | dbg_rcvry("failing in bud LEB %d commit not running", lnum); |
2240 | } | 2242 | } |
2241 | ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum); | 2243 | ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum); |
2242 | c->failure_mode = 1; | 2244 | d->failure_mode = 1; |
2243 | dump_stack(); | 2245 | dump_stack(); |
2244 | return 1; | 2246 | return 1; |
2245 | } | 2247 | } |
@@ -2344,4 +2346,41 @@ int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) | |||
2344 | return 0; | 2346 | return 0; |
2345 | } | 2347 | } |
2346 | 2348 | ||
2349 | /** | ||
2350 | * ubifs_debugging_init - initialize UBIFS debugging. | ||
2351 | * @c: UBIFS file-system description object | ||
2352 | * | ||
2353 | * This function initializes debugging-related data for the file system. | ||
2354 | * Returns zero in case of success and a negative error code in case of | ||
2355 | * failure. | ||
2356 | */ | ||
2357 | int ubifs_debugging_init(struct ubifs_info *c) | ||
2358 | { | ||
2359 | c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL); | ||
2360 | if (!c->dbg) | ||
2361 | return -ENOMEM; | ||
2362 | |||
2363 | c->dbg->buf = vmalloc(c->leb_size); | ||
2364 | if (!c->dbg->buf) | ||
2365 | goto out; | ||
2366 | |||
2367 | failure_mode_init(c); | ||
2368 | return 0; | ||
2369 | |||
2370 | out: | ||
2371 | kfree(c->dbg); | ||
2372 | return -ENOMEM; | ||
2373 | } | ||
2374 | |||
2375 | /** | ||
2376 | * ubifs_debugging_exit - free debugging data. | ||
2377 | * @c: UBIFS file-system description object | ||
2378 | */ | ||
2379 | void ubifs_debugging_exit(struct ubifs_info *c) | ||
2380 | { | ||
2381 | failure_mode_exit(c); | ||
2382 | vfree(c->dbg->buf); | ||
2383 | kfree(c->dbg); | ||
2384 | } | ||
2385 | |||
2347 | #endif /* CONFIG_UBIFS_FS_DEBUG */ | 2386 | #endif /* CONFIG_UBIFS_FS_DEBUG */ |