Re: Possible bug with extent status tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



  Hello,

On Tue 12-03-13 11:53:19, Zheng Liu wrote:
> On Mon, Mar 11, 2013 at 09:38:34PM +0100, Jan Kara wrote:
> >   Hello,
> > 
> >   while looking into the ext4 code I spotted one thing which I think is a
> > bug introduced by extent status tree code. The problem is that
> > ext4_map_blocks() checks extent status tree and if the extent is found, it
> > doesn't call into ext4_ext_map_blocks(). However ext4_ext_direct_IO() expects
> > that if the extent DIO is done to is unwritten, EXT4_IO_END_UNWRITTEN flag
> > gets set in the io_end (or inode) flags and that happens only in
> > ext4_ext_map_blocks().
> > 
> > The easiest fix seems to be to move setting of flags from
> > ext4_ext_map_blocks() up into ext4_map_blocks() (or maybe even
> > _ext4_get_block()). What do you think?
> 
> Hi Jan,
> 
> Thanks for reviewing the code.  But I don't think it is a potential bug.
> Let's see what happens after adding extent status tree.  There are three
> cases that we need to take care, a) no block has been allocated, b)
> unwritten extent has been allocated, and c) written extent has been
> allocated.
> 
> a) no block has been allocated.
> In this case, both extent tree on disk and status tree in memory haven't
> this extent.  When we do a extent-based dio write, ext4_get_block_write
> will be called with EXT4_GET_BLOCKS_IO_CREATE_EXT flag.  In
> ext4_map_blocks(), the codepath looks like:
> 
> ext4_map_blocks()
>   ->ext4_es_lookup_extent()
>     [no extent found in status tree]
>   ->ext4_ext_map_blocks() without flags
>     [no extent found in extent tree]
>   ->ext4_ext_map_blocks() with EXT4_GET_BLOCKS_IO_CREATE_EXT
>     ->ext4_mb_new_blocks()
>       [allocate an unwritten extent]
>     ->ext4_set_io_unwritten_flag()
>       [set EXT4_IO_END_UNWRITTEN flag because _PRE_IO flag is set and an
>        unwritten extent has been allocated]
> 
> In this case, we are safe.
  Agreed.

> b) unwritten extent has been allocated
> In this case, both extent tree on disk and status tree in memory have an
> unwritten extent, and codepath looks like:
> 
> ext4_map_blocks()
>   ->ext4_es_lookup_extent()
>     [unwritten extent found in status tree, EXT4_MAP_UNWRITTEN flag is
>      marked in map->m_flags.  In the mean time, ext4_ext_map_blocks()
>      isn't called]
>   [But we don't return from ext4_map_blocks because EXT4_GET_BLOCKS_CREATE
>    flag is set and EXT4_MAP_MAPPED flag is not set]
>   ->ext4_ext_map_blocks() with EXT4_GET_BLOCKS_IO_CREATE_EXT
>     ->ext4_ext_handle_uninitialized_extents()
>       ->ext4_set_io_unwritten_flag()
>         [set EXT4_IO_END_UNWRITTEN flag because _PRE_IO flag is set]
> 
> So it seems that there is no bug.
  Ah, right. This is what I was missing. I didn't realize that we won't
set EXT4_MAP_MAPPED when the extent is unwritten so we will end up calling
ext4_ext_map_blocks() later. Sorry for the noise.

								Honza
-- 
Jan Kara <jack@xxxxxxx>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux