inode.c (ccec4a4a4f27b22e51ec6a143319db49b7570581) inode.c (8a363970d1dc38c4ec4ad575c862f776f468d057)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * linux/fs/ext4/inode.c
4 *
5 * Copyright (C) 1992, 1993, 1994, 1995
6 * Remy Card (card@masi.ibp.fr)
7 * Laboratoire MASI - Institut Blaise Pascal
8 * Universite Pierre et Marie Curie (Paris VI)

--- 4803 unchanged lines hidden (view full) ---

4812static inline u64 ext4_inode_peek_iversion(const struct inode *inode)
4813{
4814 if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL))
4815 return inode_peek_iversion_raw(inode);
4816 else
4817 return inode_peek_iversion(inode);
4818}
4819
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * linux/fs/ext4/inode.c
4 *
5 * Copyright (C) 1992, 1993, 1994, 1995
6 * Remy Card (card@masi.ibp.fr)
7 * Laboratoire MASI - Institut Blaise Pascal
8 * Universite Pierre et Marie Curie (Paris VI)

--- 4803 unchanged lines hidden (view full) ---

4812static inline u64 ext4_inode_peek_iversion(const struct inode *inode)
4813{
4814 if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL))
4815 return inode_peek_iversion_raw(inode);
4816 else
4817 return inode_peek_iversion(inode);
4818}
4819
4820struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
4820struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
4821 ext4_iget_flags flags, const char *function,
4822 unsigned int line)
4821{
4822 struct ext4_iloc iloc;
4823 struct ext4_inode *raw_inode;
4824 struct ext4_inode_info *ei;
4825 struct inode *inode;
4826 journal_t *journal = EXT4_SB(sb)->s_journal;
4827 long ret;
4828 loff_t size;
4829 int block;
4830 uid_t i_uid;
4831 gid_t i_gid;
4832 projid_t i_projid;
4833
4823{
4824 struct ext4_iloc iloc;
4825 struct ext4_inode *raw_inode;
4826 struct ext4_inode_info *ei;
4827 struct inode *inode;
4828 journal_t *journal = EXT4_SB(sb)->s_journal;
4829 long ret;
4830 loff_t size;
4831 int block;
4832 uid_t i_uid;
4833 gid_t i_gid;
4834 projid_t i_projid;
4835
4836 if (((flags & EXT4_IGET_NORMAL) &&
4837 (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) ||
4838 (ino < EXT4_ROOT_INO) ||
4839 (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) {
4840 if (flags & EXT4_IGET_HANDLE)
4841 return ERR_PTR(-ESTALE);
4842 __ext4_error(sb, function, line,
4843 "inode #%lu: comm %s: iget: illegal inode #",
4844 ino, current->comm);
4845 return ERR_PTR(-EFSCORRUPTED);
4846 }
4847
4834 inode = iget_locked(sb, ino);
4835 if (!inode)
4836 return ERR_PTR(-ENOMEM);
4837 if (!(inode->i_state & I_NEW))
4838 return inode;
4839
4840 ei = EXT4_I(inode);
4841 iloc.bh = NULL;
4842
4843 ret = __ext4_get_inode_loc(inode, &iloc, 0);
4844 if (ret < 0)
4845 goto bad_inode;
4846 raw_inode = ext4_raw_inode(&iloc);
4847
4848 if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) {
4848 inode = iget_locked(sb, ino);
4849 if (!inode)
4850 return ERR_PTR(-ENOMEM);
4851 if (!(inode->i_state & I_NEW))
4852 return inode;
4853
4854 ei = EXT4_I(inode);
4855 iloc.bh = NULL;
4856
4857 ret = __ext4_get_inode_loc(inode, &iloc, 0);
4858 if (ret < 0)
4859 goto bad_inode;
4860 raw_inode = ext4_raw_inode(&iloc);
4861
4862 if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) {
4849 EXT4_ERROR_INODE(inode, "root inode unallocated");
4863 ext4_error_inode(inode, function, line, 0,
4864 "iget: root inode unallocated");
4850 ret = -EFSCORRUPTED;
4851 goto bad_inode;
4852 }
4853
4865 ret = -EFSCORRUPTED;
4866 goto bad_inode;
4867 }
4868
4869 if ((flags & EXT4_IGET_HANDLE) &&
4870 (raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) {
4871 ret = -ESTALE;
4872 goto bad_inode;
4873 }
4874
4854 if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
4855 ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
4856 if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
4857 EXT4_INODE_SIZE(inode->i_sb) ||
4858 (ei->i_extra_isize & 3)) {
4875 if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
4876 ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
4877 if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
4878 EXT4_INODE_SIZE(inode->i_sb) ||
4879 (ei->i_extra_isize & 3)) {
4859 EXT4_ERROR_INODE(inode,
4860 "bad extra_isize %u (inode size %u)",
4880 ext4_error_inode(inode, function, line, 0,
4881 "iget: bad extra_isize %u "
4882 "(inode size %u)",
4861 ei->i_extra_isize,
4862 EXT4_INODE_SIZE(inode->i_sb));
4863 ret = -EFSCORRUPTED;
4864 goto bad_inode;
4865 }
4866 } else
4867 ei->i_extra_isize = 0;
4868

--- 5 unchanged lines hidden (view full) ---

4874 __le32 gen = raw_inode->i_generation;
4875 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&inum,
4876 sizeof(inum));
4877 ei->i_csum_seed = ext4_chksum(sbi, csum, (__u8 *)&gen,
4878 sizeof(gen));
4879 }
4880
4881 if (!ext4_inode_csum_verify(inode, raw_inode, ei)) {
4883 ei->i_extra_isize,
4884 EXT4_INODE_SIZE(inode->i_sb));
4885 ret = -EFSCORRUPTED;
4886 goto bad_inode;
4887 }
4888 } else
4889 ei->i_extra_isize = 0;
4890

