aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-03-29 11:36:21 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-05-13 12:23:54 -0400
commitf1bd66afb14c25095cf6ff499c1388db423acc9e (patch)
tree9199aab4896fc9ed89213a407942bf4e49232fe0
parent8c3067e445fb25119761356c88abc39dacfb9524 (diff)
UBIFS: improve space checking debugging feature
This patch improves the 'dbg_check_space_info()' function which checks whether the amount of space before re-mounting and after re-mounting is the same (remounting from R/O to R/W modes and vice-versa). The problem is that 'dbg_check_space_info()' does not save the budgeting information before re-mounting, so when an error is reported, we do not know why the amount of free space changed. This patches makes the following changes: 1. Teaches 'dbg_dump_budg()' function to accept a 'struct ubifs_budg_info' argument and print out the this argument. This way we may ask it to print any saved budgeting info, no only the current one. 2. Accordingly changes all the callers of 'dbg_dump_budg()' to comply with the changed interface. 3. Introduce a 'saved_bi' (saved budgeting info) field to 'struct ubifs_debug_info' and save the budgeting info before re-mounting there. 4. Change 'dbg_check_space_info()' and make it print both old and new budgeting information. 5. Additionally, save 'c->igx_gc_cnt' and print it if and error happens. This value contributes to the amount of free space, so we have to print it. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--fs/ubifs/debug.c42
-rw-r--r--fs/ubifs/debug.h12
-rw-r--r--fs/ubifs/journal.c2
-rw-r--r--fs/ubifs/super.c2
-rw-r--r--fs/ubifs/tnc_commit.c2
5 files changed, 41 insertions, 19 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 8e8bba937331..546ad575b660 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -602,7 +602,7 @@ void dbg_dump_lstats(const struct ubifs_lp_stats *lst)
602 spin_unlock(&dbg_lock); 602 spin_unlock(&dbg_lock);
603} 603}
604 604
605void dbg_dump_budg(struct ubifs_info *c) 605void dbg_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
606{ 606{
607 int i; 607 int i;
608 struct rb_node *rb; 608 struct rb_node *rb;
@@ -614,20 +614,29 @@ void dbg_dump_budg(struct ubifs_info *c)
614 spin_lock(&dbg_lock); 614 spin_lock(&dbg_lock);
615 printk(KERN_DEBUG "(pid %d) Budgeting info: data budget sum %lld, " 615 printk(KERN_DEBUG "(pid %d) Budgeting info: data budget sum %lld, "
616 "total budget sum %lld\n", current->pid, 616 "total budget sum %lld\n", current->pid,
617 c->bi.data_growth + c->bi.dd_growth, 617 bi->data_growth + bi->dd_growth,
618 c->bi.data_growth + c->bi.dd_growth + c->bi.idx_growth); 618 bi->data_growth + bi->dd_growth + bi->idx_growth);
619 printk(KERN_DEBUG "\tbudg_data_growth %lld, budg_dd_growth %lld, " 619 printk(KERN_DEBUG "\tbudg_data_growth %lld, budg_dd_growth %lld, "
620 "budg_idx_growth %lld\n", c->bi.data_growth, c->bi.dd_growth, 620 "budg_idx_growth %lld\n", bi->data_growth, bi->dd_growth,
621 c->bi.idx_growth); 621 bi->idx_growth);
622 printk(KERN_DEBUG "\tmin_idx_lebs %d, old_idx_sz %llu, " 622 printk(KERN_DEBUG "\tmin_idx_lebs %d, old_idx_sz %llu, "
623 "uncommitted_idx %lld\n", c->bi.min_idx_lebs, c->bi.old_idx_sz, 623 "uncommitted_idx %lld\n", bi->min_idx_lebs, bi->old_idx_sz,
624 c->bi.uncommitted_idx); 624 bi->uncommitted_idx);
625 printk(KERN_DEBUG "\tpage_budget %d, inode_budget %d, dent_budget %d\n", 625 printk(KERN_DEBUG "\tpage_budget %d, inode_budget %d, dent_budget %d\n",
626 c->bi.page_budget, c->bi.inode_budget, c->bi.dent_budget); 626 bi->page_budget, bi->inode_budget, bi->dent_budget);
627 printk(KERN_DEBUG "\tnospace %u, nospace_rp %u\n", 627 printk(KERN_DEBUG "\tnospace %u, nospace_rp %u\n",
628 c->bi.nospace, c->bi.nospace_rp); 628 bi->nospace, bi->nospace_rp);
629 printk(KERN_DEBUG "\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n", 629 printk(KERN_DEBUG "\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n",
630 c->dark_wm, c->dead_wm, c->max_idx_node_sz); 630 c->dark_wm, c->dead_wm, c->max_idx_node_sz);
631
632 if (bi != &c->bi)
633 /*
634 * If we are dumping saved budgeting data, do not print
635 * additional information which is about the current state, not
636 * the old one which corresponded to the saved budgeting data.
637 */
638 goto out_unlock;
639
631 printk(KERN_DEBUG "\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d\n", 640 printk(KERN_DEBUG "\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d\n",
632 c->freeable_cnt, c->calc_idx_sz, c->idx_gc_cnt); 641 c->freeable_cnt, c->calc_idx_sz, c->idx_gc_cnt);
633 printk(KERN_DEBUG "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, " 642 printk(KERN_DEBUG "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, "
@@ -636,6 +645,7 @@ void dbg_dump_budg(struct ubifs_info *c)
636 atomic_long_read(&c->clean_zn_cnt)); 645 atomic_long_read(&c->clean_zn_cnt));
637 printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n", 646 printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n",
638 c->gc_lnum, c->ihead_lnum); 647 c->gc_lnum, c->ihead_lnum);
648
639 /* If we are in R/O mode, journal heads do not exist */ 649 /* If we are in R/O mode, journal heads do not exist */
640 if (c->jheads) 650 if (c->jheads)
641 for (i = 0; i < c->jhead_cnt; i++) 651 for (i = 0; i < c->jhead_cnt; i++)
@@ -660,6 +670,7 @@ void dbg_dump_budg(struct ubifs_info *c)
660 printk(KERN_DEBUG "Budgeting predictions:\n"); 670 printk(KERN_DEBUG "Budgeting predictions:\n");
661 printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n", 671 printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n",
662 available, outstanding, free); 672 available, outstanding, free);
673out_unlock:
663 spin_unlock(&dbg_lock); 674 spin_unlock(&dbg_lock);
664 spin_unlock(&c->space_lock); 675 spin_unlock(&c->space_lock);
665} 676}
@@ -983,6 +994,8 @@ void dbg_save_space_info(struct ubifs_info *c)
983 994
984 spin_lock(&c->space_lock); 995 spin_lock(&c->space_lock);
985 memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats)); 996 memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats));
997 memcpy(&d->saved_bi, &c->bi, sizeof(struct ubifs_budg_info));
998 d->saved_idx_gc_cnt = c->idx_gc_cnt;
986 999
987 /* 1000 /*
988 * We use a dirty hack here and zero out @c->freeable_cnt, because it 1001 * We use a dirty hack here and zero out @c->freeable_cnt, because it
@@ -1049,11 +1062,14 @@ int dbg_check_space_info(struct ubifs_info *c)
1049out: 1062out:
1050 ubifs_msg("saved lprops statistics dump"); 1063 ubifs_msg("saved lprops statistics dump");
1051 dbg_dump_lstats(&d->saved_lst); 1064 dbg_dump_lstats(&d->saved_lst);
1052 ubifs_get_lp_stats(c, &lst); 1065 ubifs_msg("saved budgeting info dump");
1053 1066 dbg_dump_budg(c, &d->saved_bi);
1067 ubifs_msg("saved idx_gc_cnt %d", d->saved_idx_gc_cnt);
1054 ubifs_msg("current lprops statistics dump"); 1068 ubifs_msg("current lprops statistics dump");
1069 ubifs_get_lp_stats(c, &lst);
1055 dbg_dump_lstats(&lst); 1070 dbg_dump_lstats(&lst);
1056 dbg_dump_budg(c); 1071 ubifs_msg("current budgeting info dump");
1072 dbg_dump_budg(c, &c->bi);
1057 dump_stack(); 1073 dump_stack();
1058 return -EINVAL; 1074 return -EINVAL;
1059} 1075}
@@ -2801,7 +2817,7 @@ static ssize_t write_debugfs_file(struct file *file, const char __user *buf,
2801 if (file->f_path.dentry == d->dfs_dump_lprops) 2817 if (file->f_path.dentry == d->dfs_dump_lprops)
2802 dbg_dump_lprops(c); 2818 dbg_dump_lprops(c);
2803 else if (file->f_path.dentry == d->dfs_dump_budg) 2819 else if (file->f_path.dentry == d->dfs_dump_budg)
2804 dbg_dump_budg(c); 2820 dbg_dump_budg(c, &c->bi);
2805 else if (file->f_path.dentry == d->dfs_dump_tnc) { 2821 else if (file->f_path.dentry == d->dfs_dump_tnc) {
2806 mutex_lock(&c->tnc_mutex); 2822 mutex_lock(&c->tnc_mutex);
2807 dbg_dump_tnc(c); 2823 dbg_dump_tnc(c);
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index e6493cac193d..6b5fe7ba0296 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -50,7 +50,9 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
50 * @new_ihead_offs: used by debugging to check @c->ihead_offs 50 * @new_ihead_offs: used by debugging to check @c->ihead_offs
51 * 51 *
52 * @saved_lst: saved lprops statistics (used by 'dbg_save_space_info()') 52 * @saved_lst: saved lprops statistics (used by 'dbg_save_space_info()')
53 * @saved_free: saved free space (used by 'dbg_save_space_info()') 53 * @saved_bi: saved budgeting information
54 * @saved_free: saved amount of free space
55 * @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt
54 * 56 *
55 * dfs_dir_name: name of debugfs directory containing this file-system's files 57 * dfs_dir_name: name of debugfs directory containing this file-system's files
56 * dfs_dir: direntry object of the file-system debugfs directory 58 * dfs_dir: direntry object of the file-system debugfs directory
@@ -76,7 +78,9 @@ struct ubifs_debug_info {
76 int new_ihead_offs; 78 int new_ihead_offs;
77 79
78 struct ubifs_lp_stats saved_lst; 80 struct ubifs_lp_stats saved_lst;
81 struct ubifs_budg_info saved_bi;
79 long long saved_free; 82 long long saved_free;
83 int saved_idx_gc_cnt;
80 84
81 char dfs_dir_name[100]; 85 char dfs_dir_name[100];
82 struct dentry *dfs_dir; 86 struct dentry *dfs_dir;
@@ -262,7 +266,7 @@ void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum,
262 int offs); 266 int offs);
263void dbg_dump_budget_req(const struct ubifs_budget_req *req); 267void dbg_dump_budget_req(const struct ubifs_budget_req *req);
264void dbg_dump_lstats(const struct ubifs_lp_stats *lst); 268void dbg_dump_lstats(const struct ubifs_lp_stats *lst);
265void dbg_dump_budg(struct ubifs_info *c); 269void dbg_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi);
266void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp); 270void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp);
267void dbg_dump_lprops(struct ubifs_info *c); 271void dbg_dump_lprops(struct ubifs_info *c);
268void dbg_dump_lpt_info(struct ubifs_info *c); 272void dbg_dump_lpt_info(struct ubifs_info *c);
@@ -420,7 +424,9 @@ static inline void
420dbg_dump_budget_req(const struct ubifs_budget_req *req) { return; } 424dbg_dump_budget_req(const struct ubifs_budget_req *req) { return; }
421static inline void 425static inline void
422dbg_dump_lstats(const struct ubifs_lp_stats *lst) { return; } 426dbg_dump_lstats(const struct ubifs_lp_stats *lst) { return; }
423static inline void dbg_dump_budg(struct ubifs_info *c) { return; } 427static inline void
428dbg_dump_budg(struct ubifs_info *c,
429 const struct ubifs_budg_info *bi) { return; }
424static inline void dbg_dump_lprop(const struct ubifs_info *c, 430static inline void dbg_dump_lprop(const struct ubifs_info *c,
425 const struct ubifs_lprops *lp) { return; } 431 const struct ubifs_lprops *lp) { return; }
426static inline void dbg_dump_lprops(struct ubifs_info *c) { return; } 432static inline void dbg_dump_lprops(struct ubifs_info *c) { return; }
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 65d485fc1eeb..ce55a4807cdc 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -381,7 +381,7 @@ out:
381 /* This are some budgeting problems, print useful information */ 381 /* This are some budgeting problems, print useful information */
382 down_write(&c->commit_sem); 382 down_write(&c->commit_sem);
383 dbg_dump_stack(); 383 dbg_dump_stack();
384 dbg_dump_budg(c); 384 dbg_dump_budg(c, &c->bi);
385 dbg_dump_lprops(c); 385 dbg_dump_lprops(c);
386 cmt_retries = dbg_check_lprops(c); 386 cmt_retries = dbg_check_lprops(c);
387 up_write(&c->commit_sem); 387 up_write(&c->commit_sem);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index a0aa95117ea1..407c064fb1c1 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1145,7 +1145,7 @@ static int check_free_space(struct ubifs_info *c)
1145 ubifs_assert(c->dark_wm > 0); 1145 ubifs_assert(c->dark_wm > 0);
1146 if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) { 1146 if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) {
1147 ubifs_err("insufficient free space to mount in R/W mode"); 1147 ubifs_err("insufficient free space to mount in R/W mode");
1148 dbg_dump_budg(c); 1148 dbg_dump_budg(c, &c->bi);
1149 dbg_dump_lprops(c); 1149 dbg_dump_lprops(c);
1150 return -ENOSPC; 1150 return -ENOSPC;
1151 } 1151 }
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index 66f066de2c57..c471b06798c8 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -383,7 +383,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
383 * option which forces in-the-gaps is enabled. 383 * option which forces in-the-gaps is enabled.
384 */ 384 */
385 ubifs_err("out of space"); 385 ubifs_err("out of space");
386 dbg_dump_budg(c); 386 dbg_dump_budg(c, &c->bi);
387 dbg_dump_lprops(c); 387 dbg_dump_lprops(c);
388 } 388 }
389 /* Try to commit anyway */ 389 /* Try to commit anyway */