diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 12:01:33 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 12:01:33 -0500 |
| commit | a9913f23f39f4aa74956587a03e78b758a10c314 (patch) | |
| tree | 55bbe50b2417009fc20d4fcaa248bebd1d2bf887 /fs/ext2/super.c | |
| parent | b39a07a5e073ba783cd86b60c77044587ddbf8a1 (diff) | |
| parent | 52b9666efd8b0874d334de718a7d561e7b0eb1cc (diff) | |
Merge tag 'fs_for_v5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull ext2 and udf fixes from Jan Kara:
"A couple of fixes for udf and ext2. Namely:
- fix making ext2 mountable (again) with 64k blocksize
- fix for ext2 statx(2) handling
- fix for udf handling of corrupted filesystem so that it doesn't get
corrupted even further
- couple smaller ext2 and udf cleanups"
* tag 'fs_for_v5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
udf: Drop pointless check from udf_sync_fs()
ext2: support statx syscall
udf: disallow RW mount without valid integrity descriptor
udf: finalize integrity descriptor before writeback
udf: factor out LVID finalization for reuse
ext2: Fix underflow in ext2_max_size()
ext2: Fix a typo in comment
ext2: Remove redundant check for finding no group
ext2: Annotate implicit fall through in __ext2_truncate_blocks
ext2: Set superblock revision when enabling xattr feature
ext2: Remove redundant check on s_inode_size
ext2: set proper return code
Diffstat (limited to 'fs/ext2/super.c')
| -rw-r--r-- | fs/ext2/super.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 73b2d528237f..0128010a0874 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
| @@ -757,7 +757,8 @@ static loff_t ext2_max_size(int bits) | |||
| 757 | { | 757 | { |
| 758 | loff_t res = EXT2_NDIR_BLOCKS; | 758 | loff_t res = EXT2_NDIR_BLOCKS; |
| 759 | int meta_blocks; | 759 | int meta_blocks; |
| 760 | loff_t upper_limit; | 760 | unsigned int upper_limit; |
| 761 | unsigned int ppb = 1 << (bits-2); | ||
| 761 | 762 | ||
| 762 | /* This is calculated to be the largest file size for a | 763 | /* This is calculated to be the largest file size for a |
| 763 | * dense, file such that the total number of | 764 | * dense, file such that the total number of |
| @@ -771,24 +772,34 @@ static loff_t ext2_max_size(int bits) | |||
| 771 | /* total blocks in file system block size */ | 772 | /* total blocks in file system block size */ |
| 772 | upper_limit >>= (bits - 9); | 773 | upper_limit >>= (bits - 9); |
| 773 | 774 | ||
| 775 | /* Compute how many blocks we can address by block tree */ | ||
| 776 | res += 1LL << (bits-2); | ||
| 777 | res += 1LL << (2*(bits-2)); | ||
| 778 | res += 1LL << (3*(bits-2)); | ||
| 779 | /* Does block tree limit file size? */ | ||
| 780 | if (res < upper_limit) | ||
| 781 | goto check_lfs; | ||
| 774 | 782 | ||
| 783 | res = upper_limit; | ||
| 784 | /* How many metadata blocks are needed for addressing upper_limit? */ | ||
| 785 | upper_limit -= EXT2_NDIR_BLOCKS; | ||
| 775 | /* indirect blocks */ | 786 | /* indirect blocks */ |
| 776 | meta_blocks = 1; | 787 | meta_blocks = 1; |
| 788 | upper_limit -= ppb; | ||
| 777 | /* double indirect blocks */ | 789 | /* double indirect blocks */ |
| 778 | meta_blocks += 1 + (1LL << (bits-2)); | 790 | if (upper_limit < ppb * ppb) { |
| 779 | /* tripple indirect blocks */ | 791 | meta_blocks += 1 + DIV_ROUND_UP(upper_limit, ppb); |
| 780 | meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2))); | 792 | res -= meta_blocks; |
| 781 | 793 | goto check_lfs; | |
| 782 | upper_limit -= meta_blocks; | 794 | } |
| 783 | upper_limit <<= bits; | 795 | meta_blocks += 1 + ppb; |
| 784 | 796 | upper_limit -= ppb * ppb; | |
| 785 | res += 1LL << (bits-2); | 797 | /* tripple indirect blocks for the rest */ |
| 786 | res += 1LL << (2*(bits-2)); | 798 | meta_blocks += 1 + DIV_ROUND_UP(upper_limit, ppb) + |
| 787 | res += 1LL << (3*(bits-2)); | 799 | DIV_ROUND_UP(upper_limit, ppb*ppb); |
| 800 | res -= meta_blocks; | ||
| 801 | check_lfs: | ||
| 788 | res <<= bits; | 802 | res <<= bits; |
| 789 | if (res > upper_limit) | ||
| 790 | res = upper_limit; | ||
| 791 | |||
| 792 | if (res > MAX_LFS_FILESIZE) | 803 | if (res > MAX_LFS_FILESIZE) |
| 793 | res = MAX_LFS_FILESIZE; | 804 | res = MAX_LFS_FILESIZE; |
| 794 | 805 | ||
| @@ -1024,8 +1035,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1024 | sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); | 1035 | sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); |
| 1025 | sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); | 1036 | sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); |
| 1026 | 1037 | ||
| 1027 | if (EXT2_INODE_SIZE(sb) == 0) | ||
| 1028 | goto cantfind_ext2; | ||
| 1029 | sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb); | 1038 | sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb); |
| 1030 | if (sbi->s_inodes_per_block == 0 || sbi->s_inodes_per_group == 0) | 1039 | if (sbi->s_inodes_per_block == 0 || sbi->s_inodes_per_group == 0) |
| 1031 | goto cantfind_ext2; | 1040 | goto cantfind_ext2; |
| @@ -1087,12 +1096,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1087 | sizeof(struct buffer_head *), | 1096 | sizeof(struct buffer_head *), |
| 1088 | GFP_KERNEL); | 1097 | GFP_KERNEL); |
| 1089 | if (sbi->s_group_desc == NULL) { | 1098 | if (sbi->s_group_desc == NULL) { |
| 1099 | ret = -ENOMEM; | ||
| 1090 | ext2_msg(sb, KERN_ERR, "error: not enough memory"); | 1100 | ext2_msg(sb, KERN_ERR, "error: not enough memory"); |
| 1091 | goto failed_mount; | 1101 | goto failed_mount; |
| 1092 | } | 1102 | } |
| 1093 | bgl_lock_init(sbi->s_blockgroup_lock); | 1103 | bgl_lock_init(sbi->s_blockgroup_lock); |
| 1094 | sbi->s_debts = kcalloc(sbi->s_groups_count, sizeof(*sbi->s_debts), GFP_KERNEL); | 1104 | sbi->s_debts = kcalloc(sbi->s_groups_count, sizeof(*sbi->s_debts), GFP_KERNEL); |
| 1095 | if (!sbi->s_debts) { | 1105 | if (!sbi->s_debts) { |
| 1106 | ret = -ENOMEM; | ||
| 1096 | ext2_msg(sb, KERN_ERR, "error: not enough memory"); | 1107 | ext2_msg(sb, KERN_ERR, "error: not enough memory"); |
| 1097 | goto failed_mount_group_desc; | 1108 | goto failed_mount_group_desc; |
| 1098 | } | 1109 | } |
| @@ -1148,6 +1159,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1148 | #ifdef CONFIG_EXT2_FS_XATTR | 1159 | #ifdef CONFIG_EXT2_FS_XATTR |
| 1149 | sbi->s_ea_block_cache = ext2_xattr_create_cache(); | 1160 | sbi->s_ea_block_cache = ext2_xattr_create_cache(); |
| 1150 | if (!sbi->s_ea_block_cache) { | 1161 | if (!sbi->s_ea_block_cache) { |
| 1162 | ret = -ENOMEM; | ||
| 1151 | ext2_msg(sb, KERN_ERR, "Failed to create ea_block_cache"); | 1163 | ext2_msg(sb, KERN_ERR, "Failed to create ea_block_cache"); |
| 1152 | goto failed_mount3; | 1164 | goto failed_mount3; |
| 1153 | } | 1165 | } |