--- 5 unchanged lines hidden (view full) ---

4896 __le32 gen = raw_inode->i_generation;
4897 csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&inum,
4898 sizeof(inum));
4899 ei->i_csum_seed = ext4_chksum(sbi, csum, (__u8 *)&gen,
4900 sizeof(gen));
4901 }
4902
4903 if (!ext4_inode_csum_verify(inode, raw_inode, ei)) {
4882 EXT4_ERROR_INODE(inode, "checksum invalid");
4904 ext4_error_inode(inode, function, line, 0,
4905 "iget: checksum invalid");
4883 ret = -EFSBADCRC;
4884 goto bad_inode;
4885 }
4886
4887 inode->i_mode = le16_to_cpu(raw_inode->i_mode);
4888 i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4889 i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4890 if (ext4_has_feature_project(sb) &&

--- 40 unchanged lines hidden (view full) ---

4931 ext4_set_inode_flags(inode);
4932 inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
4933 ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
4934 if (ext4_has_feature_64bit(sb))
4935 ei->i_file_acl |=
4936 ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
4937 inode->i_size = ext4_isize(sb, raw_inode);
4938 if ((size = i_size_read(inode)) < 0) {
4906 ret = -EFSBADCRC;
4907 goto bad_inode;
4908 }
4909
4910 inode->i_mode = le16_to_cpu(raw_inode->i_mode);
4911 i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4912 i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4913 if (ext4_has_feature_project(sb) &&

--- 40 unchanged lines hidden (view full) ---

4954 ext4_set_inode_flags(inode);
4955 inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
4956 ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
4957 if (ext4_has_feature_64bit(sb))
4958 ei->i_file_acl |=
4959 ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
4960 inode->i_size = ext4_isize(sb, raw_inode);
4961 if ((size = i_size_read(inode)) < 0) {
4939 EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size);
4962 ext4_error_inode(inode, function, line, 0,
4963 "iget: bad i_size value: %lld", size);
4940 ret = -EFSCORRUPTED;
4941 goto bad_inode;
4942 }
4943 ei->i_disksize = inode->i_size;
4944#ifdef CONFIG_QUOTA
4945 ei->i_reserved_quota = 0;
4946#endif
4947 inode->i_generation = le32_to_cpu(raw_inode->i_generation);

--- 59 unchanged lines hidden (view full) ---

5007 (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
5008 }
5009 ext4_inode_set_iversion_queried(inode, ivers);
5010 }
5011
5012 ret = 0;
5013 if (ei->i_file_acl &&
5014 !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
4964 ret = -EFSCORRUPTED;
4965 goto bad_inode;
4966 }
4967 ei->i_disksize = inode->i_size;
4968#ifdef CONFIG_QUOTA
4969 ei->i_reserved_quota = 0;
4970#endif
4971 inode->i_generation = le32_to_cpu(raw_inode->i_generation);

--- 59 unchanged lines hidden (view full) ---

