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