lkml.org 
[lkml]   [2007]   [Sep]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH V2] dir_index: error out instead of BUG on corrupt dx dirs
    Duane Griffin wrote:

    > "Corrupt root limit in dir inode %ld, running e2fsck is recommended\n"
    >
    >
    Probably good, for anything that was read from disk, certainly.

    I don't know if it's worth differentiating messages for different types
    of corruption (root block vs. others, etc...) - I guess the other error
    cases do.

    Maybe it'd be best to just consolidate the fsck suggestion message under
    fail: ?

    Here's a patch rolling up yours with mine + discussed changes, and
    consolidating the fsck suggestion message.

    How's it look to you? Suppose I'd better run this a bit to be sure it's
    not hitting any common cases and issuing new warnings...?

    ThAnks!
    -Eric

    ---------------------------------

    Convert asserts (BUGs) in dx_probe from bad on-disk data to recoverable
    errors with helpful warnings. With help catching other asserts
    from Duane Griffin <duaneg@dghda.com>

    Signed-off-by: Eric Sandeen <sandeen@redhat.com>

    Index: linux-2.6.22-rc4/fs/ext3/namei.c
    ===================================================================
    --- linux-2.6.22-rc4.orig/fs/ext3/namei.c
    +++ linux-2.6.22-rc4/fs/ext3/namei.c
    @@ -379,13 +379,28 @@ dx_probe(struct dentry *dentry, struct i

    entries = (struct dx_entry *) (((char *)&root->info) +
    root->info.info_length);
    - assert(dx_get_limit(entries) == dx_root_limit(dir,
    - root->info.info_length));
    +
    + if (dx_get_limit(entries) != dx_root_limit(dir,
    + root->info.info_length)) {
    + ext3_warning(dir->i_sb, __FUNCTION__,
    + "dx entry: limit != root limit\n");
    + brelse(bh);
    + *err = ERR_BAD_DX_DIR;
    + goto fail;
    + }
    +
    dxtrace (printk("Look up %x", hash));
    while (1)
    {
    count = dx_get_count(entries);
    - assert (count && count <= dx_get_limit(entries));
    + if (!count || count > dx_get_limit(entries)) {
    + ext3_warning(dir->i_sb, __FUNCTION__,
    + "dx entry: no count or count > limit\n");
    + brelse(bh);
    + *err = ERR_BAD_DX_DIR;
    + goto fail2;
    + }
    +
    p = entries + 1;
    q = entries + count - 1;
    while (p <= q)
    @@ -423,8 +438,15 @@ dx_probe(struct dentry *dentry, struct i
    if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
    goto fail2;
    at = entries = ((struct dx_node *) bh->b_data)->entries;
    - assert (dx_get_limit(entries) == dx_node_limit (dir));
    + if (dx_get_limit(entries) != dx_node_limit (dir)) {
    + ext3_warning(dir->i_sb, __FUNCTION__,
    + "dx entry: limit != node limit\n");
    + brelse(bh);
    + *err = ERR_BAD_DX_DIR;
    + goto fail2;
    + }
    frame++;
    + frame->bh = NULL;
    }
    fail2:
    while (frame >= frame_in) {
    @@ -432,6 +454,10 @@ fail2:
    frame--;
    }
    fail:
    + if (*err == ERR_BAD_DX_DIR)
    + ext3_warning(dir->i_sb, __FUNCTION__,
    + "Corrupt dir inode %ld, running e2fsck is "
    + "recommended.\n", dir->i_ino);
    return NULL;
    }

    Index: linux-2.6.22-rc4/fs/ext4/namei.c
    ===================================================================
    --- linux-2.6.22-rc4.orig/fs/ext4/namei.c
    +++ linux-2.6.22-rc4/fs/ext4/namei.c
    @@ -379,13 +379,28 @@ dx_probe(struct dentry *dentry, struct i

    entries = (struct dx_entry *) (((char *)&root->info) +
    root->info.info_length);
    - assert(dx_get_limit(entries) == dx_root_limit(dir,
    - root->info.info_length));
    +
    + if (dx_get_limit(entries) != dx_root_limit(dir,
    + root->info.info_length)) {
    + ext4_warning(dir->i_sb, __FUNCTION__,
    + "dx entry: limit != root limit\n");
    + brelse(bh);
    + *err = ERR_BAD_DX_DIR;
    + goto fail;
    + }
    +
    dxtrace (printk("Look up %x", hash));
    while (1)
    {
    count = dx_get_count(entries);
    - assert (count && count <= dx_get_limit(entries));
    + if (!count || count > dx_get_limit(entries)) {
    + ext4_warning(dir->i_sb, __FUNCTION__,
    + "dx entry: no count or count > limit\n");
    + brelse(bh);
    + *err = ERR_BAD_DX_DIR;
    + goto fail2;
    + }
    +
    p = entries + 1;
    q = entries + count - 1;
    while (p <= q)
    @@ -423,8 +438,15 @@ dx_probe(struct dentry *dentry, struct i
    if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
    goto fail2;
    at = entries = ((struct dx_node *) bh->b_data)->entries;
    - assert (dx_get_limit(entries) == dx_node_limit (dir));
    + if (dx_get_limit(entries) != dx_node_limit (dir)) {
    + ext4_warning(dir->i_sb, __FUNCTION__,
    + "dx entry: limit != node limit\n");
    + brelse(bh);
    + *err = ERR_BAD_DX_DIR;
    + goto fail2;
    + }
    frame++;
    + frame->bh = NULL;
    }
    fail2:
    while (frame >= frame_in) {
    @@ -432,6 +454,10 @@ fail2:
    frame--;
    }
    fail:
    + if (*err == ERR_BAD_DX_DIR)
    + ext4_warning(dir->i_sb, __FUNCTION__,
    + "Corrupt dir inode %ld, running e2fsck is "
    + "recommended.\n", dir->i_ino);
    return NULL;
    }


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-09-11 00:45    [W:0.056 / U:1.672 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site