lkml.org 
[lkml]   [2009]   [Feb]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 29/39] ext4: Use new buffer_head flag to check uninit group bitmaps initialization

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

    ------------------
    From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

    (cherry picked from commit 2ccb5fb9f113dae969d1ae9b6c10e80fa34f8cd3)

    For uninit block group, the on-disk bitmap is not initialized. That
    implies we cannot depend on the uptodate flag on the bitmap
    buffer_head to find bitmap validity. Use a new buffer_head flag which
    would be set after we properly initialize the bitmap. This also
    prevents (re-)initializing the uninit group bitmap every time we call
    ext4_read_block_bitmap().

    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
    Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    fs/ext4/balloc.c | 25 +++++++++++++++++++++++--
    fs/ext4/ext4.h | 19 +++++++++++++++++++
    fs/ext4/ialloc.c | 24 ++++++++++++++++++++++--
    fs/ext4/mballoc.c | 24 ++++++++++++++++++++++--
    4 files changed, 86 insertions(+), 6 deletions(-)
    --- a/fs/ext4/balloc.c
    +++ b/fs/ext4/balloc.c
    @@ -320,20 +320,41 @@ ext4_read_block_bitmap(struct super_bloc
    block_group, bitmap_blk);
    return NULL;
    }
    - if (buffer_uptodate(bh) &&
    - !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)))
    +
    + if (bitmap_uptodate(bh))
    return bh;

    lock_buffer(bh);
    + if (bitmap_uptodate(bh)) {
    + unlock_buffer(bh);
    + return bh;
    + }
    spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
    if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
    ext4_init_block_bitmap(sb, bh, block_group, desc);
    + set_bitmap_uptodate(bh);
    set_buffer_uptodate(bh);
    unlock_buffer(bh);
    spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
    return bh;
    }
    spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
    + if (buffer_uptodate(bh)) {
    + /*
    + * if not uninit if bh is uptodate,
    + * bitmap is also uptodate
    + */
    + set_bitmap_uptodate(bh);
    + unlock_buffer(bh);
    + return bh;
    + }
    + /*
    + * submit the buffer_head for read. We can
    + * safely mark the bitmap as uptodate now.
    + * We do it here so the bitmap uptodate bit
    + * get set with buffer lock held.
    + */
    + set_bitmap_uptodate(bh);
    if (bh_submit_read(bh) < 0) {
    put_bh(bh);
    ext4_error(sb, __func__,
    --- a/fs/ext4/ext4.h
    +++ b/fs/ext4/ext4.h
    @@ -19,6 +19,7 @@
    #include <linux/types.h>
    #include <linux/blkdev.h>
    #include <linux/magic.h>
    +#include <linux/jbd2.h>
    #include "ext4_i.h"

    /*
    @@ -1286,6 +1287,24 @@ extern int ext4_get_blocks_wrap(handle_t
    sector_t block, unsigned long max_blocks,
    struct buffer_head *bh, int create,
    int extend_disksize, int flag);
    +
    +/*
    + * Add new method to test wether block and inode bitmaps are properly
    + * initialized. With uninit_bg reading the block from disk is not enough
    + * to mark the bitmap uptodate. We need to also zero-out the bitmap
    + */
    +#define BH_BITMAP_UPTODATE BH_JBDPrivateStart
    +
    +static inline int bitmap_uptodate(struct buffer_head *bh)
    +{
    + return (buffer_uptodate(bh) &&
    + test_bit(BH_BITMAP_UPTODATE, &(bh)->b_state));
    +}
    +static inline void set_bitmap_uptodate(struct buffer_head *bh)
    +{
    + set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
    +}
    +
    #endif /* __KERNEL__ */

    #endif /* _EXT4_H */
    --- a/fs/ext4/ialloc.c
    +++ b/fs/ext4/ialloc.c
    @@ -115,20 +115,40 @@ ext4_read_inode_bitmap(struct super_bloc
    block_group, bitmap_blk);
    return NULL;
    }
    - if (buffer_uptodate(bh) &&
    - !(desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)))
    + if (bitmap_uptodate(bh))
    return bh;

    lock_buffer(bh);
    + if (bitmap_uptodate(bh)) {
    + unlock_buffer(bh);
    + return bh;
    + }
    spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
    if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
    ext4_init_inode_bitmap(sb, bh, block_group, desc);
    + set_bitmap_uptodate(bh);
    set_buffer_uptodate(bh);
    unlock_buffer(bh);
    spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
    return bh;
    }
    spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
    + if (buffer_uptodate(bh)) {
    + /*
    + * if not uninit if bh is uptodate,
    + * bitmap is also uptodate
    + */
    + set_bitmap_uptodate(bh);
    + unlock_buffer(bh);
    + return bh;
    + }
    + /*
    + * submit the buffer_head for read. We can
    + * safely mark the bitmap as uptodate now.
    + * We do it here so the bitmap uptodate bit
    + * get set with buffer lock held.
    + */
    + set_bitmap_uptodate(bh);
    if (bh_submit_read(bh) < 0) {
    put_bh(bh);
    ext4_error(sb, __func__,
    --- a/fs/ext4/mballoc.c
    +++ b/fs/ext4/mballoc.c
    @@ -794,22 +794,42 @@ static int ext4_mb_init_cache(struct pag
    if (bh[i] == NULL)
    goto out;

    - if (buffer_uptodate(bh[i]) &&
    - !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)))
    + if (bitmap_uptodate(bh[i]))
    continue;

    lock_buffer(bh[i]);
    + if (bitmap_uptodate(bh[i])) {
    + unlock_buffer(bh[i]);
    + continue;
    + }
    spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
    if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
    ext4_init_block_bitmap(sb, bh[i],
    first_group + i, desc);
    + set_bitmap_uptodate(bh[i]);
    set_buffer_uptodate(bh[i]);
    unlock_buffer(bh[i]);
    spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
    continue;
    }
    spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
    + if (buffer_uptodate(bh[i])) {
    + /*
    + * if not uninit if bh is uptodate,
    + * bitmap is also uptodate
    + */
    + set_bitmap_uptodate(bh[i]);
    + unlock_buffer(bh[i]);
    + continue;
    + }
    get_bh(bh[i]);
    + /*
    + * submit the buffer_head for read. We can
    + * safely mark the bitmap as uptodate now.
    + * We do it here so the bitmap uptodate bit
    + * get set with buffer lock held.
    + */
    + set_bitmap_uptodate(bh[i]);
    bh[i]->b_end_io = end_buffer_read_sync;
    submit_bh(READ, bh[i]);
    mb_debug("read bitmap for group %lu\n", first_group + i);


    \
     
     \ /
      Last update: 2009-02-18 22:47    [from the cache]
    ©2003-2014 Jasper Spaans. Advertise on this site