Commit 84338237 authored by Ryusuke Konishi's avatar Ryusuke Konishi

nilfs2: ensure to clear dirty state when deleting metadata file block

This would fix the following failure during GC:

 nilfs_cpfile_delete_checkpoints: cannot delete block
 NILFS: GC failed during preparation: cannot delete checkpoints: err=-2

The problem was caused by a break in state consistency between page
cache and btree; the above block was removed from the btree but the
page buffering the block was remaining in the page cache in dirty
state.

This resolves the inconsistency by ensuring to clear dirty state of
the page buffering the deleted block.
Reported-by: default avatarDavid Arendt <admin@prnet.org>
Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
parent 201913ed
...@@ -300,7 +300,7 @@ int nilfs_mdt_delete_block(struct inode *inode, unsigned long block) ...@@ -300,7 +300,7 @@ int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
int err; int err;
err = nilfs_bmap_delete(ii->i_bmap, block); err = nilfs_bmap_delete(ii->i_bmap, block);
if (likely(!err)) { if (!err || err == -ENOENT) {
nilfs_mdt_mark_dirty(inode); nilfs_mdt_mark_dirty(inode);
nilfs_mdt_forget_block(inode, block); nilfs_mdt_forget_block(inode, block);
} }
......
...@@ -128,7 +128,8 @@ void nilfs_forget_buffer(struct buffer_head *bh) ...@@ -128,7 +128,8 @@ void nilfs_forget_buffer(struct buffer_head *bh)
lock_buffer(bh); lock_buffer(bh);
clear_buffer_nilfs_volatile(bh); clear_buffer_nilfs_volatile(bh);
if (test_clear_buffer_dirty(bh) && nilfs_page_buffers_clean(page)) clear_buffer_dirty(bh);
if (nilfs_page_buffers_clean(page))
__nilfs_clear_page_dirty(page); __nilfs_clear_page_dirty(page);
clear_buffer_uptodate(bh); clear_buffer_uptodate(bh);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment