aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/ext4.h4
-rw-r--r--fs/ext4/inode.c11
-rw-r--r--fs/ext4/mballoc.c9
-rw-r--r--fs/ext4/super.c2
-rw-r--r--fs/ext4/xattr.c15
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 */
566static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block, 568static 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);