1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2024, Alibaba Cloud 4 */ 5 #include <linux/xxhash.h> 6 #include <linux/mount.h> 7 #include "internal.h" 8 #include "xattr.h" 9 10 #include "../internal.h" 11 12 static struct vfsmount *erofs_ishare_mnt; 13 14 static inline bool erofs_is_ishare_inode(struct inode *inode) 15 { 16 /* assumed FS_ONDEMAND is excluded with FS_PAGE_CACHE_SHARE feature */ 17 return inode->i_sb->s_type == &erofs_anon_fs_type; 18 } 19 20 static int erofs_ishare_iget5_eq(struct inode *inode, void *data) 21 { 22 struct erofs_inode_fingerprint *fp1 = &EROFS_I(inode)->fingerprint; 23 struct erofs_inode_fingerprint *fp2 = data; 24 25 return fp1->size == fp2->size && 26 !memcmp(fp1->opaque, fp2->opaque, fp2->size); 27 } 28 29 static int erofs_ishare_iget5_set(struct inode *inode, void *data) 30 { 31 struct erofs_inode *vi = EROFS_I(inode); 32 33 vi->fingerprint = *(struct erofs_inode_fingerprint *)data; 34 INIT_LIST_HEAD(&vi->ishare_list); 35 spin_lock_init(&vi->ishare_lock); 36 return 0; 37 } 38 39 bool erofs_ishare_fill_inode(struct inode *inode) 40 { 41 struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); 42 struct erofs_inode *vi = EROFS_I(inode); 43 struct erofs_inode_fingerprint fp; 44 struct inode *sharedinode; 45 unsigned long hash; 46 47 if (erofs_xattr_fill_inode_fingerprint(&fp, inode, sbi->domain_id)) 48 return false; 49 hash = xxh32(fp.opaque, fp.size, 0); 50 sharedinode = iget5_locked(erofs_ishare_mnt->mnt_sb, hash, 51 erofs_ishare_iget5_eq, erofs_ishare_iget5_set, 52 &fp); 53 if (!sharedinode) { 54 kfree(fp.opaque); 55 return false; 56 } 57 58 if (inode_state_read_once(sharedinode) & I_NEW) { 59 if (erofs_inode_set_aops(sharedinode, inode, true)) { 60 iget_failed(sharedinode); 61 kfree(fp.opaque); 62 return false; 63 } 64 sharedinode->i_size = vi->vfs_inode.i_size; 65 unlock_new_inode(sharedinode); 66 } else { 67 kfree(fp.opaque); 68 if (sharedinode->i_size != vi->vfs_inode.i_size) { 69 _erofs_printk(inode->i_sb, KERN_WARNING 70 "size(%lld:%lld) not matches for the same fingerprint\n", 71 vi->vfs_inode.i_size, sharedinode->i_size); 72 iput(sharedinode); 73 return false; 74 } 75 } 76 vi->sharedinode = sharedinode; 77 INIT_LIST_HEAD(&vi->ishare_list); 78 spin_lock(&EROFS_I(sharedinode)->ishare_lock); 79 list_add(&vi->ishare_list, &EROFS_I(sharedinode)->ishare_list); 80 spin_unlock(&EROFS_I(sharedinode)->ishare_lock); 81 return true; 82 } 83 84 void erofs_ishare_free_inode(struct inode *inode) 85 { 86 struct erofs_inode *vi = EROFS_I(inode); 87 struct inode *sharedinode = vi->sharedinode; 88 89 if (!sharedinode) 90 return; 91 spin_lock(&EROFS_I(sharedinode)->ishare_lock); 92 list_del(&vi->ishare_list); 93 spin_unlock(&EROFS_I(sharedinode)->ishare_lock); 94 iput(sharedinode); 95 vi->sharedinode = NULL; 96 } 97 98 static int erofs_ishare_file_open(struct inode *inode, struct file *file) 99 { 100 struct inode *sharedinode = EROFS_I(inode)->sharedinode; 101 struct file *realfile; 102 103 if (file->f_flags & O_DIRECT) 104 return -EINVAL; 105 realfile = alloc_empty_backing_file(O_RDONLY|O_NOATIME, current_cred()); 106 if (IS_ERR(realfile)) 107 return PTR_ERR(realfile); 108 ihold(sharedinode); 109 realfile->f_op = &erofs_file_fops; 110 realfile->f_inode = sharedinode; 111 realfile->f_mapping = sharedinode->i_mapping; 112 path_get(&file->f_path); 113 backing_file_set_user_path(realfile, &file->f_path); 114 115 file_ra_state_init(&realfile->f_ra, file->f_mapping); 116 realfile->private_data = EROFS_I(inode); 117 file->private_data = realfile; 118 return 0; 119 } 120 121 static int erofs_ishare_file_release(struct inode *inode, struct file *file) 122 { 123 struct file *realfile = file->private_data; 124 125 iput(realfile->f_inode); 126 fput(realfile); 127 file->private_data = NULL; 128 return 0; 129 } 130 131 static ssize_t erofs_ishare_file_read_iter(struct kiocb *iocb, 132 struct iov_iter *to) 133 { 134 struct file *realfile = iocb->ki_filp->private_data; 135 struct kiocb dedup_iocb; 136 ssize_t nread; 137 138 if (!iov_iter_count(to)) 139 return 0; 140 kiocb_clone(&dedup_iocb, iocb, realfile); 141 nread = filemap_read(&dedup_iocb, to, 0); 142 iocb->ki_pos = dedup_iocb.ki_pos; 143 return nread; 144 } 145 146 static int erofs_ishare_mmap(struct file *file, struct vm_area_struct *vma) 147 { 148 struct file *realfile = file->private_data; 149 150 vma_set_file(vma, realfile); 151 return generic_file_readonly_mmap(file, vma); 152 } 153 154 static int erofs_ishare_fadvise(struct file *file, loff_t offset, 155 loff_t len, int advice) 156 { 157 return vfs_fadvise(file->private_data, offset, len, advice); 158 } 159 160 const struct file_operations erofs_ishare_fops = { 161 .open = erofs_ishare_file_open, 162 .llseek = generic_file_llseek, 163 .read_iter = erofs_ishare_file_read_iter, 164 .mmap = erofs_ishare_mmap, 165 .release = erofs_ishare_file_release, 166 .get_unmapped_area = thp_get_unmapped_area, 167 .splice_read = filemap_splice_read, 168 .fadvise = erofs_ishare_fadvise, 169 }; 170 171 struct inode *erofs_real_inode(struct inode *inode, bool *need_iput) 172 { 173 struct erofs_inode *vi, *vi_share; 174 struct inode *realinode; 175 176 *need_iput = false; 177 if (!erofs_is_ishare_inode(inode)) 178 return inode; 179 180 vi_share = EROFS_I(inode); 181 spin_lock(&vi_share->ishare_lock); 182 /* fetch any one as real inode */ 183 DBG_BUGON(list_empty(&vi_share->ishare_list)); 184 list_for_each_entry(vi, &vi_share->ishare_list, ishare_list) { 185 realinode = igrab(&vi->vfs_inode); 186 if (realinode) { 187 *need_iput = true; 188 break; 189 } 190 } 191 spin_unlock(&vi_share->ishare_lock); 192 193 DBG_BUGON(!realinode); 194 return realinode; 195 } 196 197 int __init erofs_init_ishare(void) 198 { 199 erofs_ishare_mnt = kern_mount(&erofs_anon_fs_type); 200 return PTR_ERR_OR_ZERO(erofs_ishare_mnt); 201 } 202 203 void erofs_exit_ishare(void) 204 { 205 kern_unmount(erofs_ishare_mnt); 206 } 207