diff options
| -rw-r--r-- | fs/ext4/ext4.h | 4 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 11 | ||||
| -rw-r--r-- | fs/ext4/mballoc.c | 9 | ||||
| -rw-r--r-- | fs/ext4/super.c | 2 | ||||
| -rw-r--r-- | fs/ext4/xattr.c | 15 |
5 files changed, 38 insertions, 3 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 4dc64ed58d26..2a0f75d55fad 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -403,6 +403,9 @@ struct ext4_mount_options { | |||
| 403 | #endif | 403 | #endif |
| 404 | }; | 404 | }; |
| 405 | 405 | ||
| 406 | /* Max physical block we can addres w/o extents */ | ||
| 407 | #define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF | ||
| 408 | |||
| 406 | /* | 409 | /* |
| 407 | * Structure of an inode on the disk | 410 | * Structure of an inode on the disk |
| 408 | */ | 411 | */ |
| @@ -857,6 +860,7 @@ struct ext4_sb_info { | |||
| 857 | unsigned long s_gdb_count; /* Number of group descriptor blocks */ | 860 | unsigned long s_gdb_count; /* Number of group descriptor blocks */ |
| 858 | unsigned long s_desc_per_block; /* Number of group descriptors per block */ | 861 | unsigned long s_desc_per_block; /* Number of group descriptors per block */ |
| 859 | ext4_group_t s_groups_count; /* Number of groups in the fs */ | 862 | ext4_group_t s_groups_count; /* Number of groups in the fs */ |
| 863 | ext4_group_t s_blockfile_groups;/* Groups acceptable for non-extent files */ | ||
| 860 | unsigned long s_overhead_last; /* Last calculated overhead */ | 864 | unsigned long s_overhead_last; /* Last calculated overhead */ |
| 861 | unsigned long s_blocks_last; /* Last seen block count */ | 865 | unsigned long s_blocks_last; /* Last seen block count */ |
| 862 | loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */ | 866 | loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */ |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d04c8428bde2..5a8979259c9a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -562,15 +562,21 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) | |||
| 562 | * | 562 | * |
| 563 | * Normally this function find the preferred place for block allocation, | 563 | * Normally this function find the preferred place for block allocation, |
| 564 | * returns it. | 564 | * returns it. |
| 565 | * Because this is only used for non-extent files, we limit the block nr | ||
| 566 | * to 32 bits. | ||
| 565 | */ | 567 | */ |
| 566 | static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block, | 568 | static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block, |
| 567 | Indirect *partial) | 569 | Indirect *partial) |
| 568 | { | 570 | { |
| 571 | ext4_fsblk_t goal; | ||
| 572 | |||
| 569 | /* | 573 | /* |
| 570 | * XXX need to get goal block from mballoc's data structures | 574 | * XXX need to get goal block from mballoc's data structures |
| 571 | */ | 575 | */ |
| 572 | 576 | ||
| 573 | return ext4_find_near(inode, partial); | 577 | goal = ext4_find_near(inode, partial); |
| 578 | goal = goal & EXT4_MAX_BLOCK_FILE_PHYS; | ||
| 579 | return goal; | ||
| 574 | } | 580 | } |
| 575 | 581 | ||
| 576 | /** | 582 | /** |
| @@ -651,6 +657,8 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, | |||
| 651 | if (*err) | 657 | if (*err) |
| 652 | goto failed_out; | 658 | goto failed_out; |
| 653 | 659 | ||
| 660 | BUG_ON(current_block + count > EXT4_MAX_BLOCK_FILE_PHYS); | ||
| 661 | |||
| 654 | target -= count; | 662 | target -= count; |
| 655 | /* allocate blocks for indirect blocks */ | 663 | /* allocate blocks for indirect blocks */ |
| 656 | while (index < indirect_blks && count) { | 664 | while (index < indirect_blks && count) { |
| @@ -685,6 +693,7 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, | |||
| 685 | ar.flags = EXT4_MB_HINT_DATA; | 693 | ar.flags = EXT4_MB_HINT_DATA; |
| 686 | 694 | ||
| 687 | current_block = ext4_mb_new_blocks(handle, &ar, err); | 695 | current_block = ext4_mb_new_blocks(handle, &ar, err); |
| 696 | BUG_ON(current_block + ar.len > EXT4_MAX_BLOCK_FILE_PHYS); | ||
| 688 | 697 | ||
| 689 | if (*err && (target == blks)) { | 698 | if (*err && (target == blks)) { |
| 690 | /* | 699 | /* |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index d23056d375b3..e9c61896d605 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -1965,6 +1965,10 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) | |||
| 1965 | sb = ac->ac_sb; | 1965 | sb = ac->ac_sb; |
| 1966 | sbi = EXT4_SB(sb); | 1966 | sbi = EXT4_SB(sb); |
| 1967 | ngroups = ext4_get_groups_count(sb); | 1967 | ngroups = ext4_get_groups_count(sb); |
| 1968 | /* non-extent files are limited to low blocks/groups */ | ||
| 1969 | if (!(EXT4_I(ac->ac_inode)->i_flags & EXT4_EXTENTS_FL)) | ||
| 1970 | ngroups = sbi->s_blockfile_groups; | ||
| 1971 | |||
| 1968 | BUG_ON(ac->ac_status == AC_STATUS_FOUND); | 1972 | BUG_ON(ac->ac_status == AC_STATUS_FOUND); |
| 1969 | 1973 | ||
| 1970 | /* first, try the goal */ | 1974 | /* first, try the goal */ |
| @@ -3382,6 +3386,11 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac) | |||
| 3382 | ac->ac_o_ex.fe_logical >= pa->pa_lstart + pa->pa_len) | 3386 | ac->ac_o_ex.fe_logical >= pa->pa_lstart + pa->pa_len) |
| 3383 | continue; | 3387 | continue; |
| 3384 | 3388 | ||
| 3389 | /* non-extent files can't have physical blocks past 2^32 */ | ||
| 3390 | if (!(EXT4_I(ac->ac_inode)->i_flags & EXT4_EXTENTS_FL) && | ||
| 3391 | pa->pa_pstart + pa->pa_len > EXT4_MAX_BLOCK_FILE_PHYS) | ||
| 3392 | continue; | ||
| 3393 | |||
| 3385 | /* found preallocated blocks, use them */ | 3394 | /* found preallocated blocks, use them */ |
| 3386 | spin_lock(&pa->pa_lock); | 3395 | spin_lock(&pa->pa_lock); |
| 3387 | if (pa->pa_deleted == 0 && pa->pa_free) { | 3396 | if (pa->pa_deleted == 0 && pa->pa_free) { |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index af95dd8ba54b..a6b1ab734728 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -2616,6 +2616,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2616 | goto failed_mount; | 2616 | goto failed_mount; |
| 2617 | } | 2617 | } |
| 2618 | sbi->s_groups_count = blocks_count; | 2618 | sbi->s_groups_count = blocks_count; |
| 2619 | sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count, | ||
| 2620 | (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); | ||
| 2619 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / | 2621 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / |
| 2620 | EXT4_DESC_PER_BLOCK(sb); | 2622 | EXT4_DESC_PER_BLOCK(sb); |
| 2621 | sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *), | 2623 | sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *), |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 62b31c246994..fed5b01d7a8d 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
| @@ -810,12 +810,23 @@ inserted: | |||
| 810 | get_bh(new_bh); | 810 | get_bh(new_bh); |
| 811 | } else { | 811 | } else { |
| 812 | /* We need to allocate a new block */ | 812 | /* We need to allocate a new block */ |
| 813 | ext4_fsblk_t goal = ext4_group_first_block_no(sb, | 813 | ext4_fsblk_t goal, block; |
| 814 | |||
| 815 | goal = ext4_group_first_block_no(sb, | ||
| 814 | EXT4_I(inode)->i_block_group); | 816 | EXT4_I(inode)->i_block_group); |
| 815 | ext4_fsblk_t block = ext4_new_meta_blocks(handle, inode, | 817 | |
| 818 | /* non-extent files can't have physical blocks past 2^32 */ | ||
| 819 | if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) | ||
| 820 | goal = goal & EXT4_MAX_BLOCK_FILE_PHYS; | ||
| 821 | |||
| 822 | block = ext4_new_meta_blocks(handle, inode, | ||
| 816 | goal, NULL, &error); | 823 | goal, NULL, &error); |
| 817 | if (error) | 824 | if (error) |
| 818 | goto cleanup; | 825 | goto cleanup; |
| 826 | |||
| 827 | if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) | ||
| 828 | BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS); | ||
| 829 | |||
| 819 | ea_idebug(inode, "creating block %d", block); | 830 | ea_idebug(inode, "creating block %d", block); |
| 820 | 831 | ||
| 821 | new_bh = sb_getblk(sb, block); | 832 | new_bh = sb_getblk(sb, block); |
