aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs/debug.c')
-rw-r--r--fs/ubifs/debug.c327
1 files changed, 291 insertions, 36 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 510ffa0bbda4..e975bd82f38b 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -32,6 +32,8 @@
32#include "ubifs.h" 32#include "ubifs.h"
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/moduleparam.h> 34#include <linux/moduleparam.h>
35#include <linux/debugfs.h>
36#include <linux/math64.h>
35 37
36#ifdef CONFIG_UBIFS_FS_DEBUG 38#ifdef CONFIG_UBIFS_FS_DEBUG
37 39
@@ -596,7 +598,9 @@ void dbg_dump_budg(struct ubifs_info *c)
596 struct rb_node *rb; 598 struct rb_node *rb;
597 struct ubifs_bud *bud; 599 struct ubifs_bud *bud;
598 struct ubifs_gced_idx_leb *idx_gc; 600 struct ubifs_gced_idx_leb *idx_gc;
601 long long available, outstanding, free;
599 602
603 ubifs_assert(spin_is_locked(&c->space_lock));
600 spin_lock(&dbg_lock); 604 spin_lock(&dbg_lock);
601 printk(KERN_DEBUG "(pid %d) Budgeting info: budg_data_growth %lld, " 605 printk(KERN_DEBUG "(pid %d) Budgeting info: budg_data_growth %lld, "
602 "budg_dd_growth %lld, budg_idx_growth %lld\n", current->pid, 606 "budg_dd_growth %lld, budg_idx_growth %lld\n", current->pid,
@@ -616,9 +620,11 @@ void dbg_dump_budg(struct ubifs_info *c)
616 c->dark_wm, c->dead_wm, c->max_idx_node_sz); 620 c->dark_wm, c->dead_wm, c->max_idx_node_sz);
617 printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n", 621 printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n",
618 c->gc_lnum, c->ihead_lnum); 622 c->gc_lnum, c->ihead_lnum);
619 for (i = 0; i < c->jhead_cnt; i++) 623 /* If we are in R/O mode, journal heads do not exist */
620 printk(KERN_DEBUG "\tjhead %d\t LEB %d\n", 624 if (c->jheads)
621 c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum); 625 for (i = 0; i < c->jhead_cnt; i++)
626 printk(KERN_DEBUG "\tjhead %d\t LEB %d\n",
627 c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum);
622 for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) { 628 for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) {
623 bud = rb_entry(rb, struct ubifs_bud, rb); 629 bud = rb_entry(rb, struct ubifs_bud, rb);
624 printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum); 630 printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum);
@@ -629,6 +635,14 @@ void dbg_dump_budg(struct ubifs_info *c)
629 printk(KERN_DEBUG "\tGC'ed idx LEB %d unmap %d\n", 635 printk(KERN_DEBUG "\tGC'ed idx LEB %d unmap %d\n",
630 idx_gc->lnum, idx_gc->unmap); 636 idx_gc->lnum, idx_gc->unmap);
631 printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state); 637 printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state);
638
639 /* Print budgeting predictions */
640 available = ubifs_calc_available(c, c->min_idx_lebs);
641 outstanding = c->budg_data_growth + c->budg_dd_growth;
642 free = ubifs_get_free_space_nolock(c);
643 printk(KERN_DEBUG "Budgeting predictions:\n");
644 printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n",
645 available, outstanding, free);
632 spin_unlock(&dbg_lock); 646 spin_unlock(&dbg_lock);
633} 647}
634 648
@@ -645,7 +659,8 @@ void dbg_dump_lprops(struct ubifs_info *c)
645 struct ubifs_lprops lp; 659 struct ubifs_lprops lp;
646 struct ubifs_lp_stats lst; 660 struct ubifs_lp_stats lst;
647 661
648 printk(KERN_DEBUG "(pid %d) Dumping LEB properties\n", current->pid); 662 printk(KERN_DEBUG "(pid %d) start dumping LEB properties\n",
663 current->pid);
649 ubifs_get_lp_stats(c, &lst); 664 ubifs_get_lp_stats(c, &lst);
650 dbg_dump_lstats(&lst); 665 dbg_dump_lstats(&lst);
651 666
@@ -656,6 +671,8 @@ void dbg_dump_lprops(struct ubifs_info *c)
656 671
657 dbg_dump_lprop(c, &lp); 672 dbg_dump_lprop(c, &lp);
658 } 673 }
674 printk(KERN_DEBUG "(pid %d) finish dumping LEB properties\n",
675 current->pid);
659} 676}
660 677
661void dbg_dump_lpt_info(struct ubifs_info *c) 678void dbg_dump_lpt_info(struct ubifs_info *c)
@@ -663,6 +680,7 @@ void dbg_dump_lpt_info(struct ubifs_info *c)
663 int i; 680 int i;
664 681
665 spin_lock(&dbg_lock); 682 spin_lock(&dbg_lock);
683 printk(KERN_DEBUG "(pid %d) dumping LPT information\n", current->pid);
666 printk(KERN_DEBUG "\tlpt_sz: %lld\n", c->lpt_sz); 684 printk(KERN_DEBUG "\tlpt_sz: %lld\n", c->lpt_sz);
667 printk(KERN_DEBUG "\tpnode_sz: %d\n", c->pnode_sz); 685 printk(KERN_DEBUG "\tpnode_sz: %d\n", c->pnode_sz);
668 printk(KERN_DEBUG "\tnnode_sz: %d\n", c->nnode_sz); 686 printk(KERN_DEBUG "\tnnode_sz: %d\n", c->nnode_sz);
@@ -684,7 +702,8 @@ void dbg_dump_lpt_info(struct ubifs_info *c)
684 printk(KERN_DEBUG "\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs); 702 printk(KERN_DEBUG "\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs);
685 printk(KERN_DEBUG "\tLPT head is at %d:%d\n", 703 printk(KERN_DEBUG "\tLPT head is at %d:%d\n",
686 c->nhead_lnum, c->nhead_offs); 704 c->nhead_lnum, c->nhead_offs);
687 printk(KERN_DEBUG "\tLPT ltab is at %d:%d\n", c->ltab_lnum, c->ltab_offs); 705 printk(KERN_DEBUG "\tLPT ltab is at %d:%d\n",
706 c->ltab_lnum, c->ltab_offs);
688 if (c->big_lpt) 707 if (c->big_lpt)
689 printk(KERN_DEBUG "\tLPT lsave is at %d:%d\n", 708 printk(KERN_DEBUG "\tLPT lsave is at %d:%d\n",
690 c->lsave_lnum, c->lsave_offs); 709 c->lsave_lnum, c->lsave_offs);
@@ -703,9 +722,9 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
703 if (dbg_failure_mode) 722 if (dbg_failure_mode)
704 return; 723 return;
705 724
706 printk(KERN_DEBUG "(pid %d) Dumping LEB %d\n", current->pid, lnum); 725 printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
707 726 current->pid, lnum);
708 sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); 727 sleb = ubifs_scan(c, lnum, 0, c->dbg->buf);
709 if (IS_ERR(sleb)) { 728 if (IS_ERR(sleb)) {
710 ubifs_err("scan error %d", (int)PTR_ERR(sleb)); 729 ubifs_err("scan error %d", (int)PTR_ERR(sleb));
711 return; 730 return;
@@ -721,6 +740,8 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
721 dbg_dump_node(c, snod->node); 740 dbg_dump_node(c, snod->node);
722 } 741 }
723 742
743 printk(KERN_DEBUG "(pid %d) finish dumping LEB %d\n",
744 current->pid, lnum);
724 ubifs_scan_destroy(sleb); 745 ubifs_scan_destroy(sleb);
725 return; 746 return;
726} 747}
@@ -768,7 +789,7 @@ void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat)
768{ 789{
769 int i; 790 int i;
770 791
771 printk(KERN_DEBUG "(pid %d) Dumping heap cat %d (%d elements)\n", 792 printk(KERN_DEBUG "(pid %d) start dumping heap cat %d (%d elements)\n",
772 current->pid, cat, heap->cnt); 793 current->pid, cat, heap->cnt);
773 for (i = 0; i < heap->cnt; i++) { 794 for (i = 0; i < heap->cnt; i++) {
774 struct ubifs_lprops *lprops = heap->arr[i]; 795 struct ubifs_lprops *lprops = heap->arr[i];
@@ -777,6 +798,7 @@ void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat)
777 "flags %d\n", i, lprops->lnum, lprops->hpos, 798 "flags %d\n", i, lprops->lnum, lprops->hpos,
778 lprops->free, lprops->dirty, lprops->flags); 799 lprops->free, lprops->dirty, lprops->flags);
779 } 800 }
801 printk(KERN_DEBUG "(pid %d) finish dumping heap\n", current->pid);
780} 802}
781 803
782void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, 804void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
@@ -784,7 +806,7 @@ void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
784{ 806{
785 int i; 807 int i;
786 808
787 printk(KERN_DEBUG "(pid %d) Dumping pnode:\n", current->pid); 809 printk(KERN_DEBUG "(pid %d) dumping pnode:\n", current->pid);
788 printk(KERN_DEBUG "\taddress %zx parent %zx cnext %zx\n", 810 printk(KERN_DEBUG "\taddress %zx parent %zx cnext %zx\n",
789 (size_t)pnode, (size_t)parent, (size_t)pnode->cnext); 811 (size_t)pnode, (size_t)parent, (size_t)pnode->cnext);
790 printk(KERN_DEBUG "\tflags %lu iip %d level %d num %d\n", 812 printk(KERN_DEBUG "\tflags %lu iip %d level %d num %d\n",
@@ -803,7 +825,7 @@ void dbg_dump_tnc(struct ubifs_info *c)
803 int level; 825 int level;
804 826
805 printk(KERN_DEBUG "\n"); 827 printk(KERN_DEBUG "\n");
806 printk(KERN_DEBUG "(pid %d) Dumping the TNC tree\n", current->pid); 828 printk(KERN_DEBUG "(pid %d) start dumping TNC tree\n", current->pid);
807 znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); 829 znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL);
808 level = znode->level; 830 level = znode->level;
809 printk(KERN_DEBUG "== Level %d ==\n", level); 831 printk(KERN_DEBUG "== Level %d ==\n", level);
@@ -815,8 +837,7 @@ void dbg_dump_tnc(struct ubifs_info *c)
815 dbg_dump_znode(c, znode); 837 dbg_dump_znode(c, znode);
816 znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); 838 znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode);
817 } 839 }
818 840 printk(KERN_DEBUG "(pid %d) finish dumping TNC tree\n", current->pid);
819 printk(KERN_DEBUG "\n");
820} 841}
821 842
822static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode, 843static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode,
@@ -839,6 +860,65 @@ void dbg_dump_index(struct ubifs_info *c)
839} 860}
840 861
841/** 862/**
863 * dbg_save_space_info - save information about flash space.
864 * @c: UBIFS file-system description object
865 *
866 * This function saves information about UBIFS free space, dirty space, etc, in
867 * order to check it later.
868 */
869void dbg_save_space_info(struct ubifs_info *c)
870{
871 struct ubifs_debug_info *d = c->dbg;
872
873 ubifs_get_lp_stats(c, &d->saved_lst);
874
875 spin_lock(&c->space_lock);
876 d->saved_free = ubifs_get_free_space_nolock(c);
877 spin_unlock(&c->space_lock);
878}
879
880/**
881 * dbg_check_space_info - check flash space information.
882 * @c: UBIFS file-system description object
883 *
884 * This function compares current flash space information with the information
885 * which was saved when the 'dbg_save_space_info()' function was called.
886 * Returns zero if the information has not changed, and %-EINVAL it it has
887 * changed.
888 */
889int dbg_check_space_info(struct ubifs_info *c)
890{
891 struct ubifs_debug_info *d = c->dbg;
892 struct ubifs_lp_stats lst;
893 long long avail, free;
894
895 spin_lock(&c->space_lock);
896 avail = ubifs_calc_available(c, c->min_idx_lebs);
897 spin_unlock(&c->space_lock);
898 free = ubifs_get_free_space(c);
899
900 if (free != d->saved_free) {
901 ubifs_err("free space changed from %lld to %lld",
902 d->saved_free, free);
903 goto out;
904 }
905
906 return 0;
907
908out:
909 ubifs_msg("saved lprops statistics dump");
910 dbg_dump_lstats(&d->saved_lst);
911 ubifs_get_lp_stats(c, &lst);
912 ubifs_msg("current lprops statistics dump");
913 dbg_dump_lstats(&d->saved_lst);
914 spin_lock(&c->space_lock);
915 dbg_dump_budg(c);
916 spin_unlock(&c->space_lock);
917 dump_stack();
918 return -EINVAL;
919}
920
921/**
842 * dbg_check_synced_i_size - check synchronized inode size. 922 * dbg_check_synced_i_size - check synchronized inode size.
843 * @inode: inode to check 923 * @inode: inode to check
844 * 924 *
@@ -992,8 +1072,8 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
992 zbr1->offs, DBGKEY(&key)); 1072 zbr1->offs, DBGKEY(&key));
993 dbg_err("but it should have key %s according to tnc", 1073 dbg_err("but it should have key %s according to tnc",
994 DBGKEY(&zbr1->key)); 1074 DBGKEY(&zbr1->key));
995 dbg_dump_node(c, dent1); 1075 dbg_dump_node(c, dent1);
996 goto out_free; 1076 goto out_free;
997 } 1077 }
998 1078
999 key_read(c, &dent2->key, &key); 1079 key_read(c, &dent2->key, &key);
@@ -1002,8 +1082,8 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
1002 zbr1->offs, DBGKEY(&key)); 1082 zbr1->offs, DBGKEY(&key));
1003 dbg_err("but it should have key %s according to tnc", 1083 dbg_err("but it should have key %s according to tnc",
1004 DBGKEY(&zbr2->key)); 1084 DBGKEY(&zbr2->key));
1005 dbg_dump_node(c, dent2); 1085 dbg_dump_node(c, dent2);
1006 goto out_free; 1086 goto out_free;
1007 } 1087 }
1008 1088
1009 nlen1 = le16_to_cpu(dent1->nlen); 1089 nlen1 = le16_to_cpu(dent1->nlen);
@@ -1020,9 +1100,9 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
1020 dbg_err("bad order of colliding key %s", 1100 dbg_err("bad order of colliding key %s",
1021 DBGKEY(&key)); 1101 DBGKEY(&key));
1022 1102
1023 dbg_msg("first node at %d:%d\n", zbr1->lnum, zbr1->offs); 1103 ubifs_msg("first node at %d:%d\n", zbr1->lnum, zbr1->offs);
1024 dbg_dump_node(c, dent1); 1104 dbg_dump_node(c, dent1);
1025 dbg_msg("second node at %d:%d\n", zbr2->lnum, zbr2->offs); 1105 ubifs_msg("second node at %d:%d\n", zbr2->lnum, zbr2->offs);
1026 dbg_dump_node(c, dent2); 1106 dbg_dump_node(c, dent2);
1027 1107
1028out_free: 1108out_free:
@@ -1327,7 +1407,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
1327 * @c: UBIFS file-system description object 1407 * @c: UBIFS file-system description object
1328 * @leaf_cb: called for each leaf node 1408 * @leaf_cb: called for each leaf node
1329 * @znode_cb: called for each indexing node 1409 * @znode_cb: called for each indexing node
1330 * @priv: private date which is passed to callbacks 1410 * @priv: private data which is passed to callbacks
1331 * 1411 *
1332 * This function walks the UBIFS index and calls the @leaf_cb for each leaf 1412 * This function walks the UBIFS index and calls the @leaf_cb for each leaf
1333 * node and @znode_cb for each indexing node. Returns zero in case of success 1413 * node and @znode_cb for each indexing node. Returns zero in case of success
@@ -2097,13 +2177,13 @@ static int simple_rand(void)
2097 return (next >> 16) & 32767; 2177 return (next >> 16) & 32767;
2098} 2178}
2099 2179
2100void dbg_failure_mode_registration(struct ubifs_info *c) 2180static void failure_mode_init(struct ubifs_info *c)
2101{ 2181{
2102 struct failure_mode_info *fmi; 2182 struct failure_mode_info *fmi;
2103 2183
2104 fmi = kmalloc(sizeof(struct failure_mode_info), GFP_NOFS); 2184 fmi = kmalloc(sizeof(struct failure_mode_info), GFP_NOFS);
2105 if (!fmi) { 2185 if (!fmi) {
2106 dbg_err("Failed to register failure mode - no memory"); 2186 ubifs_err("Failed to register failure mode - no memory");
2107 return; 2187 return;
2108 } 2188 }
2109 fmi->c = c; 2189 fmi->c = c;
@@ -2112,7 +2192,7 @@ void dbg_failure_mode_registration(struct ubifs_info *c)
2112 spin_unlock(&fmi_lock); 2192 spin_unlock(&fmi_lock);
2113} 2193}
2114 2194
2115void dbg_failure_mode_deregistration(struct ubifs_info *c) 2195static void failure_mode_exit(struct ubifs_info *c)
2116{ 2196{
2117 struct failure_mode_info *fmi, *tmp; 2197 struct failure_mode_info *fmi, *tmp;
2118 2198
@@ -2146,42 +2226,44 @@ static int in_failure_mode(struct ubi_volume_desc *desc)
2146 struct ubifs_info *c = dbg_find_info(desc); 2226 struct ubifs_info *c = dbg_find_info(desc);
2147 2227
2148 if (c && dbg_failure_mode) 2228 if (c && dbg_failure_mode)
2149 return c->failure_mode; 2229 return c->dbg->failure_mode;
2150 return 0; 2230 return 0;
2151} 2231}
2152 2232
2153static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) 2233static int do_fail(struct ubi_volume_desc *desc, int lnum, int write)
2154{ 2234{
2155 struct ubifs_info *c = dbg_find_info(desc); 2235 struct ubifs_info *c = dbg_find_info(desc);
2236 struct ubifs_debug_info *d;
2156 2237
2157 if (!c || !dbg_failure_mode) 2238 if (!c || !dbg_failure_mode)
2158 return 0; 2239 return 0;
2159 if (c->failure_mode) 2240 d = c->dbg;
2241 if (d->failure_mode)
2160 return 1; 2242 return 1;
2161 if (!c->fail_cnt) { 2243 if (!d->fail_cnt) {
2162 /* First call - decide delay to failure */ 2244 /* First call - decide delay to failure */
2163 if (chance(1, 2)) { 2245 if (chance(1, 2)) {
2164 unsigned int delay = 1 << (simple_rand() >> 11); 2246 unsigned int delay = 1 << (simple_rand() >> 11);
2165 2247
2166 if (chance(1, 2)) { 2248 if (chance(1, 2)) {
2167 c->fail_delay = 1; 2249 d->fail_delay = 1;
2168 c->fail_timeout = jiffies + 2250 d->fail_timeout = jiffies +
2169 msecs_to_jiffies(delay); 2251 msecs_to_jiffies(delay);
2170 dbg_rcvry("failing after %ums", delay); 2252 dbg_rcvry("failing after %ums", delay);
2171 } else { 2253 } else {
2172 c->fail_delay = 2; 2254 d->fail_delay = 2;
2173 c->fail_cnt_max = delay; 2255 d->fail_cnt_max = delay;
2174 dbg_rcvry("failing after %u calls", delay); 2256 dbg_rcvry("failing after %u calls", delay);
2175 } 2257 }
2176 } 2258 }
2177 c->fail_cnt += 1; 2259 d->fail_cnt += 1;
2178 } 2260 }
2179 /* Determine if failure delay has expired */ 2261 /* Determine if failure delay has expired */
2180 if (c->fail_delay == 1) { 2262 if (d->fail_delay == 1) {
2181 if (time_before(jiffies, c->fail_timeout)) 2263 if (time_before(jiffies, d->fail_timeout))
2182 return 0; 2264 return 0;
2183 } else if (c->fail_delay == 2) 2265 } else if (d->fail_delay == 2)
2184 if (c->fail_cnt++ < c->fail_cnt_max) 2266 if (d->fail_cnt++ < d->fail_cnt_max)
2185 return 0; 2267 return 0;
2186 if (lnum == UBIFS_SB_LNUM) { 2268 if (lnum == UBIFS_SB_LNUM) {
2187 if (write) { 2269 if (write) {
@@ -2239,7 +2321,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); 2321 dbg_rcvry("failing in bud LEB %d commit not running", lnum);
2240 } 2322 }
2241 ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum); 2323 ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum);
2242 c->failure_mode = 1; 2324 d->failure_mode = 1;
2243 dump_stack(); 2325 dump_stack();
2244 return 1; 2326 return 1;
2245} 2327}
@@ -2344,4 +2426,177 @@ int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
2344 return 0; 2426 return 0;
2345} 2427}
2346 2428
2429/**
2430 * ubifs_debugging_init - initialize UBIFS debugging.
2431 * @c: UBIFS file-system description object
2432 *
2433 * This function initializes debugging-related data for the file system.
2434 * Returns zero in case of success and a negative error code in case of
2435 * failure.
2436 */
2437int ubifs_debugging_init(struct ubifs_info *c)
2438{
2439 c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL);
2440 if (!c->dbg)
2441 return -ENOMEM;
2442
2443 c->dbg->buf = vmalloc(c->leb_size);
2444 if (!c->dbg->buf)
2445 goto out;
2446
2447 failure_mode_init(c);
2448 return 0;
2449
2450out:
2451 kfree(c->dbg);
2452 return -ENOMEM;
2453}
2454
2455/**
2456 * ubifs_debugging_exit - free debugging data.
2457 * @c: UBIFS file-system description object
2458 */
2459void ubifs_debugging_exit(struct ubifs_info *c)
2460{
2461 failure_mode_exit(c);
2462 vfree(c->dbg->buf);
2463 kfree(c->dbg);
2464}
2465
2466/*
2467 * Root directory for UBIFS stuff in debugfs. Contains sub-directories which
2468 * contain the stuff specific to particular file-system mounts.
2469 */
2470static struct dentry *dfs_rootdir;
2471
2472/**
2473 * dbg_debugfs_init - initialize debugfs file-system.
2474 *
2475 * UBIFS uses debugfs file-system to expose various debugging knobs to
2476 * user-space. This function creates "ubifs" directory in the debugfs
2477 * file-system. Returns zero in case of success and a negative error code in
2478 * case of failure.
2479 */
2480int dbg_debugfs_init(void)
2481{
2482 dfs_rootdir = debugfs_create_dir("ubifs", NULL);
2483 if (IS_ERR(dfs_rootdir)) {
2484 int err = PTR_ERR(dfs_rootdir);
2485 ubifs_err("cannot create \"ubifs\" debugfs directory, "
2486 "error %d\n", err);
2487 return err;
2488 }
2489
2490 return 0;
2491}
2492
2493/**
2494 * dbg_debugfs_exit - remove the "ubifs" directory from debugfs file-system.
2495 */
2496void dbg_debugfs_exit(void)
2497{
2498 debugfs_remove(dfs_rootdir);
2499}
2500
2501static int open_debugfs_file(struct inode *inode, struct file *file)
2502{
2503 file->private_data = inode->i_private;
2504 return 0;
2505}
2506
2507static ssize_t write_debugfs_file(struct file *file, const char __user *buf,
2508 size_t count, loff_t *ppos)
2509{
2510 struct ubifs_info *c = file->private_data;
2511 struct ubifs_debug_info *d = c->dbg;
2512
2513 if (file->f_path.dentry == d->dfs_dump_lprops)
2514 dbg_dump_lprops(c);
2515 else if (file->f_path.dentry == d->dfs_dump_budg) {
2516 spin_lock(&c->space_lock);
2517 dbg_dump_budg(c);
2518 spin_unlock(&c->space_lock);
2519 } else if (file->f_path.dentry == d->dfs_dump_tnc) {
2520 mutex_lock(&c->tnc_mutex);
2521 dbg_dump_tnc(c);
2522 mutex_unlock(&c->tnc_mutex);
2523 } else
2524 return -EINVAL;
2525
2526 *ppos += count;
2527 return count;
2528}
2529
2530static const struct file_operations dfs_fops = {
2531 .open = open_debugfs_file,
2532 .write = write_debugfs_file,
2533 .owner = THIS_MODULE,
2534};
2535
2536/**
2537 * dbg_debugfs_init_fs - initialize debugfs for UBIFS instance.
2538 * @c: UBIFS file-system description object
2539 *
2540 * This function creates all debugfs files for this instance of UBIFS. Returns
2541 * zero in case of success and a negative error code in case of failure.
2542 *
2543 * Note, the only reason we have not merged this function with the
2544 * 'ubifs_debugging_init()' function is because it is better to initialize
2545 * debugfs interfaces at the very end of the mount process, and remove them at
2546 * the very beginning of the mount process.
2547 */
2548int dbg_debugfs_init_fs(struct ubifs_info *c)
2549{
2550 int err;
2551 const char *fname;
2552 struct dentry *dent;
2553 struct ubifs_debug_info *d = c->dbg;
2554
2555 sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id);
2556 d->dfs_dir = debugfs_create_dir(d->dfs_dir_name, dfs_rootdir);
2557 if (IS_ERR(d->dfs_dir)) {
2558 err = PTR_ERR(d->dfs_dir);
2559 ubifs_err("cannot create \"%s\" debugfs directory, error %d\n",
2560 d->dfs_dir_name, err);
2561 goto out;
2562 }
2563
2564 fname = "dump_lprops";
2565 dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
2566 if (IS_ERR(dent))
2567 goto out_remove;
2568 d->dfs_dump_lprops = dent;
2569
2570 fname = "dump_budg";
2571 dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
2572 if (IS_ERR(dent))
2573 goto out_remove;
2574 d->dfs_dump_budg = dent;
2575
2576 fname = "dump_tnc";
2577 dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
2578 if (IS_ERR(dent))
2579 goto out_remove;
2580 d->dfs_dump_tnc = dent;
2581
2582 return 0;
2583
2584out_remove:
2585 err = PTR_ERR(dent);
2586 ubifs_err("cannot create \"%s\" debugfs directory, error %d\n",
2587 fname, err);
2588 debugfs_remove_recursive(d->dfs_dir);
2589out:
2590 return err;
2591}
2592
2593/**
2594 * dbg_debugfs_exit_fs - remove all debugfs files.
2595 * @c: UBIFS file-system description object
2596 */
2597void dbg_debugfs_exit_fs(struct ubifs_info *c)
2598{
2599 debugfs_remove_recursive(c->dbg->dfs_dir);
2600}
2601
2347#endif /* CONFIG_UBIFS_FS_DEBUG */ 2602#endif /* CONFIG_UBIFS_FS_DEBUG */