diff options
Diffstat (limited to 'fs/ext3/resize.c')
-rw-r--r-- | fs/ext3/resize.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 5e1337fd878a..b73cba12f79c 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -336,7 +336,7 @@ static int verify_reserved_gdb(struct super_block *sb, | |||
336 | unsigned five = 5; | 336 | unsigned five = 5; |
337 | unsigned seven = 7; | 337 | unsigned seven = 7; |
338 | unsigned grp; | 338 | unsigned grp; |
339 | __u32 *p = (__u32 *)primary->b_data; | 339 | __le32 *p = (__le32 *)primary->b_data; |
340 | int gdbackups = 0; | 340 | int gdbackups = 0; |
341 | 341 | ||
342 | while ((grp = ext3_list_backups(sb, &three, &five, &seven)) < end) { | 342 | while ((grp = ext3_list_backups(sb, &three, &five, &seven)) < end) { |
@@ -380,7 +380,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
380 | struct buffer_head *dind; | 380 | struct buffer_head *dind; |
381 | int gdbackups; | 381 | int gdbackups; |
382 | struct ext3_iloc iloc; | 382 | struct ext3_iloc iloc; |
383 | __u32 *data; | 383 | __le32 *data; |
384 | int err; | 384 | int err; |
385 | 385 | ||
386 | if (test_opt(sb, DEBUG)) | 386 | if (test_opt(sb, DEBUG)) |
@@ -417,7 +417,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
417 | goto exit_bh; | 417 | goto exit_bh; |
418 | } | 418 | } |
419 | 419 | ||
420 | data = (__u32 *)dind->b_data; | 420 | data = (__le32 *)dind->b_data; |
421 | if (le32_to_cpu(data[gdb_num % EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) { | 421 | if (le32_to_cpu(data[gdb_num % EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) { |
422 | ext3_warning(sb, __FUNCTION__, | 422 | ext3_warning(sb, __FUNCTION__, |
423 | "new group %u GDT block "E3FSBLK" not reserved", | 423 | "new group %u GDT block "E3FSBLK" not reserved", |
@@ -439,8 +439,8 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
439 | if ((err = ext3_reserve_inode_write(handle, inode, &iloc))) | 439 | if ((err = ext3_reserve_inode_write(handle, inode, &iloc))) |
440 | goto exit_dindj; | 440 | goto exit_dindj; |
441 | 441 | ||
442 | n_group_desc = (struct buffer_head **)kmalloc((gdb_num + 1) * | 442 | n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *), |
443 | sizeof(struct buffer_head *), GFP_KERNEL); | 443 | GFP_KERNEL); |
444 | if (!n_group_desc) { | 444 | if (!n_group_desc) { |
445 | err = -ENOMEM; | 445 | err = -ENOMEM; |
446 | ext3_warning (sb, __FUNCTION__, | 446 | ext3_warning (sb, __FUNCTION__, |
@@ -519,7 +519,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, | |||
519 | struct buffer_head *dind; | 519 | struct buffer_head *dind; |
520 | struct ext3_iloc iloc; | 520 | struct ext3_iloc iloc; |
521 | ext3_fsblk_t blk; | 521 | ext3_fsblk_t blk; |
522 | __u32 *data, *end; | 522 | __le32 *data, *end; |
523 | int gdbackups = 0; | 523 | int gdbackups = 0; |
524 | int res, i; | 524 | int res, i; |
525 | int err; | 525 | int err; |
@@ -536,8 +536,8 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, | |||
536 | } | 536 | } |
537 | 537 | ||
538 | blk = EXT3_SB(sb)->s_sbh->b_blocknr + 1 + EXT3_SB(sb)->s_gdb_count; | 538 | blk = EXT3_SB(sb)->s_sbh->b_blocknr + 1 + EXT3_SB(sb)->s_gdb_count; |
539 | data = (__u32 *)dind->b_data + EXT3_SB(sb)->s_gdb_count; | 539 | data = (__le32 *)dind->b_data + EXT3_SB(sb)->s_gdb_count; |
540 | end = (__u32 *)dind->b_data + EXT3_ADDR_PER_BLOCK(sb); | 540 | end = (__le32 *)dind->b_data + EXT3_ADDR_PER_BLOCK(sb); |
541 | 541 | ||
542 | /* Get each reserved primary GDT block and verify it holds backups */ | 542 | /* Get each reserved primary GDT block and verify it holds backups */ |
543 | for (res = 0; res < reserved_gdb; res++, blk++) { | 543 | for (res = 0; res < reserved_gdb; res++, blk++) { |
@@ -545,7 +545,8 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, | |||
545 | ext3_warning(sb, __FUNCTION__, | 545 | ext3_warning(sb, __FUNCTION__, |
546 | "reserved block "E3FSBLK | 546 | "reserved block "E3FSBLK |
547 | " not at offset %ld", | 547 | " not at offset %ld", |
548 | blk, (long)(data - (__u32 *)dind->b_data)); | 548 | blk, |
549 | (long)(data - (__le32 *)dind->b_data)); | ||
549 | err = -EINVAL; | 550 | err = -EINVAL; |
550 | goto exit_bh; | 551 | goto exit_bh; |
551 | } | 552 | } |
@@ -560,7 +561,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, | |||
560 | goto exit_bh; | 561 | goto exit_bh; |
561 | } | 562 | } |
562 | if (++data >= end) | 563 | if (++data >= end) |
563 | data = (__u32 *)dind->b_data; | 564 | data = (__le32 *)dind->b_data; |
564 | } | 565 | } |
565 | 566 | ||
566 | for (i = 0; i < reserved_gdb; i++) { | 567 | for (i = 0; i < reserved_gdb; i++) { |
@@ -584,7 +585,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, | |||
584 | blk = input->group * EXT3_BLOCKS_PER_GROUP(sb); | 585 | blk = input->group * EXT3_BLOCKS_PER_GROUP(sb); |
585 | for (i = 0; i < reserved_gdb; i++) { | 586 | for (i = 0; i < reserved_gdb; i++) { |
586 | int err2; | 587 | int err2; |
587 | data = (__u32 *)primary[i]->b_data; | 588 | data = (__le32 *)primary[i]->b_data; |
588 | /* printk("reserving backup %lu[%u] = %lu\n", | 589 | /* printk("reserving backup %lu[%u] = %lu\n", |
589 | primary[i]->b_blocknr, gdbackups, | 590 | primary[i]->b_blocknr, gdbackups, |
590 | blk + primary[i]->b_blocknr); */ | 591 | blk + primary[i]->b_blocknr); */ |
@@ -689,7 +690,7 @@ exit_err: | |||
689 | "can't update backup for group %d (err %d), " | 690 | "can't update backup for group %d (err %d), " |
690 | "forcing fsck on next reboot", group, err); | 691 | "forcing fsck on next reboot", group, err); |
691 | sbi->s_mount_state &= ~EXT3_VALID_FS; | 692 | sbi->s_mount_state &= ~EXT3_VALID_FS; |
692 | sbi->s_es->s_state &= ~cpu_to_le16(EXT3_VALID_FS); | 693 | sbi->s_es->s_state &= cpu_to_le16(~EXT3_VALID_FS); |
693 | mark_buffer_dirty(sbi->s_sbh); | 694 | mark_buffer_dirty(sbi->s_sbh); |
694 | } | 695 | } |
695 | } | 696 | } |
@@ -730,6 +731,18 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) | |||
730 | return -EPERM; | 731 | return -EPERM; |
731 | } | 732 | } |
732 | 733 | ||
734 | if (le32_to_cpu(es->s_blocks_count) + input->blocks_count < | ||
735 | le32_to_cpu(es->s_blocks_count)) { | ||
736 | ext3_warning(sb, __FUNCTION__, "blocks_count overflow\n"); | ||
737 | return -EINVAL; | ||
738 | } | ||
739 | |||
740 | if (le32_to_cpu(es->s_inodes_count) + EXT3_INODES_PER_GROUP(sb) < | ||
741 | le32_to_cpu(es->s_inodes_count)) { | ||
742 | ext3_warning(sb, __FUNCTION__, "inodes_count overflow\n"); | ||
743 | return -EINVAL; | ||
744 | } | ||
745 | |||
733 | if (reserved_gdb || gdb_off == 0) { | 746 | if (reserved_gdb || gdb_off == 0) { |
734 | if (!EXT3_HAS_COMPAT_FEATURE(sb, | 747 | if (!EXT3_HAS_COMPAT_FEATURE(sb, |
735 | EXT3_FEATURE_COMPAT_RESIZE_INODE)){ | 748 | EXT3_FEATURE_COMPAT_RESIZE_INODE)){ |
@@ -958,6 +971,11 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, | |||
958 | 971 | ||
959 | add = EXT3_BLOCKS_PER_GROUP(sb) - last; | 972 | add = EXT3_BLOCKS_PER_GROUP(sb) - last; |
960 | 973 | ||
974 | if (o_blocks_count + add < o_blocks_count) { | ||
975 | ext3_warning(sb, __FUNCTION__, "blocks_count overflow"); | ||
976 | return -EINVAL; | ||
977 | } | ||
978 | |||
961 | if (o_blocks_count + add > n_blocks_count) | 979 | if (o_blocks_count + add > n_blocks_count) |
962 | add = n_blocks_count - o_blocks_count; | 980 | add = n_blocks_count - o_blocks_count; |
963 | 981 | ||