Commit 5f50cce9 authored by Chris Mason's avatar Chris Mason Committed by Linus Torvalds

[PATCH] reiserfs: small filesystem fix

On small filesystems (<128M), make sure not to reference bitmap blocks that
don't exist.

Thanks to Jan Kara for finding this bug.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c76aaef0
...@@ -236,6 +236,9 @@ static int bmap_hash_id(struct super_block *s, u32 id) { ...@@ -236,6 +236,9 @@ static int bmap_hash_id(struct super_block *s, u32 id) {
if (!bm) if (!bm)
bm = 1; bm = 1;
} }
/* this can only be true when SB_BMAP_NR = 1 */
if (bm >= SB_BMAP_NR(s))
bm = 0;
return bm; return bm;
} }
...@@ -293,6 +296,10 @@ static int scan_bitmap (struct reiserfs_transaction_handle *th, ...@@ -293,6 +296,10 @@ static int scan_bitmap (struct reiserfs_transaction_handle *th,
get_bit_address (s, *start, &bm, &off); get_bit_address (s, *start, &bm, &off);
get_bit_address (s, finish, &end_bm, &end_off); get_bit_address (s, finish, &end_bm, &end_off);
if (bm > SB_BMAP_NR(s))
return 0;
if (end_bm > SB_BMAP_NR(s))
end_bm = SB_BMAP_NR(s);
/* When the bitmap is more than 10% free, anyone can allocate. /* When the bitmap is more than 10% free, anyone can allocate.
* When it's less than 10% free, only files that already use the * When it's less than 10% free, only files that already use the
...@@ -313,6 +320,7 @@ static int scan_bitmap (struct reiserfs_transaction_handle *th, ...@@ -313,6 +320,7 @@ static int scan_bitmap (struct reiserfs_transaction_handle *th,
if (nr_allocated) if (nr_allocated)
goto ret; goto ret;
} }
/* we know from above that start is a reasonable number */
get_bit_address (s, *start, &bm, &off); get_bit_address (s, *start, &bm, &off);
} }
...@@ -1050,9 +1058,10 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint, ...@@ -1050,9 +1058,10 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint,
{ {
int initial_amount_needed = amount_needed; int initial_amount_needed = amount_needed;
int ret; int ret;
struct super_block *s = hint->th->t_super;
/* Check if there is enough space, taking into account reserved space */ /* Check if there is enough space, taking into account reserved space */
if ( SB_FREE_BLOCKS(hint->th->t_super) - REISERFS_SB(hint->th->t_super)->reserved_blocks < if ( SB_FREE_BLOCKS(s) - REISERFS_SB(s)->reserved_blocks <
amount_needed - reserved_by_us) amount_needed - reserved_by_us)
return NO_DISK_SPACE; return NO_DISK_SPACE;
/* should this be if !hint->inode && hint->preallocate? */ /* should this be if !hint->inode && hint->preallocate? */
...@@ -1072,6 +1081,8 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint, ...@@ -1072,6 +1081,8 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint,
/* find search start and save it in hint structure */ /* find search start and save it in hint structure */
determine_search_start(hint, amount_needed); determine_search_start(hint, amount_needed);
if (hint->search_start >= SB_BLOCK_COUNT(s))
hint->search_start = SB_BLOCK_COUNT(s) - 1;
/* allocation itself; fill new_blocknrs and preallocation arrays */ /* allocation itself; fill new_blocknrs and preallocation arrays */
ret = blocknrs_and_prealloc_arrays_from_search_start ret = blocknrs_and_prealloc_arrays_from_search_start
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment