diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-05-05 07:16:32 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-05-13 12:23:57 -0400 |
commit | c1f1f91d2183b91c684900b529b6c336ad3dd27c (patch) | |
tree | a4df1e218b75bfbfa60c304a83d6364ef0320ce4 /fs | |
parent | 45cd5cddbfbdf0993dbc76d06ed77d0bf547b421 (diff) |
UBIFS: fix inode size debugging check failure
This patch fixes a problem with the following symptoms:
UBIFS: deferred recovery completed
UBIFS error (pid 15676): dbg_check_synced_i_size: ui_size is 11481088, synced_i_size is 11459081, but inode is clean
UBIFS error (pid 15676): dbg_check_synced_i_size: i_ino 128, i_mode 0x81a4, i_size 11481088
It happens when additional debugging checks are enabled and we are recovering
from a power cut. When we fixup corrupted inode size during recovery, we change
them in-place and we change ui_size as well, but not synced_i_size, which
causes this failure. This patch makes sure we change both fields and fixes the
issue.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ubifs/recovery.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index d6c8ce3c722e..3f41a0ce192b 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -1490,18 +1490,22 @@ int ubifs_recover_size(struct ubifs_info *c) | |||
1490 | if (c->ro_mount) { | 1490 | if (c->ro_mount) { |
1491 | /* Fix the inode size and pin it in memory */ | 1491 | /* Fix the inode size and pin it in memory */ |
1492 | struct inode *inode; | 1492 | struct inode *inode; |
1493 | struct ubifs_inode *ui; | ||
1493 | 1494 | ||
1494 | ubifs_assert(!e->inode); | 1495 | ubifs_assert(!e->inode); |
1495 | 1496 | ||
1496 | inode = ubifs_iget(c->vfs_sb, e->inum); | 1497 | inode = ubifs_iget(c->vfs_sb, e->inum); |
1497 | if (IS_ERR(inode)) | 1498 | if (IS_ERR(inode)) |
1498 | return PTR_ERR(inode); | 1499 | return PTR_ERR(inode); |
1500 | |||
1501 | ui = ubifs_inode(inode); | ||
1499 | if (inode->i_size < e->d_size) { | 1502 | if (inode->i_size < e->d_size) { |
1500 | dbg_rcvry("ino %lu size %lld -> %lld", | 1503 | dbg_rcvry("ino %lu size %lld -> %lld", |
1501 | (unsigned long)e->inum, | 1504 | (unsigned long)e->inum, |
1502 | inode->i_size, e->d_size); | 1505 | inode->i_size, e->d_size); |
1503 | inode->i_size = e->d_size; | 1506 | inode->i_size = e->d_size; |
1504 | ubifs_inode(inode)->ui_size = e->d_size; | 1507 | ui->ui_size = e->d_size; |
1508 | ui->synced_i_size = e->d_size; | ||
1505 | e->inode = inode; | 1509 | e->inode = inode; |
1506 | this = rb_next(this); | 1510 | this = rb_next(this); |
1507 | continue; | 1511 | continue; |