Skip to content

Commit

Permalink
nilfs2: always lookup disk block address before reading metadata block
Browse files Browse the repository at this point in the history
The current metadata file code skips disk address lookup for its data
block if the buffer has a mapped flag.

This has a potential risk to cause read request to be performed
against the stale block address that GC moved, and it may lead to meta
data corruption.  The mapped flag is safe if the buffer has an
uptodate flag, otherwise it may prevent necessary update of disk
address in the next read.

This will avoid the potential problem by ensuring disk address lookup
before reading metadata block even for buffers with the mapped flag.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
  • Loading branch information
Ryusuke Konishi committed Sep 14, 2009
1 parent 027d640 commit 1435110
Showing 1 changed file with 10 additions and 15 deletions.
25 changes: 10 additions & 15 deletions fs/nilfs2/mdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,12 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
goto failed_unlock;

err = -EEXIST;
if (buffer_uptodate(bh) || buffer_mapped(bh))
if (buffer_uptodate(bh))
goto failed_bh;
#if 0
/* The uptodate flag is not protected by the page lock, but
the mapped flag is. Thus, we don't have to wait the buffer. */

wait_on_buffer(bh);
if (buffer_uptodate(bh))
goto failed_bh;
#endif

bh->b_bdev = nilfs->ns_bdev;
err = nilfs_mdt_insert_new_block(inode, block, bh, init_block);
Expand Down Expand Up @@ -162,17 +159,15 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
unlock_buffer(bh);
goto out;
}
if (!buffer_mapped(bh)) { /* unused buffer */
ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff,
&blknum);
if (unlikely(ret)) {
unlock_buffer(bh);
goto failed_bh;
}
bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev;
bh->b_blocknr = blknum;
set_buffer_mapped(bh);

ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff, &blknum);
if (unlikely(ret)) {
unlock_buffer(bh);
goto failed_bh;
}
bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev;
bh->b_blocknr = blknum;
set_buffer_mapped(bh);

bh->b_end_io = end_buffer_read_sync;
get_bh(bh);
Expand Down

0 comments on commit 1435110

Please sign in to comment.