aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext2/super.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 154e25f13d77..6abaf75163f0 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -680,11 +680,31 @@ static int ext2_check_descriptors (struct super_block * sb)
680static loff_t ext2_max_size(int bits) 680static loff_t ext2_max_size(int bits)
681{ 681{
682 loff_t res = EXT2_NDIR_BLOCKS; 682 loff_t res = EXT2_NDIR_BLOCKS;
683 /* This constant is calculated to be the largest file size for a 683 int meta_blocks;
684 * dense, 4k-blocksize file such that the total number of 684 loff_t upper_limit;
685
686 /* This is calculated to be the largest file size for a
687 * dense, file such that the total number of
685 * sectors in the file, including data and all indirect blocks, 688 * sectors in the file, including data and all indirect blocks,
686 * does not exceed 2^32. */ 689 * does not exceed 2^32 -1
687 const loff_t upper_limit = 0x1ff7fffd000LL; 690 * __u32 i_blocks representing the total number of
691 * 512 bytes blocks of the file
692 */
693 upper_limit = (1LL << 32) - 1;
694
695 /* total blocks in file system block size */
696 upper_limit >>= (bits - 9);
697
698
699 /* indirect blocks */
700 meta_blocks = 1;
701 /* double indirect blocks */
702 meta_blocks += 1 + (1LL << (bits-2));
703 /* tripple indirect blocks */
704 meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2)));
705
706 upper_limit -= meta_blocks;
707 upper_limit <<= bits;
688 708
689 res += 1LL << (bits-2); 709 res += 1LL << (bits-2);
690 res += 1LL << (2*(bits-2)); 710 res += 1LL << (2*(bits-2));
@@ -692,6 +712,10 @@ static loff_t ext2_max_size(int bits)
692 res <<= bits; 712 res <<= bits;
693 if (res > upper_limit) 713 if (res > upper_limit)
694 res = upper_limit; 714 res = upper_limit;
715
716 if (res > MAX_LFS_FILESIZE)
717 res = MAX_LFS_FILESIZE;
718
695 return res; 719 return res;
696} 720}
697 721