aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/debug.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-05-02 15:34:39 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-05-13 12:23:57 -0400
commit45cd5cddbfbdf0993dbc76d06ed77d0bf547b421 (patch)
tree90fb0e0924d94de9b6a5d2dc3b27841fd882c5d5 /fs/ubifs/debug.c
parent69f8a75a7d9db05a7ee708514d605ab74956c73e (diff)
UBIFS: fix debugging FS checking failure
When the debugging self-checks are enabled, we go trough whole file-system after mount and check/validate every single node referred to by the index. This is implemented by the 'dbg_check_filesystem()' function. However, this function fails if we mount "unclean" file-system, i.e., if we mount the file-system after a power cut. It fails with the following symptoms: UBIFS DBG (pid 8171): ubifs_recover_size: ino 937 size 3309925 -> 3317760 UBIFS: recovery deferred UBIFS error (pid 8171): check_leaf: data node at LEB 1000:0 is not within inode size 3309925 The reason of failure is that recovery fixed up the inode size in memory, but not on the flash so far. So the value on the flash is incorrect so far, and would be corrected when we re-mount R/W. But 'check_leaf()' ignores this fact and tries to validate the size of the on-flash inode, which is incorrect, so it fails. This patch teaches the checking code to look at the VFS inode cache first, and if there is the inode in question, use that inode instead of the inode on the flash media. This fixes the issue. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'fs/ubifs/debug.c')
-rw-r--r--fs/ubifs/debug.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index f7515bd38b4f..b5ba2ea5b626 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -1818,6 +1818,8 @@ static struct fsck_inode *add_inode(struct ubifs_info *c,
1818 struct rb_node **p, *parent = NULL; 1818 struct rb_node **p, *parent = NULL;
1819 struct fsck_inode *fscki; 1819 struct fsck_inode *fscki;
1820 ino_t inum = key_inum_flash(c, &ino->key); 1820 ino_t inum = key_inum_flash(c, &ino->key);
1821 struct inode *inode;
1822 struct ubifs_inode *ui;
1821 1823
1822 p = &fsckd->inodes.rb_node; 1824 p = &fsckd->inodes.rb_node;
1823 while (*p) { 1825 while (*p) {
@@ -1841,19 +1843,46 @@ static struct fsck_inode *add_inode(struct ubifs_info *c,
1841 if (!fscki) 1843 if (!fscki)
1842 return ERR_PTR(-ENOMEM); 1844 return ERR_PTR(-ENOMEM);
1843 1845
1846 inode = ilookup(c->vfs_sb, inum);
1847
1844 fscki->inum = inum; 1848 fscki->inum = inum;
1845 fscki->nlink = le32_to_cpu(ino->nlink); 1849 /*
1846 fscki->size = le64_to_cpu(ino->size); 1850 * If the inode is present in the VFS inode cache, use it instead of
1847 fscki->xattr_cnt = le32_to_cpu(ino->xattr_cnt); 1851 * the on-flash inode which might be out-of-date. E.g., the size might
1848 fscki->xattr_sz = le32_to_cpu(ino->xattr_size); 1852 * be out-of-date. If we do not do this, the following may happen, for
1849 fscki->xattr_nms = le32_to_cpu(ino->xattr_names); 1853 * example:
1850 fscki->mode = le32_to_cpu(ino->mode); 1854 * 1. A power cut happens
1855 * 2. We mount the file-system R/O, the replay process fixes up the
1856 * inode size in the VFS cache, but on on-flash.
1857 * 3. 'check_leaf()' fails because it hits a data node beyond inode
1858 * size.
1859 */
1860 if (!inode) {
1861 fscki->nlink = le32_to_cpu(ino->nlink);
1862 fscki->size = le64_to_cpu(ino->size);
1863 fscki->xattr_cnt = le32_to_cpu(ino->xattr_cnt);
1864 fscki->xattr_sz = le32_to_cpu(ino->xattr_size);
1865 fscki->xattr_nms = le32_to_cpu(ino->xattr_names);
1866 fscki->mode = le32_to_cpu(ino->mode);
1867 } else {
1868 ui = ubifs_inode(inode);
1869 fscki->nlink = inode->i_nlink;
1870 fscki->size = inode->i_size;
1871 fscki->xattr_cnt = ui->xattr_cnt;
1872 fscki->xattr_sz = ui->xattr_size;
1873 fscki->xattr_nms = ui->xattr_names;
1874 fscki->mode = inode->i_mode;
1875 iput(inode);
1876 }
1877
1851 if (S_ISDIR(fscki->mode)) { 1878 if (S_ISDIR(fscki->mode)) {
1852 fscki->calc_sz = UBIFS_INO_NODE_SZ; 1879 fscki->calc_sz = UBIFS_INO_NODE_SZ;
1853 fscki->calc_cnt = 2; 1880 fscki->calc_cnt = 2;
1854 } 1881 }
1882
1855 rb_link_node(&fscki->rb, parent, p); 1883 rb_link_node(&fscki->rb, parent, p);
1856 rb_insert_color(&fscki->rb, &fsckd->inodes); 1884 rb_insert_color(&fscki->rb, &fsckd->inodes);
1885
1857 return fscki; 1886 return fscki;
1858} 1887}
1859 1888