aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-07 12:01:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-07 12:01:33 -0500
commita9913f23f39f4aa74956587a03e78b758a10c314 (patch)
tree55bbe50b2417009fc20d4fcaa248bebd1d2bf887 /fs/ext2
parentb39a07a5e073ba783cd86b60c77044587ddbf8a1 (diff)
parent52b9666efd8b0874d334de718a7d561e7b0eb1cc (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')
-rw-r--r--fs/ext2/ext2.h1
-rw-r--r--fs/ext2/file.c1
-rw-r--r--fs/ext2/ialloc.c2
-rw-r--r--fs/ext2/inode.c30
-rw-r--r--fs/ext2/namei.c2
-rw-r--r--fs/ext2/super.c44
-rw-r--r--fs/ext2/symlink.c2
-rw-r--r--fs/ext2/xattr.c1
8 files changed, 64 insertions, 19 deletions
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 93fcfe7bbb3b..10ab238de9a6 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -758,6 +758,7 @@ extern int ext2_write_inode (struct inode *, struct writeback_control *);
758extern void ext2_evict_inode(struct inode *); 758extern void ext2_evict_inode(struct inode *);
759extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); 759extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
760extern int ext2_setattr (struct dentry *, struct iattr *); 760extern int ext2_setattr (struct dentry *, struct iattr *);
761extern int ext2_getattr (const struct path *, struct kstat *, u32, unsigned int);
761extern void ext2_set_inode_flags(struct inode *inode); 762extern void ext2_set_inode_flags(struct inode *inode);
762extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, 763extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
763 u64 start, u64 len); 764 u64 start, u64 len);
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 28b2609f25c1..39c4772e96c9 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -199,6 +199,7 @@ const struct inode_operations ext2_file_inode_operations = {
199#ifdef CONFIG_EXT2_FS_XATTR 199#ifdef CONFIG_EXT2_FS_XATTR
200 .listxattr = ext2_listxattr, 200 .listxattr = ext2_listxattr,
201#endif 201#endif
202 .getattr = ext2_getattr,
202 .setattr = ext2_setattr, 203 .setattr = ext2_setattr,
203 .get_acl = ext2_get_acl, 204 .get_acl = ext2_get_acl,
204 .set_acl = ext2_set_acl, 205 .set_acl = ext2_set_acl,
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 5c3d7b7e4975..a0c5ea91fcd4 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -222,8 +222,6 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
222 best_desc = desc; 222 best_desc = desc;
223 } 223 }
224 } 224 }
225 if (!best_desc)
226 return -1;
227 225
228 return best_group; 226 return best_group;
229} 227}
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index e4bb9386c045..c27c27300d95 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -717,7 +717,7 @@ static int ext2_get_blocks(struct inode *inode,
717 /* the number of blocks need to allocate for [d,t]indirect blocks */ 717 /* the number of blocks need to allocate for [d,t]indirect blocks */
718 indirect_blks = (chain + depth) - partial - 1; 718 indirect_blks = (chain + depth) - partial - 1;
719 /* 719 /*
720 * Next look up the indirect map to count the totoal number of 720 * Next look up the indirect map to count the total number of
721 * direct blocks to allocate for this branch. 721 * direct blocks to allocate for this branch.
722 */ 722 */
723 count = ext2_blks_to_allocate(partial, indirect_blks, 723 count = ext2_blks_to_allocate(partial, indirect_blks,
@@ -1239,6 +1239,7 @@ do_indirects:
1239 mark_inode_dirty(inode); 1239 mark_inode_dirty(inode);
1240 ext2_free_branches(inode, &nr, &nr+1, 1); 1240 ext2_free_branches(inode, &nr, &nr+1, 1);
1241 } 1241 }
1242 /* fall through */
1242 case EXT2_IND_BLOCK: 1243 case EXT2_IND_BLOCK:
1243 nr = i_data[EXT2_DIND_BLOCK]; 1244 nr = i_data[EXT2_DIND_BLOCK];
1244 if (nr) { 1245 if (nr) {
@@ -1246,6 +1247,7 @@ do_indirects:
1246 mark_inode_dirty(inode); 1247 mark_inode_dirty(inode);
1247 ext2_free_branches(inode, &nr, &nr+1, 2); 1248 ext2_free_branches(inode, &nr, &nr+1, 2);
1248 } 1249 }
1250 /* fall through */
1249 case EXT2_DIND_BLOCK: 1251 case EXT2_DIND_BLOCK:
1250 nr = i_data[EXT2_TIND_BLOCK]; 1252 nr = i_data[EXT2_TIND_BLOCK];
1251 if (nr) { 1253 if (nr) {
@@ -1635,6 +1637,32 @@ int ext2_write_inode(struct inode *inode, struct writeback_control *wbc)
1635 return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); 1637 return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
1636} 1638}
1637 1639
1640int ext2_getattr(const struct path *path, struct kstat *stat,
1641 u32 request_mask, unsigned int query_falgs)
1642{
1643 struct inode *inode = d_inode(path->dentry);
1644 struct ext2_inode_info *ei = EXT2_I(inode);
1645 unsigned int flags;
1646
1647 flags = ei->i_flags & EXT2_FL_USER_VISIBLE;
1648 if (flags & EXT2_APPEND_FL)
1649 stat->attributes |= STATX_ATTR_APPEND;
1650 if (flags & EXT2_COMPR_FL)
1651 stat->attributes |= STATX_ATTR_COMPRESSED;
1652 if (flags & EXT2_IMMUTABLE_FL)
1653 stat->attributes |= STATX_ATTR_IMMUTABLE;
1654 if (flags & EXT2_NODUMP_FL)
1655 stat->attributes |= STATX_ATTR_NODUMP;
1656 stat->attributes_mask |= (STATX_ATTR_APPEND |
1657 STATX_ATTR_COMPRESSED |
1658 STATX_ATTR_ENCRYPTED |
1659 STATX_ATTR_IMMUTABLE |
1660 STATX_ATTR_NODUMP);
1661
1662 generic_fillattr(inode, stat);
1663 return 0;
1664}
1665
1638int ext2_setattr(struct dentry *dentry, struct iattr *iattr) 1666int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
1639{ 1667{
1640 struct inode *inode = d_inode(dentry); 1668 struct inode *inode = d_inode(dentry);
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 0c26dcc5d850..ccfbbf59e2fc 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -416,6 +416,7 @@ const struct inode_operations ext2_dir_inode_operations = {
416#ifdef CONFIG_EXT2_FS_XATTR 416#ifdef CONFIG_EXT2_FS_XATTR
417 .listxattr = ext2_listxattr, 417 .listxattr = ext2_listxattr,
418#endif 418#endif
419 .getattr = ext2_getattr,
419 .setattr = ext2_setattr, 420 .setattr = ext2_setattr,
420 .get_acl = ext2_get_acl, 421 .get_acl = ext2_get_acl,
421 .set_acl = ext2_set_acl, 422 .set_acl = ext2_set_acl,
@@ -426,6 +427,7 @@ const struct inode_operations ext2_special_inode_operations = {
426#ifdef CONFIG_EXT2_FS_XATTR 427#ifdef CONFIG_EXT2_FS_XATTR
427 .listxattr = ext2_listxattr, 428 .listxattr = ext2_listxattr,
428#endif 429#endif
430 .getattr = ext2_getattr,
429 .setattr = ext2_setattr, 431 .setattr = ext2_setattr,
430 .get_acl = ext2_get_acl, 432 .get_acl = ext2_get_acl,
431 .set_acl = ext2_set_acl, 433 .set_acl = ext2_set_acl,
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;
801check_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 }
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index d5589ddcc281..00cdb8679486 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -23,6 +23,7 @@
23 23
24const struct inode_operations ext2_symlink_inode_operations = { 24const struct inode_operations ext2_symlink_inode_operations = {
25 .get_link = page_get_link, 25 .get_link = page_get_link,
26 .getattr = ext2_getattr,
26 .setattr = ext2_setattr, 27 .setattr = ext2_setattr,
27#ifdef CONFIG_EXT2_FS_XATTR 28#ifdef CONFIG_EXT2_FS_XATTR
28 .listxattr = ext2_listxattr, 29 .listxattr = ext2_listxattr,
@@ -31,6 +32,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
31 32
32const struct inode_operations ext2_fast_symlink_inode_operations = { 33const struct inode_operations ext2_fast_symlink_inode_operations = {
33 .get_link = simple_get_link, 34 .get_link = simple_get_link,
35 .getattr = ext2_getattr,
34 .setattr = ext2_setattr, 36 .setattr = ext2_setattr,
35#ifdef CONFIG_EXT2_FS_XATTR 37#ifdef CONFIG_EXT2_FS_XATTR
36 .listxattr = ext2_listxattr, 38 .listxattr = ext2_listxattr,
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index 4f30876ee325..1e33e0ac8cf1 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -342,6 +342,7 @@ static void ext2_xattr_update_super_block(struct super_block *sb)
342 return; 342 return;
343 343
344 spin_lock(&EXT2_SB(sb)->s_lock); 344 spin_lock(&EXT2_SB(sb)->s_lock);
345 ext2_update_dynamic_rev(sb);
345 EXT2_SET_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR); 346 EXT2_SET_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR);
346 spin_unlock(&EXT2_SB(sb)->s_lock); 347 spin_unlock(&EXT2_SB(sb)->s_lock);
347 mark_buffer_dirty(EXT2_SB(sb)->s_sbh); 348 mark_buffer_dirty(EXT2_SB(sb)->s_sbh);