UBIFS: fix clean znode counter corruption in error cases
UBIFS maintains per-filesystem and global clean znode counters ('c->clean_zn_cnt' and 'ubifs_clean_zn_cnt'). It is important to maintain correct values there since the shrinker relies on 'ubifs_clean_zn_cnt'. However, in case of failures during commit the counters were corrupted. E.g., if a failure happens in the middle of 'write_index()', then some nodes in the commit list ('c->cnext') are marked as clean, and some are marked as dirty. And the 'ubifs_destroy_tnc_subtree()' frees does not retrun correct count, and we end up with non-zero 'c->clean_zn_cnt' when unmounting. This means that if we have 2 file-sytem and one of them fails, and we unmount it, 'ubifs_clean_zn_cnt' stays incorrect and confuses the shrinker. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
parent
812eb25831
commit
8370723770
1 changed files with 5 additions and 4 deletions
|
@ -2876,12 +2876,13 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
|
|||
*/
|
||||
void ubifs_tnc_close(struct ubifs_info *c)
|
||||
{
|
||||
long clean_freed;
|
||||
|
||||
tnc_destroy_cnext(c);
|
||||
if (c->zroot.znode) {
|
||||
clean_freed = ubifs_destroy_tnc_subtree(c->zroot.znode);
|
||||
atomic_long_sub(clean_freed, &ubifs_clean_zn_cnt);
|
||||
long n;
|
||||
|
||||
ubifs_destroy_tnc_subtree(c->zroot.znode);
|
||||
n = atomic_long_read(&c->clean_zn_cnt);
|
||||
atomic_long_sub(n, &ubifs_clean_zn_cnt);
|
||||
}
|
||||
kfree(c->gap_lebs);
|
||||
kfree(c->ilebs);
|
||||
|
|
Loading…
Reference in a new issue