nilfs2: ensure to clear dirty state when deleting metadata file block
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Tue, 5 May 2009 12:52:06 +0000 (21:52 +0900)
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Sun, 10 May 2009 08:04:42 +0000 (17:04 +0900)
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: David Arendt <admin@prnet.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
fs/nilfs2/mdt.c
fs/nilfs2/page.c

index e1c6777931b714140aa50f96925769a48c499ecb..bb78745a0e30d0e7bda05d4416f9f72e5b74db75 100644 (file)
@@ -300,7 +300,7 @@ int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
        int err;
 
        err = nilfs_bmap_delete(ii->i_bmap, block);
-       if (likely(!err)) {
+       if (!err || err == -ENOENT) {
                nilfs_mdt_mark_dirty(inode);
                nilfs_mdt_forget_block(inode, block);
        }
index 1bfbba9c0e9ae3aba969e6c3341968ce24916a7d..a2692bbc7b50a510b1723b95fd7d060b74bbedb9 100644 (file)
@@ -128,7 +128,8 @@ void nilfs_forget_buffer(struct buffer_head *bh)
 
        lock_buffer(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);
 
        clear_buffer_uptodate(bh);