18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * fs/f2fs/inode.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2012 Samsung Electronics Co., Ltd. 68c2ecf20Sopenharmony_ci * http://www.samsung.com/ 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci#include <linux/fs.h> 98c2ecf20Sopenharmony_ci#include <linux/f2fs_fs.h> 108c2ecf20Sopenharmony_ci#include <linux/buffer_head.h> 118c2ecf20Sopenharmony_ci#include <linux/backing-dev.h> 128c2ecf20Sopenharmony_ci#include <linux/writeback.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include "f2fs.h" 158c2ecf20Sopenharmony_ci#include "node.h" 168c2ecf20Sopenharmony_ci#include "segment.h" 178c2ecf20Sopenharmony_ci#include "xattr.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#include <trace/events/f2fs.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_civoid f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci if (is_inode_flag_set(inode, FI_NEW_INODE)) 248c2ecf20Sopenharmony_ci return; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci if (f2fs_readonly(F2FS_I_SB(inode)->sb)) 278c2ecf20Sopenharmony_ci return; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci if (f2fs_inode_dirtied(inode, sync)) 308c2ecf20Sopenharmony_ci return; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci mark_inode_dirty_sync(inode); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_civoid f2fs_set_inode_flags(struct inode *inode) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci unsigned int flags = F2FS_I(inode)->i_flags; 388c2ecf20Sopenharmony_ci unsigned int new_fl = 0; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci if (flags & F2FS_SYNC_FL) 418c2ecf20Sopenharmony_ci new_fl |= S_SYNC; 428c2ecf20Sopenharmony_ci if (flags & F2FS_APPEND_FL) 438c2ecf20Sopenharmony_ci new_fl |= S_APPEND; 448c2ecf20Sopenharmony_ci if (flags & F2FS_IMMUTABLE_FL) 458c2ecf20Sopenharmony_ci new_fl |= S_IMMUTABLE; 468c2ecf20Sopenharmony_ci if (flags & F2FS_NOATIME_FL) 478c2ecf20Sopenharmony_ci new_fl |= S_NOATIME; 488c2ecf20Sopenharmony_ci if (flags & F2FS_DIRSYNC_FL) 498c2ecf20Sopenharmony_ci new_fl |= S_DIRSYNC; 508c2ecf20Sopenharmony_ci if (file_is_encrypt(inode)) 518c2ecf20Sopenharmony_ci new_fl |= S_ENCRYPTED; 528c2ecf20Sopenharmony_ci if (file_is_verity(inode)) 538c2ecf20Sopenharmony_ci new_fl |= S_VERITY; 548c2ecf20Sopenharmony_ci if (flags & F2FS_CASEFOLD_FL) 558c2ecf20Sopenharmony_ci new_fl |= S_CASEFOLD; 568c2ecf20Sopenharmony_ci inode_set_flags(inode, new_fl, 578c2ecf20Sopenharmony_ci S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC| 588c2ecf20Sopenharmony_ci S_ENCRYPTED|S_VERITY|S_CASEFOLD); 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci int extra_size = get_extra_isize(inode); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || 668c2ecf20Sopenharmony_ci S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { 678c2ecf20Sopenharmony_ci if (ri->i_addr[extra_size]) 688c2ecf20Sopenharmony_ci inode->i_rdev = old_decode_dev( 698c2ecf20Sopenharmony_ci le32_to_cpu(ri->i_addr[extra_size])); 708c2ecf20Sopenharmony_ci else 718c2ecf20Sopenharmony_ci inode->i_rdev = new_decode_dev( 728c2ecf20Sopenharmony_ci le32_to_cpu(ri->i_addr[extra_size + 1])); 738c2ecf20Sopenharmony_ci } 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic int __written_first_block(struct f2fs_sb_info *sbi, 778c2ecf20Sopenharmony_ci struct f2fs_inode *ri) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci if (!__is_valid_data_blkaddr(addr)) 828c2ecf20Sopenharmony_ci return 1; 838c2ecf20Sopenharmony_ci if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC_ENHANCE)) 848c2ecf20Sopenharmony_ci return -EFSCORRUPTED; 858c2ecf20Sopenharmony_ci return 0; 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci int extra_size = get_extra_isize(inode); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { 938c2ecf20Sopenharmony_ci if (old_valid_dev(inode->i_rdev)) { 948c2ecf20Sopenharmony_ci ri->i_addr[extra_size] = 958c2ecf20Sopenharmony_ci cpu_to_le32(old_encode_dev(inode->i_rdev)); 968c2ecf20Sopenharmony_ci ri->i_addr[extra_size + 1] = 0; 978c2ecf20Sopenharmony_ci } else { 988c2ecf20Sopenharmony_ci ri->i_addr[extra_size] = 0; 998c2ecf20Sopenharmony_ci ri->i_addr[extra_size + 1] = 1008c2ecf20Sopenharmony_ci cpu_to_le32(new_encode_dev(inode->i_rdev)); 1018c2ecf20Sopenharmony_ci ri->i_addr[extra_size + 2] = 0; 1028c2ecf20Sopenharmony_ci } 1038c2ecf20Sopenharmony_ci } 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic void __recover_inline_status(struct inode *inode, struct page *ipage) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci void *inline_data = inline_data_addr(inode, ipage); 1098c2ecf20Sopenharmony_ci __le32 *start = inline_data; 1108c2ecf20Sopenharmony_ci __le32 *end = start + MAX_INLINE_DATA(inode) / sizeof(__le32); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci while (start < end) { 1138c2ecf20Sopenharmony_ci if (*start++) { 1148c2ecf20Sopenharmony_ci f2fs_wait_on_page_writeback(ipage, NODE, true, true); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci set_inode_flag(inode, FI_DATA_EXIST); 1178c2ecf20Sopenharmony_ci set_raw_inline(inode, F2FS_INODE(ipage)); 1188c2ecf20Sopenharmony_ci set_page_dirty(ipage); 1198c2ecf20Sopenharmony_ci return; 1208c2ecf20Sopenharmony_ci } 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci return; 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistatic bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci struct f2fs_inode *ri = &F2FS_NODE(page)->i; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci if (!f2fs_sb_has_inode_chksum(sbi)) 1308c2ecf20Sopenharmony_ci return false; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci if (!IS_INODE(page) || !(ri->i_inline & F2FS_EXTRA_ATTR)) 1338c2ecf20Sopenharmony_ci return false; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci if (!F2FS_FITS_IN_INODE(ri, le16_to_cpu(ri->i_extra_isize), 1368c2ecf20Sopenharmony_ci i_inode_checksum)) 1378c2ecf20Sopenharmony_ci return false; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci return true; 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic __u32 f2fs_inode_chksum(struct f2fs_sb_info *sbi, struct page *page) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci struct f2fs_node *node = F2FS_NODE(page); 1458c2ecf20Sopenharmony_ci struct f2fs_inode *ri = &node->i; 1468c2ecf20Sopenharmony_ci __le32 ino = node->footer.ino; 1478c2ecf20Sopenharmony_ci __le32 gen = ri->i_generation; 1488c2ecf20Sopenharmony_ci __u32 chksum, chksum_seed; 1498c2ecf20Sopenharmony_ci __u32 dummy_cs = 0; 1508c2ecf20Sopenharmony_ci unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum); 1518c2ecf20Sopenharmony_ci unsigned int cs_size = sizeof(dummy_cs); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci chksum = f2fs_chksum(sbi, sbi->s_chksum_seed, (__u8 *)&ino, 1548c2ecf20Sopenharmony_ci sizeof(ino)); 1558c2ecf20Sopenharmony_ci chksum_seed = f2fs_chksum(sbi, chksum, (__u8 *)&gen, sizeof(gen)); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci chksum = f2fs_chksum(sbi, chksum_seed, (__u8 *)ri, offset); 1588c2ecf20Sopenharmony_ci chksum = f2fs_chksum(sbi, chksum, (__u8 *)&dummy_cs, cs_size); 1598c2ecf20Sopenharmony_ci offset += cs_size; 1608c2ecf20Sopenharmony_ci chksum = f2fs_chksum(sbi, chksum, (__u8 *)ri + offset, 1618c2ecf20Sopenharmony_ci F2FS_BLKSIZE - offset); 1628c2ecf20Sopenharmony_ci return chksum; 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cibool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci struct f2fs_inode *ri; 1688c2ecf20Sopenharmony_ci __u32 provided, calculated; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci if (unlikely(is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN))) 1718c2ecf20Sopenharmony_ci return true; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_CHECK_FS 1748c2ecf20Sopenharmony_ci if (!f2fs_enable_inode_chksum(sbi, page)) 1758c2ecf20Sopenharmony_ci#else 1768c2ecf20Sopenharmony_ci if (!f2fs_enable_inode_chksum(sbi, page) || 1778c2ecf20Sopenharmony_ci PageDirty(page) || PageWriteback(page)) 1788c2ecf20Sopenharmony_ci#endif 1798c2ecf20Sopenharmony_ci return true; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci ri = &F2FS_NODE(page)->i; 1828c2ecf20Sopenharmony_ci provided = le32_to_cpu(ri->i_inode_checksum); 1838c2ecf20Sopenharmony_ci calculated = f2fs_inode_chksum(sbi, page); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci if (provided != calculated) 1868c2ecf20Sopenharmony_ci f2fs_warn(sbi, "checksum invalid, nid = %lu, ino_of_node = %x, %x vs. %x", 1878c2ecf20Sopenharmony_ci page->index, ino_of_node(page), provided, calculated); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci return provided == calculated; 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_civoid f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci struct f2fs_inode *ri = &F2FS_NODE(page)->i; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci if (!f2fs_enable_inode_chksum(sbi, page)) 1978c2ecf20Sopenharmony_ci return; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci ri->i_inode_checksum = cpu_to_le32(f2fs_inode_chksum(sbi, page)); 2008c2ecf20Sopenharmony_ci} 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic bool sanity_check_inode(struct inode *inode, struct page *node_page) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 2058c2ecf20Sopenharmony_ci struct f2fs_inode_info *fi = F2FS_I(inode); 2068c2ecf20Sopenharmony_ci struct f2fs_inode *ri = F2FS_INODE(node_page); 2078c2ecf20Sopenharmony_ci unsigned long long iblocks; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci iblocks = le64_to_cpu(F2FS_INODE(node_page)->i_blocks); 2108c2ecf20Sopenharmony_ci if (!iblocks) { 2118c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2128c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode i_blocks i_ino=%lx iblocks=%llu, run fsck to fix.", 2138c2ecf20Sopenharmony_ci __func__, inode->i_ino, iblocks); 2148c2ecf20Sopenharmony_ci return false; 2158c2ecf20Sopenharmony_ci } 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci if (ino_of_node(node_page) != nid_of_node(node_page)) { 2188c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2198c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode footer i_ino=%lx, ino,nid: [%u, %u] run fsck to fix.", 2208c2ecf20Sopenharmony_ci __func__, inode->i_ino, 2218c2ecf20Sopenharmony_ci ino_of_node(node_page), nid_of_node(node_page)); 2228c2ecf20Sopenharmony_ci return false; 2238c2ecf20Sopenharmony_ci } 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci if (f2fs_sb_has_flexible_inline_xattr(sbi) 2268c2ecf20Sopenharmony_ci && !f2fs_has_extra_attr(inode)) { 2278c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2288c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted inode ino=%lx, run fsck to fix.", 2298c2ecf20Sopenharmony_ci __func__, inode->i_ino); 2308c2ecf20Sopenharmony_ci return false; 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci if (f2fs_has_extra_attr(inode) && 2348c2ecf20Sopenharmony_ci !f2fs_sb_has_extra_attr(sbi)) { 2358c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2368c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) is with extra_attr, but extra_attr feature is off", 2378c2ecf20Sopenharmony_ci __func__, inode->i_ino); 2388c2ecf20Sopenharmony_ci return false; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci if (fi->i_extra_isize > F2FS_TOTAL_EXTRA_ATTR_SIZE || 2428c2ecf20Sopenharmony_ci fi->i_extra_isize % sizeof(__le32)) { 2438c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2448c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_extra_isize: %d, max: %zu", 2458c2ecf20Sopenharmony_ci __func__, inode->i_ino, fi->i_extra_isize, 2468c2ecf20Sopenharmony_ci F2FS_TOTAL_EXTRA_ATTR_SIZE); 2478c2ecf20Sopenharmony_ci return false; 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci if (f2fs_has_extra_attr(inode) && 2518c2ecf20Sopenharmony_ci f2fs_sb_has_flexible_inline_xattr(sbi) && 2528c2ecf20Sopenharmony_ci f2fs_has_inline_xattr(inode) && 2538c2ecf20Sopenharmony_ci (!fi->i_inline_xattr_size || 2548c2ecf20Sopenharmony_ci fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE)) { 2558c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2568c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, max: %zu", 2578c2ecf20Sopenharmony_ci __func__, inode->i_ino, fi->i_inline_xattr_size, 2588c2ecf20Sopenharmony_ci MAX_INLINE_XATTR_SIZE); 2598c2ecf20Sopenharmony_ci return false; 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci if (F2FS_I(inode)->extent_tree) { 2638c2ecf20Sopenharmony_ci struct extent_info *ei = &F2FS_I(inode)->extent_tree->largest; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci if (ei->len && 2668c2ecf20Sopenharmony_ci (!f2fs_is_valid_blkaddr(sbi, ei->blk, 2678c2ecf20Sopenharmony_ci DATA_GENERIC_ENHANCE) || 2688c2ecf20Sopenharmony_ci !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1, 2698c2ecf20Sopenharmony_ci DATA_GENERIC_ENHANCE))) { 2708c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2718c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] is incorrect, run fsck to fix", 2728c2ecf20Sopenharmony_ci __func__, inode->i_ino, 2738c2ecf20Sopenharmony_ci ei->blk, ei->fofs, ei->len); 2748c2ecf20Sopenharmony_ci return false; 2758c2ecf20Sopenharmony_ci } 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci if (f2fs_sanity_check_inline_data(inode)) { 2798c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2808c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix", 2818c2ecf20Sopenharmony_ci __func__, inode->i_ino, inode->i_mode); 2828c2ecf20Sopenharmony_ci return false; 2838c2ecf20Sopenharmony_ci } 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci if (f2fs_has_inline_dentry(inode) && !S_ISDIR(inode->i_mode)) { 2868c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2878c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_dentry, run fsck to fix", 2888c2ecf20Sopenharmony_ci __func__, inode->i_ino, inode->i_mode); 2898c2ecf20Sopenharmony_ci return false; 2908c2ecf20Sopenharmony_ci } 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci if ((fi->i_flags & F2FS_CASEFOLD_FL) && !f2fs_sb_has_casefold(sbi)) { 2938c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 2948c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has casefold flag, but casefold feature is off", 2958c2ecf20Sopenharmony_ci __func__, inode->i_ino); 2968c2ecf20Sopenharmony_ci return false; 2978c2ecf20Sopenharmony_ci } 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci if (f2fs_has_extra_attr(inode) && f2fs_sb_has_compression(sbi) && 3008c2ecf20Sopenharmony_ci fi->i_flags & F2FS_COMPR_FL && 3018c2ecf20Sopenharmony_ci F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, 3028c2ecf20Sopenharmony_ci i_log_cluster_size)) { 3038c2ecf20Sopenharmony_ci if (ri->i_compress_algorithm >= COMPRESS_MAX) { 3048c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 3058c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has unsupported " 3068c2ecf20Sopenharmony_ci "compress algorithm: %u, run fsck to fix", 3078c2ecf20Sopenharmony_ci __func__, inode->i_ino, 3088c2ecf20Sopenharmony_ci ri->i_compress_algorithm); 3098c2ecf20Sopenharmony_ci return false; 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci if (le64_to_cpu(ri->i_compr_blocks) > 3128c2ecf20Sopenharmony_ci SECTOR_TO_BLOCK(inode->i_blocks)) { 3138c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 3148c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has inconsistent " 3158c2ecf20Sopenharmony_ci "i_compr_blocks:%llu, i_blocks:%llu, run fsck to fix", 3168c2ecf20Sopenharmony_ci __func__, inode->i_ino, 3178c2ecf20Sopenharmony_ci le64_to_cpu(ri->i_compr_blocks), 3188c2ecf20Sopenharmony_ci SECTOR_TO_BLOCK(inode->i_blocks)); 3198c2ecf20Sopenharmony_ci return false; 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci if (ri->i_log_cluster_size < MIN_COMPRESS_LOG_SIZE || 3228c2ecf20Sopenharmony_ci ri->i_log_cluster_size > MAX_COMPRESS_LOG_SIZE) { 3238c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 3248c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has unsupported " 3258c2ecf20Sopenharmony_ci "log cluster size: %u, run fsck to fix", 3268c2ecf20Sopenharmony_ci __func__, inode->i_ino, 3278c2ecf20Sopenharmony_ci ri->i_log_cluster_size); 3288c2ecf20Sopenharmony_ci return false; 3298c2ecf20Sopenharmony_ci } 3308c2ecf20Sopenharmony_ci } 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci if (fi->i_xattr_nid && f2fs_check_nid_range(sbi, fi->i_xattr_nid)) { 3338c2ecf20Sopenharmony_ci f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_xattr_nid: %u, run fsck to fix.", 3348c2ecf20Sopenharmony_ci __func__, inode->i_ino, fi->i_xattr_nid); 3358c2ecf20Sopenharmony_ci return false; 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci return true; 3398c2ecf20Sopenharmony_ci} 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_cistatic int do_read_inode(struct inode *inode) 3428c2ecf20Sopenharmony_ci{ 3438c2ecf20Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 3448c2ecf20Sopenharmony_ci struct f2fs_inode_info *fi = F2FS_I(inode); 3458c2ecf20Sopenharmony_ci struct page *node_page; 3468c2ecf20Sopenharmony_ci struct f2fs_inode *ri; 3478c2ecf20Sopenharmony_ci projid_t i_projid; 3488c2ecf20Sopenharmony_ci int err; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci /* Check if ino is within scope */ 3518c2ecf20Sopenharmony_ci if (f2fs_check_nid_range(sbi, inode->i_ino)) 3528c2ecf20Sopenharmony_ci return -EINVAL; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci node_page = f2fs_get_node_page(sbi, inode->i_ino); 3558c2ecf20Sopenharmony_ci if (IS_ERR(node_page)) 3568c2ecf20Sopenharmony_ci return PTR_ERR(node_page); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci ri = F2FS_INODE(node_page); 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci inode->i_mode = le16_to_cpu(ri->i_mode); 3618c2ecf20Sopenharmony_ci i_uid_write(inode, le32_to_cpu(ri->i_uid)); 3628c2ecf20Sopenharmony_ci i_gid_write(inode, le32_to_cpu(ri->i_gid)); 3638c2ecf20Sopenharmony_ci set_nlink(inode, le32_to_cpu(ri->i_links)); 3648c2ecf20Sopenharmony_ci inode->i_size = le64_to_cpu(ri->i_size); 3658c2ecf20Sopenharmony_ci inode->i_blocks = SECTOR_FROM_BLOCK(le64_to_cpu(ri->i_blocks) - 1); 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci inode->i_atime.tv_sec = le64_to_cpu(ri->i_atime); 3688c2ecf20Sopenharmony_ci inode->i_ctime.tv_sec = le64_to_cpu(ri->i_ctime); 3698c2ecf20Sopenharmony_ci inode->i_mtime.tv_sec = le64_to_cpu(ri->i_mtime); 3708c2ecf20Sopenharmony_ci inode->i_atime.tv_nsec = le32_to_cpu(ri->i_atime_nsec); 3718c2ecf20Sopenharmony_ci inode->i_ctime.tv_nsec = le32_to_cpu(ri->i_ctime_nsec); 3728c2ecf20Sopenharmony_ci inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec); 3738c2ecf20Sopenharmony_ci inode->i_generation = le32_to_cpu(ri->i_generation); 3748c2ecf20Sopenharmony_ci if (S_ISDIR(inode->i_mode)) 3758c2ecf20Sopenharmony_ci fi->i_current_depth = le32_to_cpu(ri->i_current_depth); 3768c2ecf20Sopenharmony_ci else if (S_ISREG(inode->i_mode)) 3778c2ecf20Sopenharmony_ci fi->i_gc_failures[GC_FAILURE_PIN] = 3788c2ecf20Sopenharmony_ci le16_to_cpu(ri->i_gc_failures); 3798c2ecf20Sopenharmony_ci fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid); 3808c2ecf20Sopenharmony_ci fi->i_flags = le32_to_cpu(ri->i_flags); 3818c2ecf20Sopenharmony_ci if (S_ISREG(inode->i_mode)) 3828c2ecf20Sopenharmony_ci fi->i_flags &= ~F2FS_PROJINHERIT_FL; 3838c2ecf20Sopenharmony_ci bitmap_zero(fi->flags, FI_MAX); 3848c2ecf20Sopenharmony_ci fi->i_advise = ri->i_advise; 3858c2ecf20Sopenharmony_ci fi->i_pino = le32_to_cpu(ri->i_pino); 3868c2ecf20Sopenharmony_ci fi->i_dir_level = ri->i_dir_level; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci f2fs_init_extent_tree(inode, node_page); 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci get_inline_info(inode, ri); 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci fi->i_extra_isize = f2fs_has_extra_attr(inode) ? 3938c2ecf20Sopenharmony_ci le16_to_cpu(ri->i_extra_isize) : 0; 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci if (f2fs_sb_has_flexible_inline_xattr(sbi)) { 3968c2ecf20Sopenharmony_ci fi->i_inline_xattr_size = le16_to_cpu(ri->i_inline_xattr_size); 3978c2ecf20Sopenharmony_ci } else if (f2fs_has_inline_xattr(inode) || 3988c2ecf20Sopenharmony_ci f2fs_has_inline_dentry(inode)) { 3998c2ecf20Sopenharmony_ci fi->i_inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS; 4008c2ecf20Sopenharmony_ci } else { 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci /* 4038c2ecf20Sopenharmony_ci * Previous inline data or directory always reserved 200 bytes 4048c2ecf20Sopenharmony_ci * in inode layout, even if inline_xattr is disabled. In order 4058c2ecf20Sopenharmony_ci * to keep inline_dentry's structure for backward compatibility, 4068c2ecf20Sopenharmony_ci * we get the space back only from inline_data. 4078c2ecf20Sopenharmony_ci */ 4088c2ecf20Sopenharmony_ci fi->i_inline_xattr_size = 0; 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci if (!sanity_check_inode(inode, node_page)) { 4128c2ecf20Sopenharmony_ci f2fs_put_page(node_page, 1); 4138c2ecf20Sopenharmony_ci return -EFSCORRUPTED; 4148c2ecf20Sopenharmony_ci } 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci /* check data exist */ 4178c2ecf20Sopenharmony_ci if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) 4188c2ecf20Sopenharmony_ci __recover_inline_status(inode, node_page); 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci /* try to recover cold bit for non-dir inode */ 4218c2ecf20Sopenharmony_ci if (!S_ISDIR(inode->i_mode) && !is_cold_node(node_page)) { 4228c2ecf20Sopenharmony_ci f2fs_wait_on_page_writeback(node_page, NODE, true, true); 4238c2ecf20Sopenharmony_ci set_cold_node(node_page, false); 4248c2ecf20Sopenharmony_ci set_page_dirty(node_page); 4258c2ecf20Sopenharmony_ci } 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci /* get rdev by using inline_info */ 4288c2ecf20Sopenharmony_ci __get_inode_rdev(inode, ri); 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci if (S_ISREG(inode->i_mode)) { 4318c2ecf20Sopenharmony_ci err = __written_first_block(sbi, ri); 4328c2ecf20Sopenharmony_ci if (err < 0) { 4338c2ecf20Sopenharmony_ci f2fs_put_page(node_page, 1); 4348c2ecf20Sopenharmony_ci return err; 4358c2ecf20Sopenharmony_ci } 4368c2ecf20Sopenharmony_ci if (!err) 4378c2ecf20Sopenharmony_ci set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); 4388c2ecf20Sopenharmony_ci } 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci if (!f2fs_need_inode_block_update(sbi, inode->i_ino)) 4418c2ecf20Sopenharmony_ci fi->last_disk_size = inode->i_size; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci if (fi->i_flags & F2FS_PROJINHERIT_FL) 4448c2ecf20Sopenharmony_ci set_inode_flag(inode, FI_PROJ_INHERIT); 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci if (f2fs_has_extra_attr(inode) && f2fs_sb_has_project_quota(sbi) && 4478c2ecf20Sopenharmony_ci F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_projid)) 4488c2ecf20Sopenharmony_ci i_projid = (projid_t)le32_to_cpu(ri->i_projid); 4498c2ecf20Sopenharmony_ci else 4508c2ecf20Sopenharmony_ci i_projid = F2FS_DEF_PROJID; 4518c2ecf20Sopenharmony_ci fi->i_projid = make_kprojid(&init_user_ns, i_projid); 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci if (f2fs_has_extra_attr(inode) && f2fs_sb_has_inode_crtime(sbi) && 4548c2ecf20Sopenharmony_ci F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_crtime)) { 4558c2ecf20Sopenharmony_ci fi->i_crtime.tv_sec = le64_to_cpu(ri->i_crtime); 4568c2ecf20Sopenharmony_ci fi->i_crtime.tv_nsec = le32_to_cpu(ri->i_crtime_nsec); 4578c2ecf20Sopenharmony_ci } 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci if (f2fs_has_extra_attr(inode) && f2fs_sb_has_compression(sbi) && 4608c2ecf20Sopenharmony_ci (fi->i_flags & F2FS_COMPR_FL)) { 4618c2ecf20Sopenharmony_ci if (F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, 4628c2ecf20Sopenharmony_ci i_log_cluster_size)) { 4638c2ecf20Sopenharmony_ci atomic_set(&fi->i_compr_blocks, 4648c2ecf20Sopenharmony_ci le64_to_cpu(ri->i_compr_blocks)); 4658c2ecf20Sopenharmony_ci fi->i_compress_algorithm = ri->i_compress_algorithm; 4668c2ecf20Sopenharmony_ci fi->i_log_cluster_size = ri->i_log_cluster_size; 4678c2ecf20Sopenharmony_ci fi->i_cluster_size = 1 << fi->i_log_cluster_size; 4688c2ecf20Sopenharmony_ci set_inode_flag(inode, FI_COMPRESSED_FILE); 4698c2ecf20Sopenharmony_ci } 4708c2ecf20Sopenharmony_ci } 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci F2FS_I(inode)->i_disk_time[0] = inode->i_atime; 4738c2ecf20Sopenharmony_ci F2FS_I(inode)->i_disk_time[1] = inode->i_ctime; 4748c2ecf20Sopenharmony_ci F2FS_I(inode)->i_disk_time[2] = inode->i_mtime; 4758c2ecf20Sopenharmony_ci F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime; 4768c2ecf20Sopenharmony_ci f2fs_put_page(node_page, 1); 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci stat_inc_inline_xattr(inode); 4798c2ecf20Sopenharmony_ci stat_inc_inline_inode(inode); 4808c2ecf20Sopenharmony_ci stat_inc_inline_dir(inode); 4818c2ecf20Sopenharmony_ci stat_inc_compr_inode(inode); 4828c2ecf20Sopenharmony_ci stat_add_compr_blocks(inode, atomic_read(&fi->i_compr_blocks)); 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci return 0; 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cistruct inode *f2fs_iget(struct super_block *sb, unsigned long ino) 4888c2ecf20Sopenharmony_ci{ 4898c2ecf20Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_SB(sb); 4908c2ecf20Sopenharmony_ci struct inode *inode; 4918c2ecf20Sopenharmony_ci int ret = 0; 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci inode = iget_locked(sb, ino); 4948c2ecf20Sopenharmony_ci if (!inode) 4958c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci if (!(inode->i_state & I_NEW)) { 4988c2ecf20Sopenharmony_ci trace_f2fs_iget(inode); 4998c2ecf20Sopenharmony_ci return inode; 5008c2ecf20Sopenharmony_ci } 5018c2ecf20Sopenharmony_ci if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi)) 5028c2ecf20Sopenharmony_ci goto make_now; 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci ret = do_read_inode(inode); 5058c2ecf20Sopenharmony_ci if (ret) 5068c2ecf20Sopenharmony_ci goto bad_inode; 5078c2ecf20Sopenharmony_cimake_now: 5088c2ecf20Sopenharmony_ci if (ino == F2FS_NODE_INO(sbi)) { 5098c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_node_aops; 5108c2ecf20Sopenharmony_ci mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 5118c2ecf20Sopenharmony_ci } else if (ino == F2FS_META_INO(sbi)) { 5128c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_meta_aops; 5138c2ecf20Sopenharmony_ci mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 5148c2ecf20Sopenharmony_ci } else if (S_ISREG(inode->i_mode)) { 5158c2ecf20Sopenharmony_ci inode->i_op = &f2fs_file_inode_operations; 5168c2ecf20Sopenharmony_ci inode->i_fop = &f2fs_file_operations; 5178c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_dblock_aops; 5188c2ecf20Sopenharmony_ci } else if (S_ISDIR(inode->i_mode)) { 5198c2ecf20Sopenharmony_ci inode->i_op = &f2fs_dir_inode_operations; 5208c2ecf20Sopenharmony_ci inode->i_fop = &f2fs_dir_operations; 5218c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_dblock_aops; 5228c2ecf20Sopenharmony_ci mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 5238c2ecf20Sopenharmony_ci } else if (S_ISLNK(inode->i_mode)) { 5248c2ecf20Sopenharmony_ci if (file_is_encrypt(inode)) 5258c2ecf20Sopenharmony_ci inode->i_op = &f2fs_encrypted_symlink_inode_operations; 5268c2ecf20Sopenharmony_ci else 5278c2ecf20Sopenharmony_ci inode->i_op = &f2fs_symlink_inode_operations; 5288c2ecf20Sopenharmony_ci inode_nohighmem(inode); 5298c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &f2fs_dblock_aops; 5308c2ecf20Sopenharmony_ci } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || 5318c2ecf20Sopenharmony_ci S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { 5328c2ecf20Sopenharmony_ci inode->i_op = &f2fs_special_inode_operations; 5338c2ecf20Sopenharmony_ci init_special_inode(inode, inode->i_mode, inode->i_rdev); 5348c2ecf20Sopenharmony_ci } else { 5358c2ecf20Sopenharmony_ci ret = -EIO; 5368c2ecf20Sopenharmony_ci goto bad_inode; 5378c2ecf20Sopenharmony_ci } 5388c2ecf20Sopenharmony_ci f2fs_set_inode_flags(inode); 5398c2ecf20Sopenharmony_ci unlock_new_inode(inode); 5408c2ecf20Sopenharmony_ci trace_f2fs_iget(inode); 5418c2ecf20Sopenharmony_ci return inode; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_cibad_inode: 5448c2ecf20Sopenharmony_ci f2fs_inode_synced(inode); 5458c2ecf20Sopenharmony_ci iget_failed(inode); 5468c2ecf20Sopenharmony_ci trace_f2fs_iget_exit(inode, ret); 5478c2ecf20Sopenharmony_ci return ERR_PTR(ret); 5488c2ecf20Sopenharmony_ci} 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_cistruct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino) 5518c2ecf20Sopenharmony_ci{ 5528c2ecf20Sopenharmony_ci struct inode *inode; 5538c2ecf20Sopenharmony_ciretry: 5548c2ecf20Sopenharmony_ci inode = f2fs_iget(sb, ino); 5558c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 5568c2ecf20Sopenharmony_ci if (PTR_ERR(inode) == -ENOMEM) { 5578c2ecf20Sopenharmony_ci congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT); 5588c2ecf20Sopenharmony_ci goto retry; 5598c2ecf20Sopenharmony_ci } 5608c2ecf20Sopenharmony_ci } 5618c2ecf20Sopenharmony_ci return inode; 5628c2ecf20Sopenharmony_ci} 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_civoid f2fs_update_inode(struct inode *inode, struct page *node_page) 5658c2ecf20Sopenharmony_ci{ 5668c2ecf20Sopenharmony_ci struct f2fs_inode *ri; 5678c2ecf20Sopenharmony_ci struct extent_tree *et = F2FS_I(inode)->extent_tree; 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci f2fs_wait_on_page_writeback(node_page, NODE, true, true); 5708c2ecf20Sopenharmony_ci set_page_dirty(node_page); 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci f2fs_inode_synced(inode); 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci ri = F2FS_INODE(node_page); 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci ri->i_mode = cpu_to_le16(inode->i_mode); 5778c2ecf20Sopenharmony_ci ri->i_advise = F2FS_I(inode)->i_advise; 5788c2ecf20Sopenharmony_ci ri->i_uid = cpu_to_le32(i_uid_read(inode)); 5798c2ecf20Sopenharmony_ci ri->i_gid = cpu_to_le32(i_gid_read(inode)); 5808c2ecf20Sopenharmony_ci ri->i_links = cpu_to_le32(inode->i_nlink); 5818c2ecf20Sopenharmony_ci ri->i_size = cpu_to_le64(i_size_read(inode)); 5828c2ecf20Sopenharmony_ci ri->i_blocks = cpu_to_le64(SECTOR_TO_BLOCK(inode->i_blocks) + 1); 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci if (et) { 5858c2ecf20Sopenharmony_ci read_lock(&et->lock); 5868c2ecf20Sopenharmony_ci set_raw_extent(&et->largest, &ri->i_ext); 5878c2ecf20Sopenharmony_ci read_unlock(&et->lock); 5888c2ecf20Sopenharmony_ci } else { 5898c2ecf20Sopenharmony_ci memset(&ri->i_ext, 0, sizeof(ri->i_ext)); 5908c2ecf20Sopenharmony_ci } 5918c2ecf20Sopenharmony_ci set_raw_inline(inode, ri); 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci ri->i_atime = cpu_to_le64(inode->i_atime.tv_sec); 5948c2ecf20Sopenharmony_ci ri->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); 5958c2ecf20Sopenharmony_ci ri->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec); 5968c2ecf20Sopenharmony_ci ri->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); 5978c2ecf20Sopenharmony_ci ri->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); 5988c2ecf20Sopenharmony_ci ri->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); 5998c2ecf20Sopenharmony_ci if (S_ISDIR(inode->i_mode)) 6008c2ecf20Sopenharmony_ci ri->i_current_depth = 6018c2ecf20Sopenharmony_ci cpu_to_le32(F2FS_I(inode)->i_current_depth); 6028c2ecf20Sopenharmony_ci else if (S_ISREG(inode->i_mode)) 6038c2ecf20Sopenharmony_ci ri->i_gc_failures = 6048c2ecf20Sopenharmony_ci cpu_to_le16(F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN]); 6058c2ecf20Sopenharmony_ci ri->i_xattr_nid = cpu_to_le32(F2FS_I(inode)->i_xattr_nid); 6068c2ecf20Sopenharmony_ci ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); 6078c2ecf20Sopenharmony_ci ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); 6088c2ecf20Sopenharmony_ci ri->i_generation = cpu_to_le32(inode->i_generation); 6098c2ecf20Sopenharmony_ci ri->i_dir_level = F2FS_I(inode)->i_dir_level; 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci if (f2fs_has_extra_attr(inode)) { 6128c2ecf20Sopenharmony_ci ri->i_extra_isize = cpu_to_le16(F2FS_I(inode)->i_extra_isize); 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci if (f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(inode))) 6158c2ecf20Sopenharmony_ci ri->i_inline_xattr_size = 6168c2ecf20Sopenharmony_ci cpu_to_le16(F2FS_I(inode)->i_inline_xattr_size); 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci if (f2fs_sb_has_project_quota(F2FS_I_SB(inode)) && 6198c2ecf20Sopenharmony_ci F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize, 6208c2ecf20Sopenharmony_ci i_projid)) { 6218c2ecf20Sopenharmony_ci projid_t i_projid; 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci i_projid = from_kprojid(&init_user_ns, 6248c2ecf20Sopenharmony_ci F2FS_I(inode)->i_projid); 6258c2ecf20Sopenharmony_ci ri->i_projid = cpu_to_le32(i_projid); 6268c2ecf20Sopenharmony_ci } 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci if (f2fs_sb_has_inode_crtime(F2FS_I_SB(inode)) && 6298c2ecf20Sopenharmony_ci F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize, 6308c2ecf20Sopenharmony_ci i_crtime)) { 6318c2ecf20Sopenharmony_ci ri->i_crtime = 6328c2ecf20Sopenharmony_ci cpu_to_le64(F2FS_I(inode)->i_crtime.tv_sec); 6338c2ecf20Sopenharmony_ci ri->i_crtime_nsec = 6348c2ecf20Sopenharmony_ci cpu_to_le32(F2FS_I(inode)->i_crtime.tv_nsec); 6358c2ecf20Sopenharmony_ci } 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci if (f2fs_sb_has_compression(F2FS_I_SB(inode)) && 6388c2ecf20Sopenharmony_ci F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize, 6398c2ecf20Sopenharmony_ci i_log_cluster_size)) { 6408c2ecf20Sopenharmony_ci ri->i_compr_blocks = 6418c2ecf20Sopenharmony_ci cpu_to_le64(atomic_read( 6428c2ecf20Sopenharmony_ci &F2FS_I(inode)->i_compr_blocks)); 6438c2ecf20Sopenharmony_ci ri->i_compress_algorithm = 6448c2ecf20Sopenharmony_ci F2FS_I(inode)->i_compress_algorithm; 6458c2ecf20Sopenharmony_ci ri->i_log_cluster_size = 6468c2ecf20Sopenharmony_ci F2FS_I(inode)->i_log_cluster_size; 6478c2ecf20Sopenharmony_ci } 6488c2ecf20Sopenharmony_ci } 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci __set_inode_rdev(inode, ri); 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci /* deleted inode */ 6538c2ecf20Sopenharmony_ci if (inode->i_nlink == 0) 6548c2ecf20Sopenharmony_ci clear_inline_node(node_page); 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci F2FS_I(inode)->i_disk_time[0] = inode->i_atime; 6578c2ecf20Sopenharmony_ci F2FS_I(inode)->i_disk_time[1] = inode->i_ctime; 6588c2ecf20Sopenharmony_ci F2FS_I(inode)->i_disk_time[2] = inode->i_mtime; 6598c2ecf20Sopenharmony_ci F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime; 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_CHECK_FS 6628c2ecf20Sopenharmony_ci f2fs_inode_chksum_set(F2FS_I_SB(inode), node_page); 6638c2ecf20Sopenharmony_ci#endif 6648c2ecf20Sopenharmony_ci} 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_civoid f2fs_update_inode_page(struct inode *inode) 6678c2ecf20Sopenharmony_ci{ 6688c2ecf20Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 6698c2ecf20Sopenharmony_ci struct page *node_page; 6708c2ecf20Sopenharmony_ciretry: 6718c2ecf20Sopenharmony_ci node_page = f2fs_get_node_page(sbi, inode->i_ino); 6728c2ecf20Sopenharmony_ci if (IS_ERR(node_page)) { 6738c2ecf20Sopenharmony_ci int err = PTR_ERR(node_page); 6748c2ecf20Sopenharmony_ci if (err == -ENOMEM) { 6758c2ecf20Sopenharmony_ci cond_resched(); 6768c2ecf20Sopenharmony_ci goto retry; 6778c2ecf20Sopenharmony_ci } else if (err != -ENOENT) { 6788c2ecf20Sopenharmony_ci f2fs_stop_checkpoint(sbi, false); 6798c2ecf20Sopenharmony_ci } 6808c2ecf20Sopenharmony_ci return; 6818c2ecf20Sopenharmony_ci } 6828c2ecf20Sopenharmony_ci f2fs_update_inode(inode, node_page); 6838c2ecf20Sopenharmony_ci f2fs_put_page(node_page, 1); 6848c2ecf20Sopenharmony_ci} 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_ciint f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) 6878c2ecf20Sopenharmony_ci{ 6888c2ecf20Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci if (inode->i_ino == F2FS_NODE_INO(sbi) || 6918c2ecf20Sopenharmony_ci inode->i_ino == F2FS_META_INO(sbi)) 6928c2ecf20Sopenharmony_ci return 0; 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci /* 6958c2ecf20Sopenharmony_ci * atime could be updated without dirtying f2fs inode in lazytime mode 6968c2ecf20Sopenharmony_ci */ 6978c2ecf20Sopenharmony_ci if (f2fs_is_time_consistent(inode) && 6988c2ecf20Sopenharmony_ci !is_inode_flag_set(inode, FI_DIRTY_INODE)) 6998c2ecf20Sopenharmony_ci return 0; 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci if (!f2fs_is_checkpoint_ready(sbi)) 7028c2ecf20Sopenharmony_ci return -ENOSPC; 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci /* 7058c2ecf20Sopenharmony_ci * We need to balance fs here to prevent from producing dirty node pages 7068c2ecf20Sopenharmony_ci * during the urgent cleaning time when runing out of free sections. 7078c2ecf20Sopenharmony_ci */ 7088c2ecf20Sopenharmony_ci f2fs_update_inode_page(inode); 7098c2ecf20Sopenharmony_ci if (wbc && wbc->nr_to_write) 7108c2ecf20Sopenharmony_ci f2fs_balance_fs(sbi, true); 7118c2ecf20Sopenharmony_ci return 0; 7128c2ecf20Sopenharmony_ci} 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci/* 7158c2ecf20Sopenharmony_ci * Called at the last iput() if i_nlink is zero 7168c2ecf20Sopenharmony_ci */ 7178c2ecf20Sopenharmony_civoid f2fs_evict_inode(struct inode *inode) 7188c2ecf20Sopenharmony_ci{ 7198c2ecf20Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 7208c2ecf20Sopenharmony_ci nid_t xnid = F2FS_I(inode)->i_xattr_nid; 7218c2ecf20Sopenharmony_ci int err = 0; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci /* some remained atomic pages should discarded */ 7248c2ecf20Sopenharmony_ci if (f2fs_is_atomic_file(inode)) 7258c2ecf20Sopenharmony_ci f2fs_drop_inmem_pages(inode); 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_ci trace_f2fs_evict_inode(inode); 7288c2ecf20Sopenharmony_ci truncate_inode_pages_final(&inode->i_data); 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_ci if (inode->i_ino == F2FS_NODE_INO(sbi) || 7318c2ecf20Sopenharmony_ci inode->i_ino == F2FS_META_INO(sbi)) 7328c2ecf20Sopenharmony_ci goto out_clear; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci f2fs_bug_on(sbi, get_dirty_pages(inode)); 7358c2ecf20Sopenharmony_ci f2fs_remove_dirty_inode(inode); 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_ci f2fs_destroy_extent_tree(inode); 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci if (inode->i_nlink || is_bad_inode(inode)) 7408c2ecf20Sopenharmony_ci goto no_delete; 7418c2ecf20Sopenharmony_ci 7428c2ecf20Sopenharmony_ci err = dquot_initialize(inode); 7438c2ecf20Sopenharmony_ci if (err) { 7448c2ecf20Sopenharmony_ci err = 0; 7458c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); 7468c2ecf20Sopenharmony_ci } 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci f2fs_remove_ino_entry(sbi, inode->i_ino, APPEND_INO); 7498c2ecf20Sopenharmony_ci f2fs_remove_ino_entry(sbi, inode->i_ino, UPDATE_INO); 7508c2ecf20Sopenharmony_ci f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO); 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci sb_start_intwrite(inode->i_sb); 7538c2ecf20Sopenharmony_ci set_inode_flag(inode, FI_NO_ALLOC); 7548c2ecf20Sopenharmony_ci i_size_write(inode, 0); 7558c2ecf20Sopenharmony_ciretry: 7568c2ecf20Sopenharmony_ci if (F2FS_HAS_BLOCKS(inode)) 7578c2ecf20Sopenharmony_ci err = f2fs_truncate(inode); 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci if (time_to_inject(sbi, FAULT_EVICT_INODE)) { 7608c2ecf20Sopenharmony_ci f2fs_show_injection_info(sbi, FAULT_EVICT_INODE); 7618c2ecf20Sopenharmony_ci err = -EIO; 7628c2ecf20Sopenharmony_ci } 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci if (!err) { 7658c2ecf20Sopenharmony_ci f2fs_lock_op(sbi); 7668c2ecf20Sopenharmony_ci err = f2fs_remove_inode_page(inode); 7678c2ecf20Sopenharmony_ci f2fs_unlock_op(sbi); 7688c2ecf20Sopenharmony_ci if (err == -ENOENT) { 7698c2ecf20Sopenharmony_ci err = 0; 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci /* 7728c2ecf20Sopenharmony_ci * in fuzzed image, another node may has the same 7738c2ecf20Sopenharmony_ci * block address as inode's, if it was truncated 7748c2ecf20Sopenharmony_ci * previously, truncation of inode node will fail. 7758c2ecf20Sopenharmony_ci */ 7768c2ecf20Sopenharmony_ci if (is_inode_flag_set(inode, FI_DIRTY_INODE)) { 7778c2ecf20Sopenharmony_ci f2fs_warn(F2FS_I_SB(inode), 7788c2ecf20Sopenharmony_ci "f2fs_evict_inode: inconsistent node id, ino:%lu", 7798c2ecf20Sopenharmony_ci inode->i_ino); 7808c2ecf20Sopenharmony_ci f2fs_inode_synced(inode); 7818c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 7828c2ecf20Sopenharmony_ci } 7838c2ecf20Sopenharmony_ci } 7848c2ecf20Sopenharmony_ci } 7858c2ecf20Sopenharmony_ci 7868c2ecf20Sopenharmony_ci /* give more chances, if ENOMEM case */ 7878c2ecf20Sopenharmony_ci if (err == -ENOMEM) { 7888c2ecf20Sopenharmony_ci err = 0; 7898c2ecf20Sopenharmony_ci goto retry; 7908c2ecf20Sopenharmony_ci } 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_ci if (err) { 7938c2ecf20Sopenharmony_ci f2fs_update_inode_page(inode); 7948c2ecf20Sopenharmony_ci if (dquot_initialize_needed(inode)) 7958c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); 7968c2ecf20Sopenharmony_ci } 7978c2ecf20Sopenharmony_ci sb_end_intwrite(inode->i_sb); 7988c2ecf20Sopenharmony_cino_delete: 7998c2ecf20Sopenharmony_ci dquot_drop(inode); 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci stat_dec_inline_xattr(inode); 8028c2ecf20Sopenharmony_ci stat_dec_inline_dir(inode); 8038c2ecf20Sopenharmony_ci stat_dec_inline_inode(inode); 8048c2ecf20Sopenharmony_ci stat_dec_compr_inode(inode); 8058c2ecf20Sopenharmony_ci stat_sub_compr_blocks(inode, 8068c2ecf20Sopenharmony_ci atomic_read(&F2FS_I(inode)->i_compr_blocks)); 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci if (likely(!f2fs_cp_error(sbi) && 8098c2ecf20Sopenharmony_ci !is_sbi_flag_set(sbi, SBI_CP_DISABLED))) 8108c2ecf20Sopenharmony_ci f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE)); 8118c2ecf20Sopenharmony_ci else 8128c2ecf20Sopenharmony_ci f2fs_inode_synced(inode); 8138c2ecf20Sopenharmony_ci 8148c2ecf20Sopenharmony_ci /* for the case f2fs_new_inode() was failed, .i_ino is zero, skip it */ 8158c2ecf20Sopenharmony_ci if (inode->i_ino) 8168c2ecf20Sopenharmony_ci invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, 8178c2ecf20Sopenharmony_ci inode->i_ino); 8188c2ecf20Sopenharmony_ci if (xnid) 8198c2ecf20Sopenharmony_ci invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); 8208c2ecf20Sopenharmony_ci if (inode->i_nlink) { 8218c2ecf20Sopenharmony_ci if (is_inode_flag_set(inode, FI_APPEND_WRITE)) 8228c2ecf20Sopenharmony_ci f2fs_add_ino_entry(sbi, inode->i_ino, APPEND_INO); 8238c2ecf20Sopenharmony_ci if (is_inode_flag_set(inode, FI_UPDATE_WRITE)) 8248c2ecf20Sopenharmony_ci f2fs_add_ino_entry(sbi, inode->i_ino, UPDATE_INO); 8258c2ecf20Sopenharmony_ci } 8268c2ecf20Sopenharmony_ci if (is_inode_flag_set(inode, FI_FREE_NID)) { 8278c2ecf20Sopenharmony_ci f2fs_alloc_nid_failed(sbi, inode->i_ino); 8288c2ecf20Sopenharmony_ci clear_inode_flag(inode, FI_FREE_NID); 8298c2ecf20Sopenharmony_ci } else { 8308c2ecf20Sopenharmony_ci /* 8318c2ecf20Sopenharmony_ci * If xattr nid is corrupted, we can reach out error condition, 8328c2ecf20Sopenharmony_ci * err & !f2fs_exist_written_data(sbi, inode->i_ino, ORPHAN_INO)). 8338c2ecf20Sopenharmony_ci * In that case, f2fs_check_nid_range() is enough to give a clue. 8348c2ecf20Sopenharmony_ci */ 8358c2ecf20Sopenharmony_ci } 8368c2ecf20Sopenharmony_ciout_clear: 8378c2ecf20Sopenharmony_ci fscrypt_put_encryption_info(inode); 8388c2ecf20Sopenharmony_ci fsverity_cleanup_inode(inode); 8398c2ecf20Sopenharmony_ci clear_inode(inode); 8408c2ecf20Sopenharmony_ci} 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_ci/* caller should call f2fs_lock_op() */ 8438c2ecf20Sopenharmony_civoid f2fs_handle_failed_inode(struct inode *inode) 8448c2ecf20Sopenharmony_ci{ 8458c2ecf20Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 8468c2ecf20Sopenharmony_ci struct node_info ni; 8478c2ecf20Sopenharmony_ci int err; 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_ci /* 8508c2ecf20Sopenharmony_ci * clear nlink of inode in order to release resource of inode 8518c2ecf20Sopenharmony_ci * immediately. 8528c2ecf20Sopenharmony_ci */ 8538c2ecf20Sopenharmony_ci clear_nlink(inode); 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci /* 8568c2ecf20Sopenharmony_ci * we must call this to avoid inode being remained as dirty, resulting 8578c2ecf20Sopenharmony_ci * in a panic when flushing dirty inodes in gdirty_list. 8588c2ecf20Sopenharmony_ci */ 8598c2ecf20Sopenharmony_ci f2fs_update_inode_page(inode); 8608c2ecf20Sopenharmony_ci f2fs_inode_synced(inode); 8618c2ecf20Sopenharmony_ci 8628c2ecf20Sopenharmony_ci /* don't make bad inode, since it becomes a regular file. */ 8638c2ecf20Sopenharmony_ci unlock_new_inode(inode); 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci /* 8668c2ecf20Sopenharmony_ci * Note: we should add inode to orphan list before f2fs_unlock_op() 8678c2ecf20Sopenharmony_ci * so we can prevent losing this orphan when encoutering checkpoint 8688c2ecf20Sopenharmony_ci * and following suddenly power-off. 8698c2ecf20Sopenharmony_ci */ 8708c2ecf20Sopenharmony_ci err = f2fs_get_node_info(sbi, inode->i_ino, &ni); 8718c2ecf20Sopenharmony_ci if (err) { 8728c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 8738c2ecf20Sopenharmony_ci set_inode_flag(inode, FI_FREE_NID); 8748c2ecf20Sopenharmony_ci f2fs_warn(sbi, "May loss orphan inode, run fsck to fix."); 8758c2ecf20Sopenharmony_ci goto out; 8768c2ecf20Sopenharmony_ci } 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci if (ni.blk_addr != NULL_ADDR) { 8798c2ecf20Sopenharmony_ci err = f2fs_acquire_orphan_inode(sbi); 8808c2ecf20Sopenharmony_ci if (err) { 8818c2ecf20Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 8828c2ecf20Sopenharmony_ci f2fs_warn(sbi, "Too many orphan inodes, run fsck to fix."); 8838c2ecf20Sopenharmony_ci } else { 8848c2ecf20Sopenharmony_ci f2fs_add_orphan_inode(inode); 8858c2ecf20Sopenharmony_ci } 8868c2ecf20Sopenharmony_ci f2fs_alloc_nid_done(sbi, inode->i_ino); 8878c2ecf20Sopenharmony_ci } else { 8888c2ecf20Sopenharmony_ci set_inode_flag(inode, FI_FREE_NID); 8898c2ecf20Sopenharmony_ci } 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ciout: 8928c2ecf20Sopenharmony_ci f2fs_unlock_op(sbi); 8938c2ecf20Sopenharmony_ci 8948c2ecf20Sopenharmony_ci /* iput will drop the inode object */ 8958c2ecf20Sopenharmony_ci iput(inode); 8968c2ecf20Sopenharmony_ci} 897