ishare.c 5.6 KB

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