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 const struct address_space_operations *aops; 44 struct erofs_inode_fingerprint fp; 45 struct inode *sharedinode; 46 unsigned long hash; 47 48 aops = erofs_get_aops(inode, true); 49 if (IS_ERR(aops)) 50 return false; 51 if (erofs_xattr_fill_inode_fingerprint(&fp, inode, sbi->domain_id)) 52 return false; 53 hash = xxh32(fp.opaque, fp.size, 0); 54 sharedinode = iget5_locked(erofs_ishare_mnt->mnt_sb, hash, 55 erofs_ishare_iget5_eq, erofs_ishare_iget5_set, 56 &fp); 57 if (!sharedinode) { 58 kfree(fp.opaque); 59 return false; 60 } 61 62 if (inode_state_read_once(sharedinode) & I_NEW) { 63 sharedinode->i_mapping->a_ops = aops; 64 sharedinode->i_size = vi->vfs_inode.i_size; 65 unlock_new_inode(sharedinode); 66 } else { 67 kfree(fp.opaque); 68 if (aops != sharedinode->i_mapping->a_ops) { 69 iput(sharedinode); 70 return false; 71 } 72 if (sharedinode->i_size != vi->vfs_inode.i_size) { 73 _erofs_printk(inode->i_sb, KERN_WARNING 74 "size(%lld:%lld) not matches for the same fingerprint\n", 75 vi->vfs_inode.i_size, sharedinode->i_size); 76 iput(sharedinode); 77 return false; 78 } 79 } 80 vi->sharedinode = sharedinode; 81 INIT_LIST_HEAD(&vi->ishare_list); 82 spin_lock(&EROFS_I(sharedinode)->ishare_lock); 83 list_add(&vi->ishare_list, &EROFS_I(sharedinode)->ishare_list); 84 spin_unlock(&EROFS_I(sharedinode)->ishare_lock); 85 return true; 86 } 87 88 void erofs_ishare_free_inode(struct inode *inode) 89 { 90 struct erofs_inode *vi = EROFS_I(inode); 91 struct inode *sharedinode = vi->sharedinode; 92 93 if (!sharedinode) 94 return; 95 spin_lock(&EROFS_I(sharedinode)->ishare_lock); 96 list_del(&vi->ishare_list); 97 spin_unlock(&EROFS_I(sharedinode)->ishare_lock); 98 iput(sharedinode); 99 vi->sharedinode = NULL; 100 } 101 102 static int erofs_ishare_file_open(struct inode *inode, struct file *file) 103 { 104 struct inode *sharedinode = EROFS_I(inode)->sharedinode; 105 struct file *realfile; 106 107 if (file->f_flags & O_DIRECT) 108 return -EINVAL; 109 realfile = alloc_empty_backing_file(O_RDONLY|O_NOATIME, current_cred()); 110 if (IS_ERR(realfile)) 111 return PTR_ERR(realfile); 112 ihold(sharedinode); 113 realfile->f_op = &erofs_file_fops; 114 realfile->f_inode = sharedinode; 115 realfile->f_mapping = sharedinode->i_mapping; 116 path_get(&file->f_path); 117 backing_file_set_user_path(realfile, &file->f_path); 118 119 file_ra_state_init(&realfile->f_ra, file->f_mapping); 120 realfile->private_data = EROFS_I(inode); 121 file->private_data = realfile; 122 return 0; 123 } 124 125 static int erofs_ishare_file_release(struct inode *inode, struct file *file) 126 { 127 struct file *realfile = file->private_data; 128 129 iput(realfile->f_inode); 130 fput(realfile); 131 file->private_data = NULL; 132 return 0; 133 } 134 135 static ssize_t erofs_ishare_file_read_iter(struct kiocb *iocb, 136 struct iov_iter *to) 137 { 138 struct file *realfile = iocb->ki_filp->private_data; 139 struct kiocb dedup_iocb; 140 ssize_t nread; 141 142 if (!iov_iter_count(to)) 143 return 0; 144 kiocb_clone(&dedup_iocb, iocb, realfile); 145 nread = filemap_read(&dedup_iocb, to, 0); 146 iocb->ki_pos = dedup_iocb.ki_pos; 147 return nread; 148 } 149 150 static int erofs_ishare_mmap(struct file *file, struct vm_area_struct *vma) 151 { 152 struct file *realfile = file->private_data; 153 154 vma_set_file(vma, realfile); 155 return generic_file_readonly_mmap(file, vma); 156 } 157 158 static int erofs_ishare_fadvise(struct file *file, loff_t offset, 159 loff_t len, int advice) 160 { 161 return vfs_fadvise(file->private_data, offset, len, advice); 162 } 163 164 const struct file_operations erofs_ishare_fops = { 165 .open = erofs_ishare_file_open, 166 .llseek = generic_file_llseek, 167 .read_iter = erofs_ishare_file_read_iter, 168 .mmap = erofs_ishare_mmap, 169 .release = erofs_ishare_file_release, 170 .get_unmapped_area = thp_get_unmapped_area, 171 .splice_read = filemap_splice_read, 172 .fadvise = erofs_ishare_fadvise, 173 }; 174 175 struct inode *erofs_real_inode(struct inode *inode, bool *need_iput) 176 { 177 struct erofs_inode *vi, *vi_share; 178 struct inode *realinode; 179 180 *need_iput = false; 181 if (!erofs_is_ishare_inode(inode)) 182 return inode; 183 184 vi_share = EROFS_I(inode); 185 spin_lock(&vi_share->ishare_lock); 186 /* fetch any one as real inode */ 187 DBG_BUGON(list_empty(&vi_share->ishare_list)); 188 list_for_each_entry(vi, &vi_share->ishare_list, ishare_list) { 189 realinode = igrab(&vi->vfs_inode); 190 if (realinode) { 191 *need_iput = true; 192 break; 193 } 194 } 195 spin_unlock(&vi_share->ishare_lock); 196 197 DBG_BUGON(!realinode); 198 return realinode; 199 } 200 201 int __init erofs_init_ishare(void) 202 { 203 erofs_ishare_mnt = kern_mount(&erofs_anon_fs_type); 204 return PTR_ERR_OR_ZERO(erofs_ishare_mnt); 205 } 206 207 void erofs_exit_ishare(void) 208 { 209 kern_unmount(erofs_ishare_mnt); 210 } 211