lkml.org 
[lkml]   [2006]   [Mar]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[RFC][PATCH 1/2]ext3 block allocation/reservation fixes to support 2**32 block numbers
From
Date
This patch fixed the issue around the ext3 block allocation code to
treat block numbers to int type, as some places relies on block number
to be "-1" to indicate allocation failures.

The block allocation failure returned from ext3_new_blocks() is being
captured by the error anyway, so there is no need to keep the returned
block number as "int" type from ext3_new_blocks(). We could still keep
the returned allocated block as "int" from ext3_try_to_allocate_with_rsv
(), as it's a block group relative value so a 4 bytes is enough for now.

patch against 2.6.16-mm2.

Signed-Off-By: Mingming Cao <cmm@us.ibm.com>

---

linux-2.6.16-ming/fs/ext3/balloc.c | 67 +++++++++++++++---------------
linux-2.6.16-ming/fs/ext3/xattr.c | 6 +-
linux-2.6.16-ming/include/linux/ext3_fs.h | 4 -
3 files changed, 40 insertions(+), 37 deletions(-)

diff -puN fs/ext3/balloc.c~ext3_rsv_int-fix fs/ext3/balloc.c
--- linux-2.6.16/fs/ext3/balloc.c~ext3_rsv_int-fix 2006-03-29 15:49:41.199815437 -0800
+++ linux-2.6.16-ming/fs/ext3/balloc.c 2006-03-29 15:49:41.211814047 -0800
@@ -223,7 +223,7 @@ void ext3_rsv_window_add(struct super_bl
{
struct rb_root *root = &EXT3_SB(sb)->s_rsv_window_root;
struct rb_node *node = &rsv->rsv_node;
- unsigned int start = rsv->rsv_start;
+ unsigned long start = rsv->rsv_start;

struct rb_node ** p = &root->rb_node;
struct rb_node * parent = NULL;
@@ -656,7 +656,8 @@ ext3_try_to_allocate(struct super_block
struct buffer_head *bitmap_bh, int goal,
unsigned long *count, struct ext3_reserve_window *my_rsv)
{
- int group_first_block, start, end;
+ unsigned long group_first_block;
+ int start, end;
unsigned long num = 0;

/* we do allocation within the reservation window if we have a window */
@@ -766,12 +767,13 @@ fail_access:
static int find_next_reservable_window(
struct ext3_reserve_window_node *search_head,
struct ext3_reserve_window_node *my_rsv,
- struct super_block * sb, int start_block,
- int last_block)
+ struct super_block * sb,
+ unsigned long start_block,
+ unsigned long last_block)
{
struct rb_node *next;
struct ext3_reserve_window_node *rsv, *prev;
- int cur;
+ unsigned long cur;
int size = my_rsv->rsv_goal_size;

/* TODO: make the start of the reservation window byte-aligned */
@@ -889,8 +891,8 @@ static int alloc_new_reservation(struct
unsigned int group, struct buffer_head *bitmap_bh)
{
struct ext3_reserve_window_node *search_head;
- int group_first_block, group_end_block, start_block;
- int first_free_block;
+ unsigned long group_first_block, group_end_block, start_block;
+ unsigned long first_free_block;
struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root;
unsigned long size;
int ret;
@@ -1200,16 +1202,17 @@ int ext3_should_retry_alloc(struct super
* bitmap, and then for any free bit if that fails.
* This function also updates quota and i_blocks field.
*/
-int ext3_new_blocks(handle_t *handle, struct inode *inode,
+unsigned long ext3_new_blocks(handle_t *handle, struct inode *inode,
unsigned long goal, unsigned long *count, int *errp)
{
struct buffer_head *bitmap_bh = NULL;
struct buffer_head *gdp_bh;
int group_no;
int goal_group;
- int ret_block;
+ int group_target_blk;
+ int group_allocated_blk;
+ unsigned long ret_block;
int bgi; /* blockgroup iteration index */
- int target_block;
int fatal = 0, err;
int performed_allocation = 0;
int free_blocks;
@@ -1285,16 +1288,17 @@ retry:
my_rsv = NULL;

if (free_blocks > 0) {
- ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) %
+ group_target_blk = ((goal - le32_to_cpu(es->s_first_data_block)) %
EXT3_BLOCKS_PER_GROUP(sb));
bitmap_bh = read_block_bitmap(sb, group_no);
if (!bitmap_bh)
goto io_error;
- ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no,
- bitmap_bh, ret_block, my_rsv, &num, &fatal);
+ group_allocated_blk = ext3_try_to_allocate_with_rsv(sb, handle,
+ group_no, bitmap_bh,
+ group_target_blk, my_rsv, &num, &fatal);
if (fatal)
goto out;
- if (ret_block >= 0)
+ if (group_allocated_blk >= 0)
goto allocated;
}

@@ -1327,11 +1331,12 @@ retry:
bitmap_bh = read_block_bitmap(sb, group_no);
if (!bitmap_bh)
goto io_error;
- ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no,
+ group_allocated_blk = ext3_try_to_allocate_with_rsv(sb, handle,
+ group_no,
bitmap_bh, -1, my_rsv, &num, &fatal);
if (fatal)
goto out;
- if (ret_block >= 0)
+ if (group_allocated_blk >= 0)
goto allocated;
}
/*
@@ -1360,18 +1365,19 @@ allocated:
if (fatal)
goto out;

- target_block = ret_block + group_no * EXT3_BLOCKS_PER_GROUP(sb)
+ ret_block = group_allocated_blk + group_no *
+ EXT3_BLOCKS_PER_GROUP(sb)
+ le32_to_cpu(es->s_first_data_block);

- if (in_range(le32_to_cpu(gdp->bg_block_bitmap), target_block, num) ||
- in_range(le32_to_cpu(gdp->bg_inode_bitmap), target_block, num) ||
- in_range(target_block, le32_to_cpu(gdp->bg_inode_table),
+ if (in_range(le32_to_cpu(gdp->bg_block_bitmap), ret_block, num) ||
+ in_range(le32_to_cpu(gdp->bg_inode_bitmap), ret_block, num) ||
+ in_range(ret_block, le32_to_cpu(gdp->bg_inode_table),
EXT3_SB(sb)->s_itb_per_group) ||
- in_range(target_block + num - 1, le32_to_cpu(gdp->bg_inode_table),
+ in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table),
EXT3_SB(sb)->s_itb_per_group))
ext3_error(sb, "ext3_new_block",
"Allocating block in system zone - "
- "blocks from %u, length %lu", target_block, num);
+ "blocks from %lu, length %lu", ret_block, num);

performed_allocation = 1;

@@ -1380,7 +1386,7 @@ allocated:
struct buffer_head *debug_bh;

/* Record bitmap buffer state in the newly allocated block */
- debug_bh = sb_find_get_block(sb, target_block);
+ debug_bh = sb_find_get_block(sb, ret_block);
if (debug_bh) {
BUFFER_TRACE(debug_bh, "state when allocated");
BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap state");
@@ -1393,24 +1399,21 @@ allocated:
int i;

for (i = 0; i < num; i++) {
- if (ext3_test_bit(ret_block,
+ if (ext3_test_bit(group_allocated_blk,
bh2jh(bitmap_bh)->b_committed_data)) {
printk("%s: block was unexpectedly set in "
"b_committed_data\n", __FUNCTION__);
}
}
}
- ext3_debug("found bit %d\n", ret_block);
+ ext3_debug("found bit %d\n", group_allocated_blk);
spin_unlock(sb_bgl_lock(sbi, group_no));
jbd_unlock_bh_state(bitmap_bh);
#endif

- /* ret_block was blockgroup-relative. Now it becomes fs-relative */
- ret_block = target_block;
-
if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) {
ext3_error(sb, "ext3_new_block",
- "block(%d) >= blocks count(%d) - "
+ "block(%lu) >= blocks count(%d) - "
"block_group = %d, es == %p ", ret_block,
le32_to_cpu(es->s_blocks_count), group_no, es);
goto out;
@@ -1421,8 +1424,8 @@ allocated:
* list of some description. We don't know in advance whether
* the caller wants to use it as metadata or data.
*/
- ext3_debug("allocating block %d. Goal hits %d of %d.\n",
- ret_block, goal_hits, goal_attempts);
+ ext3_debug("allocating block %lu. Goal hits %d of %d.\n",
+ ret_block, goal_hits, goal_attempts);

spin_lock(sb_bgl_lock(sbi, group_no));
gdp->bg_free_blocks_count =
@@ -1461,7 +1464,7 @@ out:
return 0;
}

-int ext3_new_block(handle_t *handle, struct inode *inode,
+unsigned long ext3_new_block(handle_t *handle, struct inode *inode,
unsigned long goal, int *errp)
{
unsigned long count = 1;
diff -puN fs/ext3/xattr.c~ext3_rsv_int-fix fs/ext3/xattr.c
--- linux-2.6.16/fs/ext3/xattr.c~ext3_rsv_int-fix 2006-03-29 15:49:41.202815089 -0800
+++ linux-2.6.16-ming/fs/ext3/xattr.c 2006-03-29 15:49:41.213813815 -0800
@@ -792,14 +792,14 @@ inserted:
get_bh(new_bh);
} else {
/* We need to allocate a new block */
- int goal = le32_to_cpu(
+ unsigned long goal = le32_to_cpu(
EXT3_SB(sb)->s_es->s_first_data_block) +
EXT3_I(inode)->i_block_group *
EXT3_BLOCKS_PER_GROUP(sb);
- int block = ext3_new_block(handle, inode, goal, &error);
+ unsigned long block = ext3_new_block(handle, inode, goal, &error);
if (error)
goto cleanup;
- ea_idebug(inode, "creating block %d", block);
+ ea_idebug(inode, "creating block %lu", block);

new_bh = sb_getblk(sb, block);
if (!new_bh) {
diff -puN include/linux/ext3_fs.h~ext3_rsv_int-fix include/linux/ext3_fs.h
--- linux-2.6.16/include/linux/ext3_fs.h~ext3_rsv_int-fix 2006-03-29 15:49:41.205814742 -0800
+++ linux-2.6.16-ming/include/linux/ext3_fs.h 2006-03-29 15:49:41.214813699 -0800
@@ -732,8 +732,8 @@ struct dir_private_info {
/* balloc.c */
extern int ext3_bg_has_super(struct super_block *sb, int group);
extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group);
-extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *);
-extern int ext3_new_blocks (handle_t *, struct inode *, unsigned long,
+extern unsigned long ext3_new_block (handle_t *, struct inode *, unsigned long, int *);
+extern unsigned long ext3_new_blocks (handle_t *, struct inode *, unsigned long,
unsigned long *, int *);
extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long,
unsigned long);
_


-
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: 2006-03-30 03:42    [W:0.132 / U:0.792 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site