diff options
Diffstat (limited to 'fs/ext4')
-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); |