lkml.org 
[lkml]   [2009]   [Jun]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 38/60] ext4: fix header check in ext4_ext_search_right() for deep extent trees.

    -stable review patch. If anyone has any objections, please let us know.

    ------------------
    From: Eric Sandeen <sandeen@redhat.com>

    (cherry picked from commit 395a87bfefbc400011417e9eaae33169f9f036c0)

    The ext4_ext_search_right() function is confusing; it uses a
    "depth" variable which is 0 at the root and maximum at the leaves,
    but the on-disk metadata uses a "depth" (actually eh_depth) which
    is opposite: maximum at the root, and 0 at the leaves.

    The ext4_ext_check_header() function is given a depth and checks
    the header agaisnt that depth; it expects the on-disk semantics,
    but we are giving it the opposite in the while loop in this
    function. We should be giving it the on-disk notion of "depth"
    which we can get from (p_depth - depth) - and if you look, the last
    (more commonly hit) call to ext4_ext_check_header() does just this.

    Sending in the wrong depth results in (incorrect) messages
    about corruption:

    EXT4-fs error (device sdb1): ext4_ext_search_right: bad header
    in inode #2621457: unexpected eh_depth - magic f30a, entries 340,
    max 340(0), depth 1(2)

    http://bugzilla.kernel.org/show_bug.cgi?id=12821

    Reported-by: David Dindorp <ddi@dubex.dk>
    Signed-off-by: Eric Sandeen <sandeen@redhat.com>
    Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
    ---
    fs/ext4/extents.c | 6 ++++--
    1 file changed, 4 insertions(+), 2 deletions(-)

    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -1118,7 +1118,8 @@ ext4_ext_search_right(struct inode *inod
    struct ext4_extent_idx *ix;
    struct ext4_extent *ex;
    ext4_fsblk_t block;
    - int depth, ee_len;
    + int depth; /* Note, NOT eh_depth; depth from top of tree */
    + int ee_len;

    BUG_ON(path == NULL);
    depth = path->p_depth;
    @@ -1177,7 +1178,8 @@ ext4_ext_search_right(struct inode *inod
    if (bh == NULL)
    return -EIO;
    eh = ext_block_hdr(bh);
    - if (ext4_ext_check_header(inode, eh, depth)) {
    + /* subtract from p_depth to get proper eh_depth */
    + if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) {
    put_bh(bh);
    return -EIO;
    }



    \
     
     \ /
      Last update: 2009-06-10 06:03    [W:4.147 / U:0.308 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site