162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * fs/f2fs/inode.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2012 Samsung Electronics Co., Ltd. 662306a36Sopenharmony_ci * http://www.samsung.com/ 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci#include <linux/fs.h> 962306a36Sopenharmony_ci#include <linux/f2fs_fs.h> 1062306a36Sopenharmony_ci#include <linux/buffer_head.h> 1162306a36Sopenharmony_ci#include <linux/writeback.h> 1262306a36Sopenharmony_ci#include <linux/sched/mm.h> 1362306a36Sopenharmony_ci#include <linux/lz4.h> 1462306a36Sopenharmony_ci#include <linux/zstd.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "f2fs.h" 1762306a36Sopenharmony_ci#include "node.h" 1862306a36Sopenharmony_ci#include "segment.h" 1962306a36Sopenharmony_ci#include "xattr.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <trace/events/f2fs.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION 2462306a36Sopenharmony_ciextern const struct address_space_operations f2fs_compress_aops; 2562306a36Sopenharmony_ci#endif 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_civoid f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci if (is_inode_flag_set(inode, FI_NEW_INODE)) 3062306a36Sopenharmony_ci return; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci if (f2fs_inode_dirtied(inode, sync)) 3362306a36Sopenharmony_ci return; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci mark_inode_dirty_sync(inode); 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_civoid f2fs_set_inode_flags(struct inode *inode) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci unsigned int flags = F2FS_I(inode)->i_flags; 4162306a36Sopenharmony_ci unsigned int new_fl = 0; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci if (flags & F2FS_SYNC_FL) 4462306a36Sopenharmony_ci new_fl |= S_SYNC; 4562306a36Sopenharmony_ci if (flags & F2FS_APPEND_FL) 4662306a36Sopenharmony_ci new_fl |= S_APPEND; 4762306a36Sopenharmony_ci if (flags & F2FS_IMMUTABLE_FL) 4862306a36Sopenharmony_ci new_fl |= S_IMMUTABLE; 4962306a36Sopenharmony_ci if (flags & F2FS_NOATIME_FL) 5062306a36Sopenharmony_ci new_fl |= S_NOATIME; 5162306a36Sopenharmony_ci if (flags & F2FS_DIRSYNC_FL) 5262306a36Sopenharmony_ci new_fl |= S_DIRSYNC; 5362306a36Sopenharmony_ci if (file_is_encrypt(inode)) 5462306a36Sopenharmony_ci new_fl |= S_ENCRYPTED; 5562306a36Sopenharmony_ci if (file_is_verity(inode)) 5662306a36Sopenharmony_ci new_fl |= S_VERITY; 5762306a36Sopenharmony_ci if (flags & F2FS_CASEFOLD_FL) 5862306a36Sopenharmony_ci new_fl |= S_CASEFOLD; 5962306a36Sopenharmony_ci inode_set_flags(inode, new_fl, 6062306a36Sopenharmony_ci S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC| 6162306a36Sopenharmony_ci S_ENCRYPTED|S_VERITY|S_CASEFOLD); 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic void __get_inode_rdev(struct inode *inode, struct page *node_page) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci __le32 *addr = get_dnode_addr(inode, node_page); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || 6962306a36Sopenharmony_ci S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { 7062306a36Sopenharmony_ci if (addr[0]) 7162306a36Sopenharmony_ci inode->i_rdev = old_decode_dev(le32_to_cpu(addr[0])); 7262306a36Sopenharmony_ci else 7362306a36Sopenharmony_ci inode->i_rdev = new_decode_dev(le32_to_cpu(addr[1])); 7462306a36Sopenharmony_ci } 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic void __set_inode_rdev(struct inode *inode, struct page *node_page) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci __le32 *addr = get_dnode_addr(inode, node_page); 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { 8262306a36Sopenharmony_ci if (old_valid_dev(inode->i_rdev)) { 8362306a36Sopenharmony_ci addr[0] = cpu_to_le32(old_encode_dev(inode->i_rdev)); 8462306a36Sopenharmony_ci addr[1] = 0; 8562306a36Sopenharmony_ci } else { 8662306a36Sopenharmony_ci addr[0] = 0; 8762306a36Sopenharmony_ci addr[1] = cpu_to_le32(new_encode_dev(inode->i_rdev)); 8862306a36Sopenharmony_ci addr[2] = 0; 8962306a36Sopenharmony_ci } 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistatic void __recover_inline_status(struct inode *inode, struct page *ipage) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci void *inline_data = inline_data_addr(inode, ipage); 9662306a36Sopenharmony_ci __le32 *start = inline_data; 9762306a36Sopenharmony_ci __le32 *end = start + MAX_INLINE_DATA(inode) / sizeof(__le32); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci while (start < end) { 10062306a36Sopenharmony_ci if (*start++) { 10162306a36Sopenharmony_ci f2fs_wait_on_page_writeback(ipage, NODE, true, true); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci set_inode_flag(inode, FI_DATA_EXIST); 10462306a36Sopenharmony_ci set_raw_inline(inode, F2FS_INODE(ipage)); 10562306a36Sopenharmony_ci set_page_dirty(ipage); 10662306a36Sopenharmony_ci return; 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci return; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci struct f2fs_inode *ri = &F2FS_NODE(page)->i; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci if (!f2fs_sb_has_inode_chksum(sbi)) 11762306a36Sopenharmony_ci return false; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci if (!IS_INODE(page) || !(ri->i_inline & F2FS_EXTRA_ATTR)) 12062306a36Sopenharmony_ci return false; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci if (!F2FS_FITS_IN_INODE(ri, le16_to_cpu(ri->i_extra_isize), 12362306a36Sopenharmony_ci i_inode_checksum)) 12462306a36Sopenharmony_ci return false; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci return true; 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic __u32 f2fs_inode_chksum(struct f2fs_sb_info *sbi, struct page *page) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci struct f2fs_node *node = F2FS_NODE(page); 13262306a36Sopenharmony_ci struct f2fs_inode *ri = &node->i; 13362306a36Sopenharmony_ci __le32 ino = node->footer.ino; 13462306a36Sopenharmony_ci __le32 gen = ri->i_generation; 13562306a36Sopenharmony_ci __u32 chksum, chksum_seed; 13662306a36Sopenharmony_ci __u32 dummy_cs = 0; 13762306a36Sopenharmony_ci unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum); 13862306a36Sopenharmony_ci unsigned int cs_size = sizeof(dummy_cs); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci chksum = f2fs_chksum(sbi, sbi->s_chksum_seed, (__u8 *)&ino, 14162306a36Sopenharmony_ci sizeof(ino)); 14262306a36Sopenharmony_ci chksum_seed = f2fs_chksum(sbi, chksum, (__u8 *)&gen, sizeof(gen)); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci chksum = f2fs_chksum(sbi, chksum_seed, (__u8 *)ri, offset); 14562306a36Sopenharmony_ci chksum = f2fs_chksum(sbi, chksum, (__u8 *)&dummy_cs, cs_size); 14662306a36Sopenharmony_ci offset += cs_size; 14762306a36Sopenharmony_ci chksum = f2fs_chksum(sbi, chksum, (__u8 *)ri + offset, 14862306a36Sopenharmony_ci F2FS_BLKSIZE - offset); 14962306a36Sopenharmony_ci return chksum; 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cibool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci struct f2fs_inode *ri; 15562306a36Sopenharmony_ci __u32 provided, calculated; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci if (unlikely(is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN))) 15862306a36Sopenharmony_ci return true; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci#ifdef CONFIG_F2FS_CHECK_FS 16162306a36Sopenharmony_ci if (!f2fs_enable_inode_chksum(sbi, page)) 16262306a36Sopenharmony_ci#else 16362306a36Sopenharmony_ci if (!f2fs_enable_inode_chksum(sbi, page) || 16462306a36Sopenharmony_ci PageDirty(page) || PageWriteback(page)) 16562306a36Sopenharmony_ci#endif 16662306a36Sopenharmony_ci return true; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci ri = &F2FS_NODE(page)->i; 16962306a36Sopenharmony_ci provided = le32_to_cpu(ri->i_inode_checksum); 17062306a36Sopenharmony_ci calculated = f2fs_inode_chksum(sbi, page); 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci if (provided != calculated) 17362306a36Sopenharmony_ci f2fs_warn(sbi, "checksum invalid, nid = %lu, ino_of_node = %x, %x vs. %x", 17462306a36Sopenharmony_ci page->index, ino_of_node(page), provided, calculated); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci return provided == calculated; 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_civoid f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci struct f2fs_inode *ri = &F2FS_NODE(page)->i; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci if (!f2fs_enable_inode_chksum(sbi, page)) 18462306a36Sopenharmony_ci return; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci ri->i_inode_checksum = cpu_to_le32(f2fs_inode_chksum(sbi, page)); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistatic bool sanity_check_compress_inode(struct inode *inode, 19062306a36Sopenharmony_ci struct f2fs_inode *ri) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 19362306a36Sopenharmony_ci unsigned char clevel; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci if (ri->i_compress_algorithm >= COMPRESS_MAX) { 19662306a36Sopenharmony_ci f2fs_warn(sbi, 19762306a36Sopenharmony_ci "%s: inode (ino=%lx) has unsupported compress algorithm: %u, run fsck to fix", 19862306a36Sopenharmony_ci __func__, inode->i_ino, ri->i_compress_algorithm); 19962306a36Sopenharmony_ci return false; 20062306a36Sopenharmony_ci } 20162306a36Sopenharmony_ci if (le64_to_cpu(ri->i_compr_blocks) > 20262306a36Sopenharmony_ci SECTOR_TO_BLOCK(inode->i_blocks)) { 20362306a36Sopenharmony_ci f2fs_warn(sbi, 20462306a36Sopenharmony_ci "%s: inode (ino=%lx) has inconsistent i_compr_blocks:%llu, i_blocks:%llu, run fsck to fix", 20562306a36Sopenharmony_ci __func__, inode->i_ino, le64_to_cpu(ri->i_compr_blocks), 20662306a36Sopenharmony_ci SECTOR_TO_BLOCK(inode->i_blocks)); 20762306a36Sopenharmony_ci return false; 20862306a36Sopenharmony_ci } 20962306a36Sopenharmony_ci if (ri->i_log_cluster_size < MIN_COMPRESS_LOG_SIZE || 21062306a36Sopenharmony_ci ri->i_log_cluster_size > MAX_COMPRESS_LOG_SIZE) { 21162306a36Sopenharmony_ci f2fs_warn(sbi, 21262306a36Sopenharmony_ci "%s: inode (ino=%lx) has unsupported log cluster size: %u, run fsck to fix", 21362306a36Sopenharmony_ci __func__, inode->i_ino, ri->i_log_cluster_size); 21462306a36Sopenharmony_ci return false; 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci clevel = le16_to_cpu(ri->i_compress_flag) >> 21862306a36Sopenharmony_ci COMPRESS_LEVEL_OFFSET; 21962306a36Sopenharmony_ci switch (ri->i_compress_algorithm) { 22062306a36Sopenharmony_ci case COMPRESS_LZO: 22162306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_LZO 22262306a36Sopenharmony_ci if (clevel) 22362306a36Sopenharmony_ci goto err_level; 22462306a36Sopenharmony_ci#endif 22562306a36Sopenharmony_ci break; 22662306a36Sopenharmony_ci case COMPRESS_LZORLE: 22762306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_LZORLE 22862306a36Sopenharmony_ci if (clevel) 22962306a36Sopenharmony_ci goto err_level; 23062306a36Sopenharmony_ci#endif 23162306a36Sopenharmony_ci break; 23262306a36Sopenharmony_ci case COMPRESS_LZ4: 23362306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_LZ4 23462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_LZ4HC 23562306a36Sopenharmony_ci if (clevel && 23662306a36Sopenharmony_ci (clevel < LZ4HC_MIN_CLEVEL || clevel > LZ4HC_MAX_CLEVEL)) 23762306a36Sopenharmony_ci goto err_level; 23862306a36Sopenharmony_ci#else 23962306a36Sopenharmony_ci if (clevel) 24062306a36Sopenharmony_ci goto err_level; 24162306a36Sopenharmony_ci#endif 24262306a36Sopenharmony_ci#endif 24362306a36Sopenharmony_ci break; 24462306a36Sopenharmony_ci case COMPRESS_ZSTD: 24562306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_ZSTD 24662306a36Sopenharmony_ci if (clevel < zstd_min_clevel() || clevel > zstd_max_clevel()) 24762306a36Sopenharmony_ci goto err_level; 24862306a36Sopenharmony_ci#endif 24962306a36Sopenharmony_ci break; 25062306a36Sopenharmony_ci default: 25162306a36Sopenharmony_ci goto err_level; 25262306a36Sopenharmony_ci } 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci return true; 25562306a36Sopenharmony_cierr_level: 25662306a36Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has unsupported compress level: %u, run fsck to fix", 25762306a36Sopenharmony_ci __func__, inode->i_ino, clevel); 25862306a36Sopenharmony_ci return false; 25962306a36Sopenharmony_ci} 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistatic bool sanity_check_inode(struct inode *inode, struct page *node_page) 26262306a36Sopenharmony_ci{ 26362306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 26462306a36Sopenharmony_ci struct f2fs_inode_info *fi = F2FS_I(inode); 26562306a36Sopenharmony_ci struct f2fs_inode *ri = F2FS_INODE(node_page); 26662306a36Sopenharmony_ci unsigned long long iblocks; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci iblocks = le64_to_cpu(F2FS_INODE(node_page)->i_blocks); 26962306a36Sopenharmony_ci if (!iblocks) { 27062306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode i_blocks i_ino=%lx iblocks=%llu, run fsck to fix.", 27162306a36Sopenharmony_ci __func__, inode->i_ino, iblocks); 27262306a36Sopenharmony_ci return false; 27362306a36Sopenharmony_ci } 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci if (ino_of_node(node_page) != nid_of_node(node_page)) { 27662306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode footer i_ino=%lx, ino,nid: [%u, %u] run fsck to fix.", 27762306a36Sopenharmony_ci __func__, inode->i_ino, 27862306a36Sopenharmony_ci ino_of_node(node_page), nid_of_node(node_page)); 27962306a36Sopenharmony_ci return false; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci if (f2fs_has_extra_attr(inode)) { 28362306a36Sopenharmony_ci if (!f2fs_sb_has_extra_attr(sbi)) { 28462306a36Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) is with extra_attr, but extra_attr feature is off", 28562306a36Sopenharmony_ci __func__, inode->i_ino); 28662306a36Sopenharmony_ci return false; 28762306a36Sopenharmony_ci } 28862306a36Sopenharmony_ci if (fi->i_extra_isize > F2FS_TOTAL_EXTRA_ATTR_SIZE || 28962306a36Sopenharmony_ci fi->i_extra_isize < F2FS_MIN_EXTRA_ATTR_SIZE || 29062306a36Sopenharmony_ci fi->i_extra_isize % sizeof(__le32)) { 29162306a36Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_extra_isize: %d, max: %zu", 29262306a36Sopenharmony_ci __func__, inode->i_ino, fi->i_extra_isize, 29362306a36Sopenharmony_ci F2FS_TOTAL_EXTRA_ATTR_SIZE); 29462306a36Sopenharmony_ci return false; 29562306a36Sopenharmony_ci } 29662306a36Sopenharmony_ci if (f2fs_sb_has_flexible_inline_xattr(sbi) && 29762306a36Sopenharmony_ci f2fs_has_inline_xattr(inode) && 29862306a36Sopenharmony_ci (!fi->i_inline_xattr_size || 29962306a36Sopenharmony_ci fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE)) { 30062306a36Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, max: %zu", 30162306a36Sopenharmony_ci __func__, inode->i_ino, fi->i_inline_xattr_size, 30262306a36Sopenharmony_ci MAX_INLINE_XATTR_SIZE); 30362306a36Sopenharmony_ci return false; 30462306a36Sopenharmony_ci } 30562306a36Sopenharmony_ci if (f2fs_sb_has_compression(sbi) && 30662306a36Sopenharmony_ci fi->i_flags & F2FS_COMPR_FL && 30762306a36Sopenharmony_ci F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, 30862306a36Sopenharmony_ci i_compress_flag)) { 30962306a36Sopenharmony_ci if (!sanity_check_compress_inode(inode, ri)) 31062306a36Sopenharmony_ci return false; 31162306a36Sopenharmony_ci } 31262306a36Sopenharmony_ci } else if (f2fs_sb_has_flexible_inline_xattr(sbi)) { 31362306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode ino=%lx, run fsck to fix.", 31462306a36Sopenharmony_ci __func__, inode->i_ino); 31562306a36Sopenharmony_ci return false; 31662306a36Sopenharmony_ci } 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci if (!f2fs_sb_has_extra_attr(sbi)) { 31962306a36Sopenharmony_ci if (f2fs_sb_has_project_quota(sbi)) { 32062306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.", 32162306a36Sopenharmony_ci __func__, inode->i_ino, F2FS_FEATURE_PRJQUOTA); 32262306a36Sopenharmony_ci return false; 32362306a36Sopenharmony_ci } 32462306a36Sopenharmony_ci if (f2fs_sb_has_inode_chksum(sbi)) { 32562306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.", 32662306a36Sopenharmony_ci __func__, inode->i_ino, F2FS_FEATURE_INODE_CHKSUM); 32762306a36Sopenharmony_ci return false; 32862306a36Sopenharmony_ci } 32962306a36Sopenharmony_ci if (f2fs_sb_has_flexible_inline_xattr(sbi)) { 33062306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.", 33162306a36Sopenharmony_ci __func__, inode->i_ino, F2FS_FEATURE_FLEXIBLE_INLINE_XATTR); 33262306a36Sopenharmony_ci return false; 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci if (f2fs_sb_has_inode_crtime(sbi)) { 33562306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.", 33662306a36Sopenharmony_ci __func__, inode->i_ino, F2FS_FEATURE_INODE_CRTIME); 33762306a36Sopenharmony_ci return false; 33862306a36Sopenharmony_ci } 33962306a36Sopenharmony_ci if (f2fs_sb_has_compression(sbi)) { 34062306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode ino=%lx, wrong feature flag: %u, run fsck to fix.", 34162306a36Sopenharmony_ci __func__, inode->i_ino, F2FS_FEATURE_COMPRESSION); 34262306a36Sopenharmony_ci return false; 34362306a36Sopenharmony_ci } 34462306a36Sopenharmony_ci } 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci if (f2fs_sanity_check_inline_data(inode)) { 34762306a36Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix", 34862306a36Sopenharmony_ci __func__, inode->i_ino, inode->i_mode); 34962306a36Sopenharmony_ci return false; 35062306a36Sopenharmony_ci } 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci if (f2fs_has_inline_dentry(inode) && !S_ISDIR(inode->i_mode)) { 35362306a36Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_dentry, run fsck to fix", 35462306a36Sopenharmony_ci __func__, inode->i_ino, inode->i_mode); 35562306a36Sopenharmony_ci return false; 35662306a36Sopenharmony_ci } 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci if ((fi->i_flags & F2FS_CASEFOLD_FL) && !f2fs_sb_has_casefold(sbi)) { 35962306a36Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has casefold flag, but casefold feature is off", 36062306a36Sopenharmony_ci __func__, inode->i_ino); 36162306a36Sopenharmony_ci return false; 36262306a36Sopenharmony_ci } 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci return true; 36562306a36Sopenharmony_ci} 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_cistatic void init_idisk_time(struct inode *inode) 36862306a36Sopenharmony_ci{ 36962306a36Sopenharmony_ci struct f2fs_inode_info *fi = F2FS_I(inode); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci fi->i_disk_time[0] = inode->i_atime; 37262306a36Sopenharmony_ci fi->i_disk_time[1] = inode_get_ctime(inode); 37362306a36Sopenharmony_ci fi->i_disk_time[2] = inode->i_mtime; 37462306a36Sopenharmony_ci} 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cistatic int do_read_inode(struct inode *inode) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 37962306a36Sopenharmony_ci struct f2fs_inode_info *fi = F2FS_I(inode); 38062306a36Sopenharmony_ci struct page *node_page; 38162306a36Sopenharmony_ci struct f2fs_inode *ri; 38262306a36Sopenharmony_ci projid_t i_projid; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci /* Check if ino is within scope */ 38562306a36Sopenharmony_ci if (f2fs_check_nid_range(sbi, inode->i_ino)) 38662306a36Sopenharmony_ci return -EINVAL; 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci node_page = f2fs_get_node_page(sbi, inode->i_ino); 38962306a36Sopenharmony_ci if (IS_ERR(node_page)) 39062306a36Sopenharmony_ci return PTR_ERR(node_page); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci ri = F2FS_INODE(node_page); 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci inode->i_mode = le16_to_cpu(ri->i_mode); 39562306a36Sopenharmony_ci i_uid_write(inode, le32_to_cpu(ri->i_uid)); 39662306a36Sopenharmony_ci i_gid_write(inode, le32_to_cpu(ri->i_gid)); 39762306a36Sopenharmony_ci set_nlink(inode, le32_to_cpu(ri->i_links)); 39862306a36Sopenharmony_ci inode->i_size = le64_to_cpu(ri->i_size); 39962306a36Sopenharmony_ci inode->i_blocks = SECTOR_FROM_BLOCK(le64_to_cpu(ri->i_blocks) - 1); 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci inode->i_atime.tv_sec = le64_to_cpu(ri->i_atime); 40262306a36Sopenharmony_ci inode_set_ctime(inode, le64_to_cpu(ri->i_ctime), 40362306a36Sopenharmony_ci le32_to_cpu(ri->i_ctime_nsec)); 40462306a36Sopenharmony_ci inode->i_mtime.tv_sec = le64_to_cpu(ri->i_mtime); 40562306a36Sopenharmony_ci inode->i_atime.tv_nsec = le32_to_cpu(ri->i_atime_nsec); 40662306a36Sopenharmony_ci inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec); 40762306a36Sopenharmony_ci inode->i_generation = le32_to_cpu(ri->i_generation); 40862306a36Sopenharmony_ci if (S_ISDIR(inode->i_mode)) 40962306a36Sopenharmony_ci fi->i_current_depth = le32_to_cpu(ri->i_current_depth); 41062306a36Sopenharmony_ci else if (S_ISREG(inode->i_mode)) 41162306a36Sopenharmony_ci fi->i_gc_failures[GC_FAILURE_PIN] = 41262306a36Sopenharmony_ci le16_to_cpu(ri->i_gc_failures); 41362306a36Sopenharmony_ci fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid); 41462306a36Sopenharmony_ci fi->i_flags = le32_to_cpu(ri->i_flags); 41562306a36Sopenharmony_ci if (S_ISREG(inode->i_mode)) 41662306a36Sopenharmony_ci fi->i_flags &= ~F2FS_PROJINHERIT_FL; 41762306a36Sopenharmony_ci bitmap_zero(fi->flags, FI_MAX); 41862306a36Sopenharmony_ci fi->i_advise = ri->i_advise; 41962306a36Sopenharmony_ci fi->i_pino = le32_to_cpu(ri->i_pino); 42062306a36Sopenharmony_ci fi->i_dir_level = ri->i_dir_level; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci get_inline_info(inode, ri); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci fi->i_extra_isize = f2fs_has_extra_attr(inode) ? 42562306a36Sopenharmony_ci le16_to_cpu(ri->i_extra_isize) : 0; 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci if (f2fs_sb_has_flexible_inline_xattr(sbi)) { 42862306a36Sopenharmony_ci fi->i_inline_xattr_size = le16_to_cpu(ri->i_inline_xattr_size); 42962306a36Sopenharmony_ci } else if (f2fs_has_inline_xattr(inode) || 43062306a36Sopenharmony_ci f2fs_has_inline_dentry(inode)) { 43162306a36Sopenharmony_ci fi->i_inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS; 43262306a36Sopenharmony_ci } else { 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci /* 43562306a36Sopenharmony_ci * Previous inline data or directory always reserved 200 bytes 43662306a36Sopenharmony_ci * in inode layout, even if inline_xattr is disabled. In order 43762306a36Sopenharmony_ci * to keep inline_dentry's structure for backward compatibility, 43862306a36Sopenharmony_ci * we get the space back only from inline_data. 43962306a36Sopenharmony_ci */ 44062306a36Sopenharmony_ci fi->i_inline_xattr_size = 0; 44162306a36Sopenharmony_ci } 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci if (!sanity_check_inode(inode, node_page)) { 44462306a36Sopenharmony_ci f2fs_put_page(node_page, 1); 44562306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 44662306a36Sopenharmony_ci f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); 44762306a36Sopenharmony_ci return -EFSCORRUPTED; 44862306a36Sopenharmony_ci } 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci /* check data exist */ 45162306a36Sopenharmony_ci if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) 45262306a36Sopenharmony_ci __recover_inline_status(inode, node_page); 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci /* try to recover cold bit for non-dir inode */ 45562306a36Sopenharmony_ci if (!S_ISDIR(inode->i_mode) && !is_cold_node(node_page)) { 45662306a36Sopenharmony_ci f2fs_wait_on_page_writeback(node_page, NODE, true, true); 45762306a36Sopenharmony_ci set_cold_node(node_page, false); 45862306a36Sopenharmony_ci set_page_dirty(node_page); 45962306a36Sopenharmony_ci } 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci /* get rdev by using inline_info */ 46262306a36Sopenharmony_ci __get_inode_rdev(inode, node_page); 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci if (!f2fs_need_inode_block_update(sbi, inode->i_ino)) 46562306a36Sopenharmony_ci fi->last_disk_size = inode->i_size; 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci if (fi->i_flags & F2FS_PROJINHERIT_FL) 46862306a36Sopenharmony_ci set_inode_flag(inode, FI_PROJ_INHERIT); 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci if (f2fs_has_extra_attr(inode) && f2fs_sb_has_project_quota(sbi) && 47162306a36Sopenharmony_ci F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_projid)) 47262306a36Sopenharmony_ci i_projid = (projid_t)le32_to_cpu(ri->i_projid); 47362306a36Sopenharmony_ci else 47462306a36Sopenharmony_ci i_projid = F2FS_DEF_PROJID; 47562306a36Sopenharmony_ci fi->i_projid = make_kprojid(&init_user_ns, i_projid); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci if (f2fs_has_extra_attr(inode) && f2fs_sb_has_inode_crtime(sbi) && 47862306a36Sopenharmony_ci F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_crtime)) { 47962306a36Sopenharmony_ci fi->i_crtime.tv_sec = le64_to_cpu(ri->i_crtime); 48062306a36Sopenharmony_ci fi->i_crtime.tv_nsec = le32_to_cpu(ri->i_crtime_nsec); 48162306a36Sopenharmony_ci } 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci if (f2fs_has_extra_attr(inode) && f2fs_sb_has_compression(sbi) && 48462306a36Sopenharmony_ci (fi->i_flags & F2FS_COMPR_FL)) { 48562306a36Sopenharmony_ci if (F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, 48662306a36Sopenharmony_ci i_compress_flag)) { 48762306a36Sopenharmony_ci unsigned short compress_flag; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci atomic_set(&fi->i_compr_blocks, 49062306a36Sopenharmony_ci le64_to_cpu(ri->i_compr_blocks)); 49162306a36Sopenharmony_ci fi->i_compress_algorithm = ri->i_compress_algorithm; 49262306a36Sopenharmony_ci fi->i_log_cluster_size = ri->i_log_cluster_size; 49362306a36Sopenharmony_ci compress_flag = le16_to_cpu(ri->i_compress_flag); 49462306a36Sopenharmony_ci fi->i_compress_level = compress_flag >> 49562306a36Sopenharmony_ci COMPRESS_LEVEL_OFFSET; 49662306a36Sopenharmony_ci fi->i_compress_flag = compress_flag & 49762306a36Sopenharmony_ci GENMASK(COMPRESS_LEVEL_OFFSET - 1, 0); 49862306a36Sopenharmony_ci fi->i_cluster_size = BIT(fi->i_log_cluster_size); 49962306a36Sopenharmony_ci set_inode_flag(inode, FI_COMPRESSED_FILE); 50062306a36Sopenharmony_ci } 50162306a36Sopenharmony_ci } 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci init_idisk_time(inode); 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci /* Need all the flag bits */ 50662306a36Sopenharmony_ci f2fs_init_read_extent_tree(inode, node_page); 50762306a36Sopenharmony_ci f2fs_init_age_extent_tree(inode); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci if (!sanity_check_extent_cache(inode)) { 51062306a36Sopenharmony_ci f2fs_put_page(node_page, 1); 51162306a36Sopenharmony_ci f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); 51262306a36Sopenharmony_ci return -EFSCORRUPTED; 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci f2fs_put_page(node_page, 1); 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci stat_inc_inline_xattr(inode); 51862306a36Sopenharmony_ci stat_inc_inline_inode(inode); 51962306a36Sopenharmony_ci stat_inc_inline_dir(inode); 52062306a36Sopenharmony_ci stat_inc_compr_inode(inode); 52162306a36Sopenharmony_ci stat_add_compr_blocks(inode, atomic_read(&fi->i_compr_blocks)); 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci return 0; 52462306a36Sopenharmony_ci} 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_cistatic bool is_meta_ino(struct f2fs_sb_info *sbi, unsigned int ino) 52762306a36Sopenharmony_ci{ 52862306a36Sopenharmony_ci return ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi) || 52962306a36Sopenharmony_ci ino == F2FS_COMPRESS_INO(sbi); 53062306a36Sopenharmony_ci} 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_cistruct inode *f2fs_iget(struct super_block *sb, unsigned long ino) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_SB(sb); 53562306a36Sopenharmony_ci struct inode *inode; 53662306a36Sopenharmony_ci int ret = 0; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci inode = iget_locked(sb, ino); 53962306a36Sopenharmony_ci if (!inode) 54062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci if (!(inode->i_state & I_NEW)) { 54362306a36Sopenharmony_ci if (is_meta_ino(sbi, ino)) { 54462306a36Sopenharmony_ci f2fs_err(sbi, "inaccessible inode: %lu, run fsck to repair", ino); 54562306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 54662306a36Sopenharmony_ci ret = -EFSCORRUPTED; 54762306a36Sopenharmony_ci trace_f2fs_iget_exit(inode, ret); 54862306a36Sopenharmony_ci iput(inode); 54962306a36Sopenharmony_ci f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); 55062306a36Sopenharmony_ci return ERR_PTR(ret); 55162306a36Sopenharmony_ci } 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci trace_f2fs_iget(inode); 55462306a36Sopenharmony_ci return inode; 55562306a36Sopenharmony_ci } 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci if (is_meta_ino(sbi, ino)) 55862306a36Sopenharmony_ci goto make_now; 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci ret = do_read_inode(inode); 56162306a36Sopenharmony_ci if (ret) 56262306a36Sopenharmony_ci goto bad_inode; 56362306a36Sopenharmony_cimake_now: 56462306a36Sopenharmony_ci if (ino == F2FS_NODE_INO(sbi)) { 56562306a36Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_node_aops; 56662306a36Sopenharmony_ci mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 56762306a36Sopenharmony_ci } else if (ino == F2FS_META_INO(sbi)) { 56862306a36Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_meta_aops; 56962306a36Sopenharmony_ci mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 57062306a36Sopenharmony_ci } else if (ino == F2FS_COMPRESS_INO(sbi)) { 57162306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION 57262306a36Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_compress_aops; 57362306a36Sopenharmony_ci /* 57462306a36Sopenharmony_ci * generic_error_remove_page only truncates pages of regular 57562306a36Sopenharmony_ci * inode 57662306a36Sopenharmony_ci */ 57762306a36Sopenharmony_ci inode->i_mode |= S_IFREG; 57862306a36Sopenharmony_ci#endif 57962306a36Sopenharmony_ci mapping_set_gfp_mask(inode->i_mapping, 58062306a36Sopenharmony_ci GFP_NOFS | __GFP_HIGHMEM | __GFP_MOVABLE); 58162306a36Sopenharmony_ci } else if (S_ISREG(inode->i_mode)) { 58262306a36Sopenharmony_ci inode->i_op = &f2fs_file_inode_operations; 58362306a36Sopenharmony_ci inode->i_fop = &f2fs_file_operations; 58462306a36Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_dblock_aops; 58562306a36Sopenharmony_ci } else if (S_ISDIR(inode->i_mode)) { 58662306a36Sopenharmony_ci inode->i_op = &f2fs_dir_inode_operations; 58762306a36Sopenharmony_ci inode->i_fop = &f2fs_dir_operations; 58862306a36Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_dblock_aops; 58962306a36Sopenharmony_ci mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 59062306a36Sopenharmony_ci } else if (S_ISLNK(inode->i_mode)) { 59162306a36Sopenharmony_ci if (file_is_encrypt(inode)) 59262306a36Sopenharmony_ci inode->i_op = &f2fs_encrypted_symlink_inode_operations; 59362306a36Sopenharmony_ci else 59462306a36Sopenharmony_ci inode->i_op = &f2fs_symlink_inode_operations; 59562306a36Sopenharmony_ci inode_nohighmem(inode); 59662306a36Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_dblock_aops; 59762306a36Sopenharmony_ci } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || 59862306a36Sopenharmony_ci S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { 59962306a36Sopenharmony_ci inode->i_op = &f2fs_special_inode_operations; 60062306a36Sopenharmony_ci init_special_inode(inode, inode->i_mode, inode->i_rdev); 60162306a36Sopenharmony_ci } else { 60262306a36Sopenharmony_ci ret = -EIO; 60362306a36Sopenharmony_ci goto bad_inode; 60462306a36Sopenharmony_ci } 60562306a36Sopenharmony_ci f2fs_set_inode_flags(inode); 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci if (file_should_truncate(inode) && 60862306a36Sopenharmony_ci !is_sbi_flag_set(sbi, SBI_POR_DOING)) { 60962306a36Sopenharmony_ci ret = f2fs_truncate(inode); 61062306a36Sopenharmony_ci if (ret) 61162306a36Sopenharmony_ci goto bad_inode; 61262306a36Sopenharmony_ci file_dont_truncate(inode); 61362306a36Sopenharmony_ci } 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci unlock_new_inode(inode); 61662306a36Sopenharmony_ci trace_f2fs_iget(inode); 61762306a36Sopenharmony_ci return inode; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_cibad_inode: 62062306a36Sopenharmony_ci f2fs_inode_synced(inode); 62162306a36Sopenharmony_ci iget_failed(inode); 62262306a36Sopenharmony_ci trace_f2fs_iget_exit(inode, ret); 62362306a36Sopenharmony_ci return ERR_PTR(ret); 62462306a36Sopenharmony_ci} 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_cistruct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino) 62762306a36Sopenharmony_ci{ 62862306a36Sopenharmony_ci struct inode *inode; 62962306a36Sopenharmony_ciretry: 63062306a36Sopenharmony_ci inode = f2fs_iget(sb, ino); 63162306a36Sopenharmony_ci if (IS_ERR(inode)) { 63262306a36Sopenharmony_ci if (PTR_ERR(inode) == -ENOMEM) { 63362306a36Sopenharmony_ci memalloc_retry_wait(GFP_NOFS); 63462306a36Sopenharmony_ci goto retry; 63562306a36Sopenharmony_ci } 63662306a36Sopenharmony_ci } 63762306a36Sopenharmony_ci return inode; 63862306a36Sopenharmony_ci} 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_civoid f2fs_update_inode(struct inode *inode, struct page *node_page) 64162306a36Sopenharmony_ci{ 64262306a36Sopenharmony_ci struct f2fs_inode *ri; 64362306a36Sopenharmony_ci struct extent_tree *et = F2FS_I(inode)->extent_tree[EX_READ]; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci f2fs_wait_on_page_writeback(node_page, NODE, true, true); 64662306a36Sopenharmony_ci set_page_dirty(node_page); 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci f2fs_inode_synced(inode); 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci ri = F2FS_INODE(node_page); 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci ri->i_mode = cpu_to_le16(inode->i_mode); 65362306a36Sopenharmony_ci ri->i_advise = F2FS_I(inode)->i_advise; 65462306a36Sopenharmony_ci ri->i_uid = cpu_to_le32(i_uid_read(inode)); 65562306a36Sopenharmony_ci ri->i_gid = cpu_to_le32(i_gid_read(inode)); 65662306a36Sopenharmony_ci ri->i_links = cpu_to_le32(inode->i_nlink); 65762306a36Sopenharmony_ci ri->i_blocks = cpu_to_le64(SECTOR_TO_BLOCK(inode->i_blocks) + 1); 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci if (!f2fs_is_atomic_file(inode) || 66062306a36Sopenharmony_ci is_inode_flag_set(inode, FI_ATOMIC_COMMITTED)) 66162306a36Sopenharmony_ci ri->i_size = cpu_to_le64(i_size_read(inode)); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci if (et) { 66462306a36Sopenharmony_ci read_lock(&et->lock); 66562306a36Sopenharmony_ci set_raw_read_extent(&et->largest, &ri->i_ext); 66662306a36Sopenharmony_ci read_unlock(&et->lock); 66762306a36Sopenharmony_ci } else { 66862306a36Sopenharmony_ci memset(&ri->i_ext, 0, sizeof(ri->i_ext)); 66962306a36Sopenharmony_ci } 67062306a36Sopenharmony_ci set_raw_inline(inode, ri); 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci ri->i_atime = cpu_to_le64(inode->i_atime.tv_sec); 67362306a36Sopenharmony_ci ri->i_ctime = cpu_to_le64(inode_get_ctime(inode).tv_sec); 67462306a36Sopenharmony_ci ri->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec); 67562306a36Sopenharmony_ci ri->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); 67662306a36Sopenharmony_ci ri->i_ctime_nsec = cpu_to_le32(inode_get_ctime(inode).tv_nsec); 67762306a36Sopenharmony_ci ri->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); 67862306a36Sopenharmony_ci if (S_ISDIR(inode->i_mode)) 67962306a36Sopenharmony_ci ri->i_current_depth = 68062306a36Sopenharmony_ci cpu_to_le32(F2FS_I(inode)->i_current_depth); 68162306a36Sopenharmony_ci else if (S_ISREG(inode->i_mode)) 68262306a36Sopenharmony_ci ri->i_gc_failures = 68362306a36Sopenharmony_ci cpu_to_le16(F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN]); 68462306a36Sopenharmony_ci ri->i_xattr_nid = cpu_to_le32(F2FS_I(inode)->i_xattr_nid); 68562306a36Sopenharmony_ci ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); 68662306a36Sopenharmony_ci ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); 68762306a36Sopenharmony_ci ri->i_generation = cpu_to_le32(inode->i_generation); 68862306a36Sopenharmony_ci ri->i_dir_level = F2FS_I(inode)->i_dir_level; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci if (f2fs_has_extra_attr(inode)) { 69162306a36Sopenharmony_ci ri->i_extra_isize = cpu_to_le16(F2FS_I(inode)->i_extra_isize); 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci if (f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(inode))) 69462306a36Sopenharmony_ci ri->i_inline_xattr_size = 69562306a36Sopenharmony_ci cpu_to_le16(F2FS_I(inode)->i_inline_xattr_size); 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci if (f2fs_sb_has_project_quota(F2FS_I_SB(inode)) && 69862306a36Sopenharmony_ci F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize, 69962306a36Sopenharmony_ci i_projid)) { 70062306a36Sopenharmony_ci projid_t i_projid; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci i_projid = from_kprojid(&init_user_ns, 70362306a36Sopenharmony_ci F2FS_I(inode)->i_projid); 70462306a36Sopenharmony_ci ri->i_projid = cpu_to_le32(i_projid); 70562306a36Sopenharmony_ci } 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci if (f2fs_sb_has_inode_crtime(F2FS_I_SB(inode)) && 70862306a36Sopenharmony_ci F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize, 70962306a36Sopenharmony_ci i_crtime)) { 71062306a36Sopenharmony_ci ri->i_crtime = 71162306a36Sopenharmony_ci cpu_to_le64(F2FS_I(inode)->i_crtime.tv_sec); 71262306a36Sopenharmony_ci ri->i_crtime_nsec = 71362306a36Sopenharmony_ci cpu_to_le32(F2FS_I(inode)->i_crtime.tv_nsec); 71462306a36Sopenharmony_ci } 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci if (f2fs_sb_has_compression(F2FS_I_SB(inode)) && 71762306a36Sopenharmony_ci F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize, 71862306a36Sopenharmony_ci i_compress_flag)) { 71962306a36Sopenharmony_ci unsigned short compress_flag; 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci ri->i_compr_blocks = 72262306a36Sopenharmony_ci cpu_to_le64(atomic_read( 72362306a36Sopenharmony_ci &F2FS_I(inode)->i_compr_blocks)); 72462306a36Sopenharmony_ci ri->i_compress_algorithm = 72562306a36Sopenharmony_ci F2FS_I(inode)->i_compress_algorithm; 72662306a36Sopenharmony_ci compress_flag = F2FS_I(inode)->i_compress_flag | 72762306a36Sopenharmony_ci F2FS_I(inode)->i_compress_level << 72862306a36Sopenharmony_ci COMPRESS_LEVEL_OFFSET; 72962306a36Sopenharmony_ci ri->i_compress_flag = cpu_to_le16(compress_flag); 73062306a36Sopenharmony_ci ri->i_log_cluster_size = 73162306a36Sopenharmony_ci F2FS_I(inode)->i_log_cluster_size; 73262306a36Sopenharmony_ci } 73362306a36Sopenharmony_ci } 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci __set_inode_rdev(inode, node_page); 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci /* deleted inode */ 73862306a36Sopenharmony_ci if (inode->i_nlink == 0) 73962306a36Sopenharmony_ci clear_page_private_inline(node_page); 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci init_idisk_time(inode); 74262306a36Sopenharmony_ci#ifdef CONFIG_F2FS_CHECK_FS 74362306a36Sopenharmony_ci f2fs_inode_chksum_set(F2FS_I_SB(inode), node_page); 74462306a36Sopenharmony_ci#endif 74562306a36Sopenharmony_ci} 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_civoid f2fs_update_inode_page(struct inode *inode) 74862306a36Sopenharmony_ci{ 74962306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 75062306a36Sopenharmony_ci struct page *node_page; 75162306a36Sopenharmony_ci int count = 0; 75262306a36Sopenharmony_ciretry: 75362306a36Sopenharmony_ci node_page = f2fs_get_node_page(sbi, inode->i_ino); 75462306a36Sopenharmony_ci if (IS_ERR(node_page)) { 75562306a36Sopenharmony_ci int err = PTR_ERR(node_page); 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci /* The node block was truncated. */ 75862306a36Sopenharmony_ci if (err == -ENOENT) 75962306a36Sopenharmony_ci return; 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci if (err == -ENOMEM || ++count <= DEFAULT_RETRY_IO_COUNT) 76262306a36Sopenharmony_ci goto retry; 76362306a36Sopenharmony_ci f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_UPDATE_INODE); 76462306a36Sopenharmony_ci return; 76562306a36Sopenharmony_ci } 76662306a36Sopenharmony_ci f2fs_update_inode(inode, node_page); 76762306a36Sopenharmony_ci f2fs_put_page(node_page, 1); 76862306a36Sopenharmony_ci} 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ciint f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) 77162306a36Sopenharmony_ci{ 77262306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci if (inode->i_ino == F2FS_NODE_INO(sbi) || 77562306a36Sopenharmony_ci inode->i_ino == F2FS_META_INO(sbi)) 77662306a36Sopenharmony_ci return 0; 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci /* 77962306a36Sopenharmony_ci * atime could be updated without dirtying f2fs inode in lazytime mode 78062306a36Sopenharmony_ci */ 78162306a36Sopenharmony_ci if (f2fs_is_time_consistent(inode) && 78262306a36Sopenharmony_ci !is_inode_flag_set(inode, FI_DIRTY_INODE)) 78362306a36Sopenharmony_ci return 0; 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci if (!f2fs_is_checkpoint_ready(sbi)) 78662306a36Sopenharmony_ci return -ENOSPC; 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci /* 78962306a36Sopenharmony_ci * We need to balance fs here to prevent from producing dirty node pages 79062306a36Sopenharmony_ci * during the urgent cleaning time when running out of free sections. 79162306a36Sopenharmony_ci */ 79262306a36Sopenharmony_ci f2fs_update_inode_page(inode); 79362306a36Sopenharmony_ci if (wbc && wbc->nr_to_write) 79462306a36Sopenharmony_ci f2fs_balance_fs(sbi, true); 79562306a36Sopenharmony_ci return 0; 79662306a36Sopenharmony_ci} 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci/* 79962306a36Sopenharmony_ci * Called at the last iput() if i_nlink is zero 80062306a36Sopenharmony_ci */ 80162306a36Sopenharmony_civoid f2fs_evict_inode(struct inode *inode) 80262306a36Sopenharmony_ci{ 80362306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 80462306a36Sopenharmony_ci struct f2fs_inode_info *fi = F2FS_I(inode); 80562306a36Sopenharmony_ci nid_t xnid = fi->i_xattr_nid; 80662306a36Sopenharmony_ci int err = 0; 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci f2fs_abort_atomic_write(inode, true); 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ci if (fi->cow_inode) { 81162306a36Sopenharmony_ci clear_inode_flag(fi->cow_inode, FI_COW_FILE); 81262306a36Sopenharmony_ci iput(fi->cow_inode); 81362306a36Sopenharmony_ci fi->cow_inode = NULL; 81462306a36Sopenharmony_ci } 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_ci trace_f2fs_evict_inode(inode); 81762306a36Sopenharmony_ci truncate_inode_pages_final(&inode->i_data); 81862306a36Sopenharmony_ci 81962306a36Sopenharmony_ci if ((inode->i_nlink || is_bad_inode(inode)) && 82062306a36Sopenharmony_ci test_opt(sbi, COMPRESS_CACHE) && f2fs_compressed_file(inode)) 82162306a36Sopenharmony_ci f2fs_invalidate_compress_pages(sbi, inode->i_ino); 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_ci if (inode->i_ino == F2FS_NODE_INO(sbi) || 82462306a36Sopenharmony_ci inode->i_ino == F2FS_META_INO(sbi) || 82562306a36Sopenharmony_ci inode->i_ino == F2FS_COMPRESS_INO(sbi)) 82662306a36Sopenharmony_ci goto out_clear; 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci f2fs_bug_on(sbi, get_dirty_pages(inode)); 82962306a36Sopenharmony_ci f2fs_remove_dirty_inode(inode); 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci f2fs_destroy_extent_tree(inode); 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_ci if (inode->i_nlink || is_bad_inode(inode)) 83462306a36Sopenharmony_ci goto no_delete; 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci err = f2fs_dquot_initialize(inode); 83762306a36Sopenharmony_ci if (err) { 83862306a36Sopenharmony_ci err = 0; 83962306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); 84062306a36Sopenharmony_ci } 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci f2fs_remove_ino_entry(sbi, inode->i_ino, APPEND_INO); 84362306a36Sopenharmony_ci f2fs_remove_ino_entry(sbi, inode->i_ino, UPDATE_INO); 84462306a36Sopenharmony_ci f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO); 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING)) 84762306a36Sopenharmony_ci sb_start_intwrite(inode->i_sb); 84862306a36Sopenharmony_ci set_inode_flag(inode, FI_NO_ALLOC); 84962306a36Sopenharmony_ci i_size_write(inode, 0); 85062306a36Sopenharmony_ciretry: 85162306a36Sopenharmony_ci if (F2FS_HAS_BLOCKS(inode)) 85262306a36Sopenharmony_ci err = f2fs_truncate(inode); 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci if (time_to_inject(sbi, FAULT_EVICT_INODE)) 85562306a36Sopenharmony_ci err = -EIO; 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci if (!err) { 85862306a36Sopenharmony_ci f2fs_lock_op(sbi); 85962306a36Sopenharmony_ci err = f2fs_remove_inode_page(inode); 86062306a36Sopenharmony_ci f2fs_unlock_op(sbi); 86162306a36Sopenharmony_ci if (err == -ENOENT) { 86262306a36Sopenharmony_ci err = 0; 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci /* 86562306a36Sopenharmony_ci * in fuzzed image, another node may has the same 86662306a36Sopenharmony_ci * block address as inode's, if it was truncated 86762306a36Sopenharmony_ci * previously, truncation of inode node will fail. 86862306a36Sopenharmony_ci */ 86962306a36Sopenharmony_ci if (is_inode_flag_set(inode, FI_DIRTY_INODE)) { 87062306a36Sopenharmony_ci f2fs_warn(F2FS_I_SB(inode), 87162306a36Sopenharmony_ci "f2fs_evict_inode: inconsistent node id, ino:%lu", 87262306a36Sopenharmony_ci inode->i_ino); 87362306a36Sopenharmony_ci f2fs_inode_synced(inode); 87462306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 87562306a36Sopenharmony_ci } 87662306a36Sopenharmony_ci } 87762306a36Sopenharmony_ci } 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_ci /* give more chances, if ENOMEM case */ 88062306a36Sopenharmony_ci if (err == -ENOMEM) { 88162306a36Sopenharmony_ci err = 0; 88262306a36Sopenharmony_ci goto retry; 88362306a36Sopenharmony_ci } 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci if (err) { 88662306a36Sopenharmony_ci f2fs_update_inode_page(inode); 88762306a36Sopenharmony_ci if (dquot_initialize_needed(inode)) 88862306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); 88962306a36Sopenharmony_ci } 89062306a36Sopenharmony_ci if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING)) 89162306a36Sopenharmony_ci sb_end_intwrite(inode->i_sb); 89262306a36Sopenharmony_cino_delete: 89362306a36Sopenharmony_ci dquot_drop(inode); 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci stat_dec_inline_xattr(inode); 89662306a36Sopenharmony_ci stat_dec_inline_dir(inode); 89762306a36Sopenharmony_ci stat_dec_inline_inode(inode); 89862306a36Sopenharmony_ci stat_dec_compr_inode(inode); 89962306a36Sopenharmony_ci stat_sub_compr_blocks(inode, 90062306a36Sopenharmony_ci atomic_read(&fi->i_compr_blocks)); 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci if (likely(!f2fs_cp_error(sbi) && 90362306a36Sopenharmony_ci !is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 90462306a36Sopenharmony_ci f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE)); 90562306a36Sopenharmony_ci else 90662306a36Sopenharmony_ci f2fs_inode_synced(inode); 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci /* for the case f2fs_new_inode() was failed, .i_ino is zero, skip it */ 90962306a36Sopenharmony_ci if (inode->i_ino) 91062306a36Sopenharmony_ci invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, 91162306a36Sopenharmony_ci inode->i_ino); 91262306a36Sopenharmony_ci if (xnid) 91362306a36Sopenharmony_ci invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); 91462306a36Sopenharmony_ci if (inode->i_nlink) { 91562306a36Sopenharmony_ci if (is_inode_flag_set(inode, FI_APPEND_WRITE)) 91662306a36Sopenharmony_ci f2fs_add_ino_entry(sbi, inode->i_ino, APPEND_INO); 91762306a36Sopenharmony_ci if (is_inode_flag_set(inode, FI_UPDATE_WRITE)) 91862306a36Sopenharmony_ci f2fs_add_ino_entry(sbi, inode->i_ino, UPDATE_INO); 91962306a36Sopenharmony_ci } 92062306a36Sopenharmony_ci if (is_inode_flag_set(inode, FI_FREE_NID)) { 92162306a36Sopenharmony_ci f2fs_alloc_nid_failed(sbi, inode->i_ino); 92262306a36Sopenharmony_ci clear_inode_flag(inode, FI_FREE_NID); 92362306a36Sopenharmony_ci } else { 92462306a36Sopenharmony_ci /* 92562306a36Sopenharmony_ci * If xattr nid is corrupted, we can reach out error condition, 92662306a36Sopenharmony_ci * err & !f2fs_exist_written_data(sbi, inode->i_ino, ORPHAN_INO)). 92762306a36Sopenharmony_ci * In that case, f2fs_check_nid_range() is enough to give a clue. 92862306a36Sopenharmony_ci */ 92962306a36Sopenharmony_ci } 93062306a36Sopenharmony_ciout_clear: 93162306a36Sopenharmony_ci fscrypt_put_encryption_info(inode); 93262306a36Sopenharmony_ci fsverity_cleanup_inode(inode); 93362306a36Sopenharmony_ci clear_inode(inode); 93462306a36Sopenharmony_ci} 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci/* caller should call f2fs_lock_op() */ 93762306a36Sopenharmony_civoid f2fs_handle_failed_inode(struct inode *inode) 93862306a36Sopenharmony_ci{ 93962306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 94062306a36Sopenharmony_ci struct node_info ni; 94162306a36Sopenharmony_ci int err; 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci /* 94462306a36Sopenharmony_ci * clear nlink of inode in order to release resource of inode 94562306a36Sopenharmony_ci * immediately. 94662306a36Sopenharmony_ci */ 94762306a36Sopenharmony_ci clear_nlink(inode); 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci /* 95062306a36Sopenharmony_ci * we must call this to avoid inode being remained as dirty, resulting 95162306a36Sopenharmony_ci * in a panic when flushing dirty inodes in gdirty_list. 95262306a36Sopenharmony_ci */ 95362306a36Sopenharmony_ci f2fs_update_inode_page(inode); 95462306a36Sopenharmony_ci f2fs_inode_synced(inode); 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci /* don't make bad inode, since it becomes a regular file. */ 95762306a36Sopenharmony_ci unlock_new_inode(inode); 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci /* 96062306a36Sopenharmony_ci * Note: we should add inode to orphan list before f2fs_unlock_op() 96162306a36Sopenharmony_ci * so we can prevent losing this orphan when encoutering checkpoint 96262306a36Sopenharmony_ci * and following suddenly power-off. 96362306a36Sopenharmony_ci */ 96462306a36Sopenharmony_ci err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false); 96562306a36Sopenharmony_ci if (err) { 96662306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 96762306a36Sopenharmony_ci set_inode_flag(inode, FI_FREE_NID); 96862306a36Sopenharmony_ci f2fs_warn(sbi, "May loss orphan inode, run fsck to fix."); 96962306a36Sopenharmony_ci goto out; 97062306a36Sopenharmony_ci } 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci if (ni.blk_addr != NULL_ADDR) { 97362306a36Sopenharmony_ci err = f2fs_acquire_orphan_inode(sbi); 97462306a36Sopenharmony_ci if (err) { 97562306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 97662306a36Sopenharmony_ci f2fs_warn(sbi, "Too many orphan inodes, run fsck to fix."); 97762306a36Sopenharmony_ci } else { 97862306a36Sopenharmony_ci f2fs_add_orphan_inode(inode); 97962306a36Sopenharmony_ci } 98062306a36Sopenharmony_ci f2fs_alloc_nid_done(sbi, inode->i_ino); 98162306a36Sopenharmony_ci } else { 98262306a36Sopenharmony_ci set_inode_flag(inode, FI_FREE_NID); 98362306a36Sopenharmony_ci } 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ciout: 98662306a36Sopenharmony_ci f2fs_unlock_op(sbi); 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci /* iput will drop the inode object */ 98962306a36Sopenharmony_ci iput(inode); 99062306a36Sopenharmony_ci} 991