diff options
Diffstat (limited to 'fs/ubifs/lpt_commit.c')
-rw-r--r-- | fs/ubifs/lpt_commit.c | 131 |
1 files changed, 126 insertions, 5 deletions
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index c5c07f9cd22c..da60b5a0fab9 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c | |||
@@ -320,6 +320,7 @@ no_space: | |||
320 | dbg_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, " | 320 | dbg_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, " |
321 | "done_lsave %d", lnum, offs, len, done_ltab, done_lsave); | 321 | "done_lsave %d", lnum, offs, len, done_ltab, done_lsave); |
322 | dbg_dump_lpt_info(c); | 322 | dbg_dump_lpt_info(c); |
323 | dbg_dump_lpt_lebs(c); | ||
323 | dump_stack(); | 324 | dump_stack(); |
324 | return err; | 325 | return err; |
325 | } | 326 | } |
@@ -549,6 +550,7 @@ no_space: | |||
549 | dbg_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab " | 550 | dbg_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab " |
550 | "%d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave); | 551 | "%d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave); |
551 | dbg_dump_lpt_info(c); | 552 | dbg_dump_lpt_info(c); |
553 | dbg_dump_lpt_lebs(c); | ||
552 | dump_stack(); | 554 | dump_stack(); |
553 | return err; | 555 | return err; |
554 | } | 556 | } |
@@ -1027,7 +1029,7 @@ static int make_node_dirty(struct ubifs_info *c, int node_type, int node_num, | |||
1027 | * @c: UBIFS file-system description object | 1029 | * @c: UBIFS file-system description object |
1028 | * @node_type: LPT node type | 1030 | * @node_type: LPT node type |
1029 | */ | 1031 | */ |
1030 | static int get_lpt_node_len(struct ubifs_info *c, int node_type) | 1032 | static int get_lpt_node_len(const struct ubifs_info *c, int node_type) |
1031 | { | 1033 | { |
1032 | switch (node_type) { | 1034 | switch (node_type) { |
1033 | case UBIFS_LPT_NNODE: | 1035 | case UBIFS_LPT_NNODE: |
@@ -1048,7 +1050,7 @@ static int get_lpt_node_len(struct ubifs_info *c, int node_type) | |||
1048 | * @buf: buffer | 1050 | * @buf: buffer |
1049 | * @len: length of buffer | 1051 | * @len: length of buffer |
1050 | */ | 1052 | */ |
1051 | static int get_pad_len(struct ubifs_info *c, uint8_t *buf, int len) | 1053 | static int get_pad_len(const struct ubifs_info *c, uint8_t *buf, int len) |
1052 | { | 1054 | { |
1053 | int offs, pad_len; | 1055 | int offs, pad_len; |
1054 | 1056 | ||
@@ -1065,7 +1067,8 @@ static int get_pad_len(struct ubifs_info *c, uint8_t *buf, int len) | |||
1065 | * @buf: buffer | 1067 | * @buf: buffer |
1066 | * @node_num: node number is returned here | 1068 | * @node_num: node number is returned here |
1067 | */ | 1069 | */ |
1068 | static int get_lpt_node_type(struct ubifs_info *c, uint8_t *buf, int *node_num) | 1070 | static int get_lpt_node_type(const struct ubifs_info *c, uint8_t *buf, |
1071 | int *node_num) | ||
1069 | { | 1072 | { |
1070 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; | 1073 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; |
1071 | int pos = 0, node_type; | 1074 | int pos = 0, node_type; |
@@ -1083,7 +1086,7 @@ static int get_lpt_node_type(struct ubifs_info *c, uint8_t *buf, int *node_num) | |||
1083 | * | 1086 | * |
1084 | * This function returns %1 if the buffer contains a node or %0 if it does not. | 1087 | * This function returns %1 if the buffer contains a node or %0 if it does not. |
1085 | */ | 1088 | */ |
1086 | static int is_a_node(struct ubifs_info *c, uint8_t *buf, int len) | 1089 | static int is_a_node(const struct ubifs_info *c, uint8_t *buf, int len) |
1087 | { | 1090 | { |
1088 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; | 1091 | uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; |
1089 | int pos = 0, node_type, node_len; | 1092 | int pos = 0, node_type, node_len; |
@@ -1107,7 +1110,6 @@ static int is_a_node(struct ubifs_info *c, uint8_t *buf, int len) | |||
1107 | return 1; | 1110 | return 1; |
1108 | } | 1111 | } |
1109 | 1112 | ||
1110 | |||
1111 | /** | 1113 | /** |
1112 | * lpt_gc_lnum - garbage collect a LPT LEB. | 1114 | * lpt_gc_lnum - garbage collect a LPT LEB. |
1113 | * @c: UBIFS file-system description object | 1115 | * @c: UBIFS file-system description object |
@@ -1724,6 +1726,7 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c) | |||
1724 | dbg_err("LPT space error: free %lld lpt_sz %lld", | 1726 | dbg_err("LPT space error: free %lld lpt_sz %lld", |
1725 | free, c->lpt_sz); | 1727 | free, c->lpt_sz); |
1726 | dbg_dump_lpt_info(c); | 1728 | dbg_dump_lpt_info(c); |
1729 | dbg_dump_lpt_lebs(c); | ||
1727 | dump_stack(); | 1730 | dump_stack(); |
1728 | return -EINVAL; | 1731 | return -EINVAL; |
1729 | } | 1732 | } |
@@ -1808,6 +1811,7 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) | |||
1808 | } | 1811 | } |
1809 | if (err) { | 1812 | if (err) { |
1810 | dbg_dump_lpt_info(c); | 1813 | dbg_dump_lpt_info(c); |
1814 | dbg_dump_lpt_lebs(c); | ||
1811 | dump_stack(); | 1815 | dump_stack(); |
1812 | } | 1816 | } |
1813 | d->chk_lpt_sz2 = d->chk_lpt_sz; | 1817 | d->chk_lpt_sz2 = d->chk_lpt_sz; |
@@ -1825,4 +1829,121 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) | |||
1825 | } | 1829 | } |
1826 | } | 1830 | } |
1827 | 1831 | ||
1832 | /** | ||
1833 | * dbg_dump_lpt_leb - dump an LPT LEB. | ||
1834 | * @c: UBIFS file-system description object | ||
1835 | * @lnum: LEB number to dump | ||
1836 | * | ||
1837 | * This function dumps an LEB from LPT area. Nodes in this area are very | ||
1838 | * different to nodes in the main area (e.g., they do not have common headers, | ||
1839 | * they do not have 8-byte alignments, etc), so we have a separate function to | ||
1840 | * dump LPT area LEBs. Note, LPT has to be locked by the coller. | ||
1841 | */ | ||
1842 | static void dump_lpt_leb(const struct ubifs_info *c, int lnum) | ||
1843 | { | ||
1844 | int err, len = c->leb_size, node_type, node_num, node_len, offs; | ||
1845 | void *buf = c->dbg->buf; | ||
1846 | |||
1847 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", | ||
1848 | current->pid, lnum); | ||
1849 | err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); | ||
1850 | if (err) { | ||
1851 | ubifs_err("cannot read LEB %d, error %d", lnum, err); | ||
1852 | return; | ||
1853 | } | ||
1854 | while (1) { | ||
1855 | offs = c->leb_size - len; | ||
1856 | if (!is_a_node(c, buf, len)) { | ||
1857 | int pad_len; | ||
1858 | |||
1859 | pad_len = get_pad_len(c, buf, len); | ||
1860 | if (pad_len) { | ||
1861 | printk(KERN_DEBUG "LEB %d:%d, pad %d bytes\n", | ||
1862 | lnum, offs, pad_len); | ||
1863 | buf += pad_len; | ||
1864 | len -= pad_len; | ||
1865 | continue; | ||
1866 | } | ||
1867 | if (len) | ||
1868 | printk(KERN_DEBUG "LEB %d:%d, free %d bytes\n", | ||
1869 | lnum, offs, len); | ||
1870 | break; | ||
1871 | } | ||
1872 | |||
1873 | node_type = get_lpt_node_type(c, buf, &node_num); | ||
1874 | switch (node_type) { | ||
1875 | case UBIFS_LPT_PNODE: | ||
1876 | { | ||
1877 | node_len = c->pnode_sz; | ||
1878 | if (c->big_lpt) | ||
1879 | printk(KERN_DEBUG "LEB %d:%d, pnode num %d\n", | ||
1880 | lnum, offs, node_num); | ||
1881 | else | ||
1882 | printk(KERN_DEBUG "LEB %d:%d, pnode\n", | ||
1883 | lnum, offs); | ||
1884 | break; | ||
1885 | } | ||
1886 | case UBIFS_LPT_NNODE: | ||
1887 | { | ||
1888 | int i; | ||
1889 | struct ubifs_nnode nnode; | ||
1890 | |||
1891 | node_len = c->nnode_sz; | ||
1892 | if (c->big_lpt) | ||
1893 | printk(KERN_DEBUG "LEB %d:%d, nnode num %d, ", | ||
1894 | lnum, offs, node_num); | ||
1895 | else | ||
1896 | printk(KERN_DEBUG "LEB %d:%d, nnode, ", | ||
1897 | lnum, offs); | ||
1898 | err = ubifs_unpack_nnode(c, buf, &nnode); | ||
1899 | for (i = 0; i < UBIFS_LPT_FANOUT; i++) { | ||
1900 | printk("%d:%d", nnode.nbranch[i].lnum, | ||
1901 | nnode.nbranch[i].offs); | ||
1902 | if (i != UBIFS_LPT_FANOUT - 1) | ||
1903 | printk(", "); | ||
1904 | } | ||
1905 | printk("\n"); | ||
1906 | break; | ||
1907 | } | ||
1908 | case UBIFS_LPT_LTAB: | ||
1909 | node_len = c->ltab_sz; | ||
1910 | printk(KERN_DEBUG "LEB %d:%d, ltab\n", | ||
1911 | lnum, offs); | ||
1912 | break; | ||
1913 | case UBIFS_LPT_LSAVE: | ||
1914 | node_len = c->lsave_sz; | ||
1915 | printk(KERN_DEBUG "LEB %d:%d, lsave len\n", lnum, offs); | ||
1916 | break; | ||
1917 | default: | ||
1918 | ubifs_err("LPT node type %d not recognized", node_type); | ||
1919 | return; | ||
1920 | } | ||
1921 | |||
1922 | buf += node_len; | ||
1923 | len -= node_len; | ||
1924 | } | ||
1925 | |||
1926 | printk(KERN_DEBUG "(pid %d) finish dumping LEB %d\n", | ||
1927 | current->pid, lnum); | ||
1928 | } | ||
1929 | |||
1930 | /** | ||
1931 | * dbg_dump_lpt_lebs - dump LPT lebs. | ||
1932 | * @c: UBIFS file-system description object | ||
1933 | * | ||
1934 | * This function dumps all LPT LEBs. The caller has to make sure the LPT is | ||
1935 | * locked. | ||
1936 | */ | ||
1937 | void dbg_dump_lpt_lebs(const struct ubifs_info *c) | ||
1938 | { | ||
1939 | int i; | ||
1940 | |||
1941 | printk(KERN_DEBUG "(pid %d) start dumping all LPT LEBs\n", | ||
1942 | current->pid); | ||
1943 | for (i = 0; i < c->lpt_lebs; i++) | ||
1944 | dump_lpt_leb(c, i + c->lpt_first); | ||
1945 | printk(KERN_DEBUG "(pid %d) finish dumping all LPT LEBs\n", | ||
1946 | current->pid); | ||
1947 | } | ||
1948 | |||
1828 | #endif /* CONFIG_UBIFS_FS_DEBUG */ | 1949 | #endif /* CONFIG_UBIFS_FS_DEBUG */ |