aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/lpt_commit.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs/lpt_commit.c')
-rw-r--r--fs/ubifs/lpt_commit.c131
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 */
1030static int get_lpt_node_len(struct ubifs_info *c, int node_type) 1032static 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 */
1051static int get_pad_len(struct ubifs_info *c, uint8_t *buf, int len) 1053static 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 */
1068static int get_lpt_node_type(struct ubifs_info *c, uint8_t *buf, int *node_num) 1070static 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 */
1086static int is_a_node(struct ubifs_info *c, uint8_t *buf, int len) 1089static 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 */
1842static 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 */
1937void 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 */