5031 (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
5032 }
5033 ext4_inode_set_iversion_queried(inode, ivers);
5034 }
5035
5036 ret = 0;
5037 if (ei->i_file_acl &&
5038 !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
5015 EXT4_ERROR_INODE(inode, "bad extended attribute block %llu",
5039 ext4_error_inode(inode, function, line, 0,
5040 "iget: bad extended attribute block %llu",
5016 ei->i_file_acl);
5017 ret = -EFSCORRUPTED;
5018 goto bad_inode;
5019 } else if (!ext4_has_inline_data(inode)) {
5020 /* validate the block references in the inode */
5021 if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
5022 (S_ISLNK(inode->i_mode) &&
5023 !ext4_inode_is_fast_symlink(inode))) {

--- 11 unchanged lines hidden (view full) ---

5035 inode->i_fop = &ext4_file_operations;
5036 ext4_set_aops(inode);
5037 } else if (S_ISDIR(inode->i_mode)) {
5038 inode->i_op = &ext4_dir_inode_operations;
5039 inode->i_fop = &ext4_dir_operations;
5040 } else if (S_ISLNK(inode->i_mode)) {
5041 /* VFS does not allow setting these so must be corruption */
5042 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
5041 ei->i_file_acl);
5042 ret = -EFSCORRUPTED;
5043 goto bad_inode;
5044 } else if (!ext4_has_inline_data(inode)) {
5045 /* validate the block references in the inode */
5046 if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
5047 (S_ISLNK(inode->i_mode) &&
5048 !ext4_inode_is_fast_symlink(inode))) {

--- 11 unchanged lines hidden (view full) ---

5060 inode->i_fop = &ext4_file_operations;
5061 ext4_set_aops(inode);
5062 } else if (S_ISDIR(inode->i_mode)) {
5063 inode->i_op = &ext4_dir_inode_operations;
5064 inode->i_fop = &ext4_dir_operations;
5065 } else if (S_ISLNK(inode->i_mode)) {
5066 /* VFS does not allow setting these so must be corruption */
5067 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
5043 EXT4_ERROR_INODE(inode,
5044 "immutable or append flags not allowed on symlinks");
5068 ext4_error_inode(inode, function, line, 0,
5069 "iget: immutable or append flags "
5070 "not allowed on symlinks");
5045 ret = -EFSCORRUPTED;
5046 goto bad_inode;
5047 }
5048 if (ext4_encrypted_inode(inode)) {
5049 inode->i_op = &ext4_encrypted_symlink_inode_operations;
5050 ext4_set_aops(inode);
5051 } else if (ext4_inode_is_fast_symlink(inode)) {
5052 inode->i_link = (char *)ei->i_data;

--- 13 unchanged lines hidden (view full) ---

5066 old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
5067 else
5068 init_special_inode(inode, inode->i_mode,
5069 new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
5070 } else if (ino == EXT4_BOOT_LOADER_INO) {
5071 make_bad_inode(inode);
5072 } else {
5073 ret = -EFSCORRUPTED;
5071 ret = -EFSCORRUPTED;
5072 goto bad_inode;
5073 }
5074 if (ext4_encrypted_inode(inode)) {
5075 inode->i_op = &ext4_encrypted_symlink_inode_operations;
5076 ext4_set_aops(inode);
5077 } else if (ext4_inode_is_fast_symlink(inode)) {
5078 inode->i_link = (char *)ei->i_data;

--- 13 unchanged lines hidden (view full) ---

5092 old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
5093 else
5094 init_special_inode(inode, inode->i_mode,
5095 new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
5096 } else if (ino == EXT4_BOOT_LOADER_INO) {
5097 make_bad_inode(inode);
5098 } else {
5099 ret = -EFSCORRUPTED;
5074 EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode);
5100 ext4_error_inode(inode, function, line, 0,
5101 "iget: bogus i_mode (%o)", inode->i_mode);
5075 goto bad_inode;
5076 }
5077 brelse(iloc.bh);
5078
5079 unlock_new_inode(inode);
5080 return inode;
5081
5082bad_inode:
5083 brelse(iloc.bh);
5084 iget_failed(inode);
5085 return ERR_PTR(ret);
5086}
5087
5102 goto bad_inode;
5103 }
5104 brelse(iloc.bh);
5105
5106 unlock_new_inode(inode);
5107 return inode;
5108
5109bad_inode:
5110 brelse(iloc.bh);
5111 iget_failed(inode);
5112 return ERR_PTR(ret);
5113}
5114
5088struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino)
5089{
5090 if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
5091 return ERR_PTR(-EFSCORRUPTED);
5092 return ext4_iget(sb, ino);
5093}
5094
5095static int ext4_inode_blocks_set(handle_t *handle,
5096 struct ext4_inode *raw_inode,
5097 struct ext4_inode_info *ei)
5098{
5099 struct inode *inode = &(ei->vfs_inode);
5100 u64 i_blocks = inode->i_blocks;
5101 struct super_block *sb = inode->i_sb;
5102

--- 1194 unchanged lines hidden ---
5115static int ext4_inode_blocks_set(handle_t *handle,
5116 struct ext4_inode *raw_inode,
5117 struct ext4_inode_info *ei)
5118{
5119 struct inode *inode = &(ei->vfs_inode);
5120 u64 i_blocks = inode->i_blocks;
5121 struct super_block *sb = inode->i_sb;
5122

--- 1194 unchanged lines hidden ---