Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 71407
b: refs/heads/master
c: cb680c1
h: refs/heads/master
i:
  71405: b1bb9b0
  71403: 069e740
  71399: 30d6fea
  71391: d5e3aaf
v: v3
  • Loading branch information
Jeff Mahoney authored and Linus Torvalds committed Oct 19, 2007
1 parent 3d49c74 commit fe0ddb2
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4d20851d3757ba5bece263a4c8c5a2bd4983cb5d
refs/heads/master: cb680c1be62e9898fc2ca2a89d9fdba7c84a5c81
39 changes: 22 additions & 17 deletions trunk/fs/reiserfs/bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ static inline void get_bit_address(struct super_block *s,
int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
{
unsigned int bmap, offset;
unsigned int bmap_count = reiserfs_bmap_count(s);

if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
reiserfs_warning(s,
Expand All @@ -76,25 +77,26 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
if (unlikely(test_bit(REISERFS_OLD_FORMAT,
&(REISERFS_SB(s)->s_properties)))) {
b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) {
if (block >= bmap1 &&
block <= bmap1 + bmap_count) {
reiserfs_warning(s, "vs: 4019: is_reusable: "
"bitmap block %lu(%u) can't be freed or reused",
block, SB_BMAP_NR(s));
block, bmap_count);
return 0;
}
} else {
if (offset == 0) {
reiserfs_warning(s, "vs: 4020: is_reusable: "
"bitmap block %lu(%u) can't be freed or reused",
block, SB_BMAP_NR(s));
block, bmap_count);
return 0;
}
}

if (bmap >= SB_BMAP_NR(s)) {
if (bmap >= bmap_count) {
reiserfs_warning(s,
"vs-4030: is_reusable: there is no so many bitmap blocks: "
"block=%lu, bitmap_nr=%d", block, bmap);
"block=%lu, bitmap_nr=%u", block, bmap);
return 0;
}

Expand Down Expand Up @@ -143,8 +145,8 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,

BUG_ON(!th->t_trans_id);

RFALSE(bmap_n >= SB_BMAP_NR(s), "Bitmap %d is out of range (0..%d)",
bmap_n, SB_BMAP_NR(s) - 1);
RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of "
"range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1);
PROC_INFO_INC(s, scan_bitmap.bmap);
/* this is unclear and lacks comments, explain how journal bitmaps
work here for the reader. Convey a sense of the design here. What
Expand Down Expand Up @@ -249,12 +251,12 @@ static int bmap_hash_id(struct super_block *s, u32 id)
} else {
hash_in = (char *)(&id);
hash = keyed_hash(hash_in, 4);
bm = hash % SB_BMAP_NR(s);
bm = hash % reiserfs_bmap_count(s);
if (!bm)
bm = 1;
}
/* this can only be true when SB_BMAP_NR = 1 */
if (bm >= SB_BMAP_NR(s))
if (bm >= reiserfs_bmap_count(s))
bm = 0;
return bm;
}
Expand Down Expand Up @@ -328,10 +330,10 @@ static int scan_bitmap(struct reiserfs_transaction_handle *th,

get_bit_address(s, *start, &bm, &off);
get_bit_address(s, finish, &end_bm, &end_off);
if (bm > SB_BMAP_NR(s))
if (bm > reiserfs_bmap_count(s))
return 0;
if (end_bm > SB_BMAP_NR(s))
end_bm = SB_BMAP_NR(s);
if (end_bm > reiserfs_bmap_count(s))
end_bm = reiserfs_bmap_count(s);

/* When the bitmap is more than 10% free, anyone can allocate.
* When it's less than 10% free, only files that already use the
Expand Down Expand Up @@ -397,10 +399,12 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,

get_bit_address(s, block, &nr, &offset);

if (nr >= sb_bmap_nr(rs)) {
if (nr >= reiserfs_bmap_count(s)) {
reiserfs_warning(s, "vs-4075: reiserfs_free_block: "
"block %lu is out of range on %s",
block, reiserfs_bdevname(s));
"block %lu is out of range on %s "
"(nr=%u,max=%u)", block,
reiserfs_bdevname(s), nr,
reiserfs_bmap_count(s));
return;
}

Expand Down Expand Up @@ -1269,12 +1273,13 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
int reiserfs_init_bitmap_cache(struct super_block *sb)
{
struct reiserfs_bitmap_info *bitmap;
unsigned int bmap_nr = reiserfs_bmap_count(sb);

bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb));
bitmap = vmalloc(sizeof(*bitmap) * bmap_nr);
if (bitmap == NULL)
return -ENOMEM;

memset(bitmap, 0xff, sizeof(*bitmap) * SB_BMAP_NR(sb));
memset(bitmap, 0xff, sizeof(*bitmap) * bmap_nr);

SB_AP_BITMAP(sb) = bitmap;

Expand Down
6 changes: 3 additions & 3 deletions trunk/fs/reiserfs/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ static void cleanup_bitmap_list(struct super_block *p_s_sb,
if (jb->bitmaps == NULL)
return;

for (i = 0; i < SB_BMAP_NR(p_s_sb); i++) {
for (i = 0; i < reiserfs_bmap_count(p_s_sb); i++) {
if (jb->bitmaps[i]) {
free_bitmap_node(p_s_sb, jb->bitmaps[i]);
jb->bitmaps[i] = NULL;
Expand Down Expand Up @@ -2734,15 +2734,15 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name,
journal->j_persistent_trans = 0;
if (reiserfs_allocate_list_bitmaps(p_s_sb,
journal->j_list_bitmap,
SB_BMAP_NR(p_s_sb)))
reiserfs_bmap_count(p_s_sb)))
goto free_and_return;
allocate_bitmap_nodes(p_s_sb);

/* reserved for journal area support */
SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ?
REISERFS_OLD_DISK_OFFSET_IN_BYTES
/ p_s_sb->s_blocksize +
SB_BMAP_NR(p_s_sb) +
reiserfs_bmap_count(p_s_sb) +
1 :
REISERFS_DISK_OFFSET_IN_BYTES /
p_s_sb->s_blocksize + 2);
Expand Down
7 changes: 4 additions & 3 deletions trunk/fs/reiserfs/resize.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
}

