147e4937aSGao Xiang // SPDX-License-Identifier: GPL-2.0-only 247e4937aSGao Xiang /* 347e4937aSGao Xiang * Copyright (C) 2017-2018 HUAWEI, Inc. 447e4937aSGao Xiang * http://www.huawei.com/ 547e4937aSGao Xiang * Created by Gao Xiang <gaoxiang25@huawei.com> 647e4937aSGao Xiang */ 747e4937aSGao Xiang #include "xattr.h" 847e4937aSGao Xiang 947e4937aSGao Xiang #include <trace/events/erofs.h> 1047e4937aSGao Xiang 1147e4937aSGao Xiang /* no locking */ 1247e4937aSGao Xiang static int read_inode(struct inode *inode, void *data) 1347e4937aSGao Xiang { 14a5876e24SGao Xiang struct erofs_inode *vi = EROFS_I(inode); 158a765682SGao Xiang struct erofs_inode_compact *dic = data; 168a765682SGao Xiang struct erofs_inode_extended *die; 178a765682SGao Xiang 188a765682SGao Xiang const unsigned int ifmt = le16_to_cpu(dic->i_format); 198a765682SGao Xiang struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); 2047e4937aSGao Xiang erofs_blk_t nblks = 0; 2147e4937aSGao Xiang 228a765682SGao Xiang vi->datalayout = erofs_inode_datalayout(ifmt); 2347e4937aSGao Xiang 248a765682SGao Xiang if (vi->datalayout >= EROFS_INODE_DATALAYOUT_MAX) { 258a765682SGao Xiang errln("unsupported datalayout %u of nid %llu", 268a765682SGao Xiang vi->datalayout, vi->nid); 2747e4937aSGao Xiang DBG_BUGON(1); 2847e4937aSGao Xiang return -EOPNOTSUPP; 2947e4937aSGao Xiang } 3047e4937aSGao Xiang 318a765682SGao Xiang switch (erofs_inode_version(ifmt)) { 328a765682SGao Xiang case EROFS_INODE_LAYOUT_EXTENDED: 338a765682SGao Xiang die = data; 3447e4937aSGao Xiang 358a765682SGao Xiang vi->inode_isize = sizeof(struct erofs_inode_extended); 368a765682SGao Xiang vi->xattr_isize = erofs_xattr_ibody_size(die->i_xattr_icount); 3747e4937aSGao Xiang 388a765682SGao Xiang inode->i_mode = le16_to_cpu(die->i_mode); 398a765682SGao Xiang switch (inode->i_mode & S_IFMT) { 408a765682SGao Xiang case S_IFREG: 418a765682SGao Xiang case S_IFDIR: 428a765682SGao Xiang case S_IFLNK: 438a765682SGao Xiang vi->raw_blkaddr = le32_to_cpu(die->i_u.raw_blkaddr); 448a765682SGao Xiang break; 458a765682SGao Xiang case S_IFCHR: 468a765682SGao Xiang case S_IFBLK: 4747e4937aSGao Xiang inode->i_rdev = 488a765682SGao Xiang new_decode_dev(le32_to_cpu(die->i_u.rdev)); 498a765682SGao Xiang break; 508a765682SGao Xiang case S_IFIFO: 518a765682SGao Xiang case S_IFSOCK: 5247e4937aSGao Xiang inode->i_rdev = 0; 538a765682SGao Xiang break; 548a765682SGao Xiang default: 5547e4937aSGao Xiang goto bogusimode; 568a765682SGao Xiang } 578a765682SGao Xiang i_uid_write(inode, le32_to_cpu(die->i_uid)); 588a765682SGao Xiang i_gid_write(inode, le32_to_cpu(die->i_gid)); 598a765682SGao Xiang set_nlink(inode, le32_to_cpu(die->i_nlink)); 6047e4937aSGao Xiang 6147e4937aSGao Xiang /* ns timestamp */ 6247e4937aSGao Xiang inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = 638a765682SGao Xiang le64_to_cpu(die->i_ctime); 6447e4937aSGao Xiang inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 658a765682SGao Xiang le32_to_cpu(die->i_ctime_nsec); 6647e4937aSGao Xiang 678a765682SGao Xiang inode->i_size = le64_to_cpu(die->i_size); 6847e4937aSGao Xiang 6947e4937aSGao Xiang /* total blocks for compressed files */ 708a765682SGao Xiang if (erofs_inode_is_data_compressed(vi->datalayout)) 718a765682SGao Xiang nblks = le32_to_cpu(die->i_u.compressed_blocks); 728a765682SGao Xiang break; 738a765682SGao Xiang case EROFS_INODE_LAYOUT_COMPACT: 748a765682SGao Xiang vi->inode_isize = sizeof(struct erofs_inode_compact); 758a765682SGao Xiang vi->xattr_isize = erofs_xattr_ibody_size(dic->i_xattr_icount); 7647e4937aSGao Xiang 778a765682SGao Xiang inode->i_mode = le16_to_cpu(dic->i_mode); 788a765682SGao Xiang switch (inode->i_mode & S_IFMT) { 798a765682SGao Xiang case S_IFREG: 808a765682SGao Xiang case S_IFDIR: 818a765682SGao Xiang case S_IFLNK: 828a765682SGao Xiang vi->raw_blkaddr = le32_to_cpu(dic->i_u.raw_blkaddr); 838a765682SGao Xiang break; 848a765682SGao Xiang case S_IFCHR: 858a765682SGao Xiang case S_IFBLK: 8647e4937aSGao Xiang inode->i_rdev = 878a765682SGao Xiang new_decode_dev(le32_to_cpu(dic->i_u.rdev)); 888a765682SGao Xiang break; 898a765682SGao Xiang case S_IFIFO: 908a765682SGao Xiang case S_IFSOCK: 9147e4937aSGao Xiang inode->i_rdev = 0; 928a765682SGao Xiang break; 938a765682SGao Xiang default: 9447e4937aSGao Xiang goto bogusimode; 958a765682SGao Xiang } 968a765682SGao Xiang i_uid_write(inode, le16_to_cpu(dic->i_uid)); 978a765682SGao Xiang i_gid_write(inode, le16_to_cpu(dic->i_gid)); 988a765682SGao Xiang set_nlink(inode, le16_to_cpu(dic->i_nlink)); 9947e4937aSGao Xiang 10047e4937aSGao Xiang /* use build time to derive all file time */ 10147e4937aSGao Xiang inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = 10247e4937aSGao Xiang sbi->build_time; 10347e4937aSGao Xiang inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 10447e4937aSGao Xiang sbi->build_time_nsec; 10547e4937aSGao Xiang 1068a765682SGao Xiang inode->i_size = le32_to_cpu(dic->i_size); 1078a765682SGao Xiang if (erofs_inode_is_data_compressed(vi->datalayout)) 1088a765682SGao Xiang nblks = le32_to_cpu(dic->i_u.compressed_blocks); 1098a765682SGao Xiang break; 1108a765682SGao Xiang default: 11147e4937aSGao Xiang errln("unsupported on-disk inode version %u of nid %llu", 1128a765682SGao Xiang erofs_inode_version(ifmt), vi->nid); 11347e4937aSGao Xiang DBG_BUGON(1); 11447e4937aSGao Xiang return -EOPNOTSUPP; 11547e4937aSGao Xiang } 11647e4937aSGao Xiang 11747e4937aSGao Xiang if (!nblks) 11847e4937aSGao Xiang /* measure inode.i_blocks as generic filesystems */ 11947e4937aSGao Xiang inode->i_blocks = roundup(inode->i_size, EROFS_BLKSIZ) >> 9; 12047e4937aSGao Xiang else 12147e4937aSGao Xiang inode->i_blocks = nblks << LOG_SECTORS_PER_BLOCK; 12247e4937aSGao Xiang return 0; 12347e4937aSGao Xiang 12447e4937aSGao Xiang bogusimode: 12547e4937aSGao Xiang errln("bogus i_mode (%o) @ nid %llu", inode->i_mode, vi->nid); 12647e4937aSGao Xiang DBG_BUGON(1); 12747e4937aSGao Xiang return -EFSCORRUPTED; 12847e4937aSGao Xiang } 12947e4937aSGao Xiang 13047e4937aSGao Xiang /* 13147e4937aSGao Xiang * try_lock can be required since locking order is: 13247e4937aSGao Xiang * file data(fs_inode) 13347e4937aSGao Xiang * meta(bd_inode) 13447e4937aSGao Xiang * but the majority of the callers is "iget", 13547e4937aSGao Xiang * in that case we are pretty sure no deadlock since 13647e4937aSGao Xiang * no data operations exist. However I tend to 13747e4937aSGao Xiang * try_lock since it takes no much overhead and 13847e4937aSGao Xiang * will success immediately. 13947e4937aSGao Xiang */ 14047e4937aSGao Xiang static int fill_inline_data(struct inode *inode, void *data, 14147e4937aSGao Xiang unsigned int m_pofs) 14247e4937aSGao Xiang { 143a5876e24SGao Xiang struct erofs_inode *vi = EROFS_I(inode); 14447e4937aSGao Xiang struct erofs_sb_info *sbi = EROFS_I_SB(inode); 14547e4937aSGao Xiang 1468a765682SGao Xiang /* should be tail-packing data inline */ 1478a765682SGao Xiang if (vi->datalayout != EROFS_INODE_FLAT_INLINE) 14847e4937aSGao Xiang return 0; 14947e4937aSGao Xiang 15047e4937aSGao Xiang /* fast symlink (following ext4) */ 15147e4937aSGao Xiang if (S_ISLNK(inode->i_mode) && inode->i_size < PAGE_SIZE) { 15247e4937aSGao Xiang char *lnk = erofs_kmalloc(sbi, inode->i_size + 1, GFP_KERNEL); 15347e4937aSGao Xiang 1548d8a09b0SGao Xiang if (!lnk) 15547e4937aSGao Xiang return -ENOMEM; 15647e4937aSGao Xiang 15747e4937aSGao Xiang m_pofs += vi->inode_isize + vi->xattr_isize; 15847e4937aSGao Xiang 15947e4937aSGao Xiang /* inline symlink data shouldn't across page boundary as well */ 1608d8a09b0SGao Xiang if (m_pofs + inode->i_size > PAGE_SIZE) { 16147e4937aSGao Xiang kfree(lnk); 16247e4937aSGao Xiang errln("inline data cross block boundary @ nid %llu", 16347e4937aSGao Xiang vi->nid); 16447e4937aSGao Xiang DBG_BUGON(1); 16547e4937aSGao Xiang return -EFSCORRUPTED; 16647e4937aSGao Xiang } 16747e4937aSGao Xiang 16847e4937aSGao Xiang /* get in-page inline data */ 16947e4937aSGao Xiang memcpy(lnk, data + m_pofs, inode->i_size); 17047e4937aSGao Xiang lnk[inode->i_size] = '\0'; 17147e4937aSGao Xiang 17247e4937aSGao Xiang inode->i_link = lnk; 17347e4937aSGao Xiang set_inode_fast_symlink(inode); 17447e4937aSGao Xiang } 17547e4937aSGao Xiang return 0; 17647e4937aSGao Xiang } 17747e4937aSGao Xiang 17847e4937aSGao Xiang static int fill_inode(struct inode *inode, int isdir) 17947e4937aSGao Xiang { 18047e4937aSGao Xiang struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); 181a5876e24SGao Xiang struct erofs_inode *vi = EROFS_I(inode); 18247e4937aSGao Xiang struct page *page; 18347e4937aSGao Xiang void *data; 18447e4937aSGao Xiang int err; 18547e4937aSGao Xiang erofs_blk_t blkaddr; 18647e4937aSGao Xiang unsigned int ofs; 18747e4937aSGao Xiang erofs_off_t inode_loc; 18847e4937aSGao Xiang 18947e4937aSGao Xiang trace_erofs_fill_inode(inode, isdir); 19047e4937aSGao Xiang inode_loc = iloc(sbi, vi->nid); 19147e4937aSGao Xiang blkaddr = erofs_blknr(inode_loc); 19247e4937aSGao Xiang ofs = erofs_blkoff(inode_loc); 19347e4937aSGao Xiang 19447e4937aSGao Xiang debugln("%s, reading inode nid %llu at %u of blkaddr %u", 19547e4937aSGao Xiang __func__, vi->nid, ofs, blkaddr); 19647e4937aSGao Xiang 19747e4937aSGao Xiang page = erofs_get_meta_page(inode->i_sb, blkaddr, isdir); 19847e4937aSGao Xiang 19947e4937aSGao Xiang if (IS_ERR(page)) { 20047e4937aSGao Xiang errln("failed to get inode (nid: %llu) page, err %ld", 20147e4937aSGao Xiang vi->nid, PTR_ERR(page)); 20247e4937aSGao Xiang return PTR_ERR(page); 20347e4937aSGao Xiang } 20447e4937aSGao Xiang 20547e4937aSGao Xiang DBG_BUGON(!PageUptodate(page)); 20647e4937aSGao Xiang data = page_address(page); 20747e4937aSGao Xiang 20847e4937aSGao Xiang err = read_inode(inode, data + ofs); 20947e4937aSGao Xiang if (!err) { 21047e4937aSGao Xiang /* setup the new inode */ 211512f9922SPratik Shinde switch (inode->i_mode & S_IFMT) { 212512f9922SPratik Shinde case S_IFREG: 21347e4937aSGao Xiang inode->i_op = &erofs_generic_iops; 21447e4937aSGao Xiang inode->i_fop = &generic_ro_fops; 215512f9922SPratik Shinde break; 216512f9922SPratik Shinde case S_IFDIR: 21747e4937aSGao Xiang inode->i_op = &erofs_dir_iops; 21847e4937aSGao Xiang inode->i_fop = &erofs_dir_fops; 219512f9922SPratik Shinde break; 220512f9922SPratik Shinde case S_IFLNK: 22147e4937aSGao Xiang /* by default, page_get_link is used for symlink */ 22247e4937aSGao Xiang inode->i_op = &erofs_symlink_iops; 22347e4937aSGao Xiang inode_nohighmem(inode); 224512f9922SPratik Shinde break; 225512f9922SPratik Shinde case S_IFCHR: 226512f9922SPratik Shinde case S_IFBLK: 227512f9922SPratik Shinde case S_IFIFO: 228512f9922SPratik Shinde case S_IFSOCK: 22947e4937aSGao Xiang inode->i_op = &erofs_generic_iops; 23047e4937aSGao Xiang init_special_inode(inode, inode->i_mode, inode->i_rdev); 23147e4937aSGao Xiang goto out_unlock; 232512f9922SPratik Shinde default: 23347e4937aSGao Xiang err = -EFSCORRUPTED; 23447e4937aSGao Xiang goto out_unlock; 23547e4937aSGao Xiang } 23647e4937aSGao Xiang 2378a765682SGao Xiang if (erofs_inode_is_data_compressed(vi->datalayout)) { 23847e4937aSGao Xiang err = z_erofs_fill_inode(inode); 23947e4937aSGao Xiang goto out_unlock; 24047e4937aSGao Xiang } 24147e4937aSGao Xiang 24247e4937aSGao Xiang inode->i_mapping->a_ops = &erofs_raw_access_aops; 24347e4937aSGao Xiang 24447e4937aSGao Xiang /* fill last page if inline data is available */ 24547e4937aSGao Xiang err = fill_inline_data(inode, data, ofs); 24647e4937aSGao Xiang } 24747e4937aSGao Xiang 24847e4937aSGao Xiang out_unlock: 24947e4937aSGao Xiang unlock_page(page); 25047e4937aSGao Xiang put_page(page); 25147e4937aSGao Xiang return err; 25247e4937aSGao Xiang } 25347e4937aSGao Xiang 25447e4937aSGao Xiang /* 25547e4937aSGao Xiang * erofs nid is 64bits, but i_ino is 'unsigned long', therefore 25647e4937aSGao Xiang * we should do more for 32-bit platform to find the right inode. 25747e4937aSGao Xiang */ 25847e4937aSGao Xiang #if BITS_PER_LONG == 32 25947e4937aSGao Xiang static int erofs_ilookup_test_actor(struct inode *inode, void *opaque) 26047e4937aSGao Xiang { 26147e4937aSGao Xiang const erofs_nid_t nid = *(erofs_nid_t *)opaque; 26247e4937aSGao Xiang 263a5876e24SGao Xiang return EROFS_I(inode)->nid == nid; 26447e4937aSGao Xiang } 26547e4937aSGao Xiang 26647e4937aSGao Xiang static int erofs_iget_set_actor(struct inode *inode, void *opaque) 26747e4937aSGao Xiang { 26847e4937aSGao Xiang const erofs_nid_t nid = *(erofs_nid_t *)opaque; 26947e4937aSGao Xiang 27047e4937aSGao Xiang inode->i_ino = erofs_inode_hash(nid); 27147e4937aSGao Xiang return 0; 27247e4937aSGao Xiang } 27347e4937aSGao Xiang #endif 27447e4937aSGao Xiang 27547e4937aSGao Xiang static inline struct inode *erofs_iget_locked(struct super_block *sb, 27647e4937aSGao Xiang erofs_nid_t nid) 27747e4937aSGao Xiang { 27847e4937aSGao Xiang const unsigned long hashval = erofs_inode_hash(nid); 27947e4937aSGao Xiang 28047e4937aSGao Xiang #if BITS_PER_LONG >= 64 28147e4937aSGao Xiang /* it is safe to use iget_locked for >= 64-bit platform */ 28247e4937aSGao Xiang return iget_locked(sb, hashval); 28347e4937aSGao Xiang #else 28447e4937aSGao Xiang return iget5_locked(sb, hashval, erofs_ilookup_test_actor, 28547e4937aSGao Xiang erofs_iget_set_actor, &nid); 28647e4937aSGao Xiang #endif 28747e4937aSGao Xiang } 28847e4937aSGao Xiang 28947e4937aSGao Xiang struct inode *erofs_iget(struct super_block *sb, 29047e4937aSGao Xiang erofs_nid_t nid, 29147e4937aSGao Xiang bool isdir) 29247e4937aSGao Xiang { 29347e4937aSGao Xiang struct inode *inode = erofs_iget_locked(sb, nid); 29447e4937aSGao Xiang 2958d8a09b0SGao Xiang if (!inode) 29647e4937aSGao Xiang return ERR_PTR(-ENOMEM); 29747e4937aSGao Xiang 29847e4937aSGao Xiang if (inode->i_state & I_NEW) { 29947e4937aSGao Xiang int err; 300a5876e24SGao Xiang struct erofs_inode *vi = EROFS_I(inode); 30147e4937aSGao Xiang 30247e4937aSGao Xiang vi->nid = nid; 30347e4937aSGao Xiang 30447e4937aSGao Xiang err = fill_inode(inode, isdir); 3058d8a09b0SGao Xiang if (!err) 30647e4937aSGao Xiang unlock_new_inode(inode); 30747e4937aSGao Xiang else { 30847e4937aSGao Xiang iget_failed(inode); 30947e4937aSGao Xiang inode = ERR_PTR(err); 31047e4937aSGao Xiang } 31147e4937aSGao Xiang } 31247e4937aSGao Xiang return inode; 31347e4937aSGao Xiang } 31447e4937aSGao Xiang 31547e4937aSGao Xiang int erofs_getattr(const struct path *path, struct kstat *stat, 31647e4937aSGao Xiang u32 request_mask, unsigned int query_flags) 31747e4937aSGao Xiang { 31847e4937aSGao Xiang struct inode *const inode = d_inode(path->dentry); 31947e4937aSGao Xiang 320a5876e24SGao Xiang if (erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout)) 32147e4937aSGao Xiang stat->attributes |= STATX_ATTR_COMPRESSED; 32247e4937aSGao Xiang 32347e4937aSGao Xiang stat->attributes |= STATX_ATTR_IMMUTABLE; 32447e4937aSGao Xiang stat->attributes_mask |= (STATX_ATTR_COMPRESSED | 32547e4937aSGao Xiang STATX_ATTR_IMMUTABLE); 32647e4937aSGao Xiang 32747e4937aSGao Xiang generic_fillattr(inode, stat); 32847e4937aSGao Xiang return 0; 32947e4937aSGao Xiang } 33047e4937aSGao Xiang 33147e4937aSGao Xiang const struct inode_operations erofs_generic_iops = { 33247e4937aSGao Xiang .getattr = erofs_getattr, 33347e4937aSGao Xiang #ifdef CONFIG_EROFS_FS_XATTR 33447e4937aSGao Xiang .listxattr = erofs_listxattr, 33547e4937aSGao Xiang #endif 33647e4937aSGao Xiang .get_acl = erofs_get_acl, 33747e4937aSGao Xiang }; 33847e4937aSGao Xiang 33947e4937aSGao Xiang const struct inode_operations erofs_symlink_iops = { 34047e4937aSGao Xiang .get_link = page_get_link, 34147e4937aSGao Xiang .getattr = erofs_getattr, 34247e4937aSGao Xiang #ifdef CONFIG_EROFS_FS_XATTR 34347e4937aSGao Xiang .listxattr = erofs_listxattr, 34447e4937aSGao Xiang #endif 34547e4937aSGao Xiang .get_acl = erofs_get_acl, 34647e4937aSGao Xiang }; 34747e4937aSGao Xiang 34847e4937aSGao Xiang const struct inode_operations erofs_fast_symlink_iops = { 34947e4937aSGao Xiang .get_link = simple_get_link, 35047e4937aSGao Xiang .getattr = erofs_getattr, 35147e4937aSGao Xiang #ifdef CONFIG_EROFS_FS_XATTR 35247e4937aSGao Xiang .listxattr = erofs_listxattr, 35347e4937aSGao Xiang #endif 35447e4937aSGao Xiang .get_acl = erofs_get_acl, 35547e4937aSGao Xiang }; 35647e4937aSGao Xiang 357