/* count used bits in last bitmap block */
block_r = SB_BLOCK_COUNT(s) - (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8;
block_r = SB_BLOCK_COUNT(s) -
(reiserfs_bmap_count(s) - 1) * s->s_blocksize * 8;

/* count bitmap blocks in new fs */
bmap_nr_new = block_count_new / (s->s_blocksize * 8);
Expand All @@ -73,7 +74,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)

/* save old values */
block_count = SB_BLOCK_COUNT(s);
bmap_nr = SB_BMAP_NR(s);
bmap_nr = reiserfs_bmap_count(s);

/* resizing of reiserfs bitmaps (journal and real), if needed */
if (bmap_nr_new > bmap_nr) {
Expand Down Expand Up @@ -200,7 +201,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
free_blocks + (block_count_new - block_count -
(bmap_nr_new - bmap_nr)));
PUT_SB_BLOCK_COUNT(s, block_count_new);
PUT_SB_BMAP_NR(s, bmap_nr_new);
PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new);
s->s_dirt = 1;

journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
Expand Down
15 changes: 15 additions & 0 deletions trunk/fs/reiserfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,21 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
set_sb_umount_state(rs, REISERFS_ERROR_FS);
set_sb_fs_state(rs, 0);

/* Clear out s_bmap_nr if it would wrap. We can handle this
* case, but older revisions can't. This will cause the
* file system to fail mount on those older implementations,
* avoiding corruption. -jeffm */
if (bmap_would_wrap(reiserfs_bmap_count(s)) &&
sb_bmap_nr(rs) != 0) {
reiserfs_warning(s, "super-2030: This file system "
"claims to use %u bitmap blocks in "
"its super block, but requires %u. "
"Clearing to zero.", sb_bmap_nr(rs),
reiserfs_bmap_count(s));

set_sb_bmap_nr(rs, 0);
}

if (old_format_only(s)) {
/* filesystem of format 3.5 either with standard or non-standard
journal */
Expand Down
12 changes: 12 additions & 0 deletions trunk/include/linux/reiserfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,18 @@ static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb)
return sb->s_fs_info;
}

/* Don't trust REISERFS_SB(sb)->s_bmap_nr, it's a u16
* which overflows on large file systems. */
static inline u32 reiserfs_bmap_count(struct super_block *sb)
{
return (SB_BLOCK_COUNT(sb) - 1) / (sb->s_blocksize * 8) + 1;
}

static inline int bmap_would_wrap(unsigned bmap_nr)
{
return bmap_nr > ((1LL << 16) - 1);
}

/** this says about version of key of all items (but stat data) the
object consists of */
#define get_inode_item_key_version( inode ) \
Expand Down

0 comments on commit fe0ddb2

Please sign in to comment.