aufs6-mmap.patch 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. SPDX-License-Identifier: GPL-2.0
  2. aufs6.6.63 mmap patch
  3. diff --git a/fs/proc/base.c b/fs/proc/base.c
  4. index 699f085d4de7..8e7cb5a20a30 100644
  5. --- a/fs/proc/base.c
  6. +++ b/fs/proc/base.c
  7. @@ -2277,7 +2277,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
  8. rc = -ENOENT;
  9. vma = find_exact_vma(mm, vm_start, vm_end);
  10. if (vma && vma->vm_file) {
  11. - *path = vma->vm_file->f_path;
  12. + *path = vma_pr_or_file(vma)->f_path;
  13. path_get(path);
  14. rc = 0;
  15. }
  16. diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
  17. index 4d3493579458..42edd9a42c78 100644
  18. --- a/fs/proc/nommu.c
  19. +++ b/fs/proc/nommu.c
  20. @@ -39,7 +39,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
  21. file = region->vm_file;
  22. if (file) {
  23. - struct inode *inode = file_inode(region->vm_file);
  24. + struct inode *inode;
  25. +
  26. + file = vmr_pr_or_file(region);
  27. + inode = file_inode(file);
  28. dev = inode->i_sb->s_dev;
  29. ino = inode->i_ino;
  30. }
  31. diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
  32. index 59571737e167..fc9b9f4aa75f 100644
  33. --- a/fs/proc/task_mmu.c
  34. +++ b/fs/proc/task_mmu.c
  35. @@ -271,7 +271,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
  36. const char *name = NULL;
  37. if (file) {
  38. - struct inode *inode = file_inode(vma->vm_file);
  39. + struct inode *inode;
  40. +
  41. + file = vma_pr_or_file(vma);
  42. + inode = file_inode(file);
  43. dev = inode->i_sb->s_dev;
  44. ino = inode->i_ino;
  45. pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
  46. @@ -1947,7 +1950,7 @@ static int show_numa_map(struct seq_file *m, void *v)
  47. struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
  48. struct vm_area_struct *vma = v;
  49. struct numa_maps *md = &numa_priv->md;
  50. - struct file *file = vma->vm_file;
  51. + struct file *file = vma_pr_or_file(vma);
  52. struct mm_struct *mm = vma->vm_mm;
  53. struct mempolicy *pol;
  54. char buffer[64];
  55. diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
  56. index 7cebd397cc26..81be1641c7fb 100644
  57. --- a/fs/proc/task_nommu.c
  58. +++ b/fs/proc/task_nommu.c
  59. @@ -137,7 +137,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
  60. file = vma->vm_file;
  61. if (file) {
  62. - struct inode *inode = file_inode(vma->vm_file);
  63. + struct inode *inode;
  64. +
  65. + file = vma_pr_or_file(vma);
  66. + inode = file_inode(file);
  67. dev = inode->i_sb->s_dev;
  68. ino = inode->i_ino;
  69. pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
  70. diff --git a/include/linux/mm.h b/include/linux/mm.h
  71. index b6a4d6471b4a..00c7e351d2e8 100644
  72. --- a/include/linux/mm.h
  73. +++ b/include/linux/mm.h
  74. @@ -2415,6 +2415,43 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
  75. static inline struct vm_area_struct *vma_lookup(struct mm_struct *mm,
  76. unsigned long addr);
  77. +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
  78. +extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
  79. +extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
  80. + int);
  81. +extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
  82. +extern void vma_do_fput(struct vm_area_struct *, const char[], int);
  83. +
  84. +#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
  85. + __LINE__)
  86. +#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
  87. + __LINE__)
  88. +#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
  89. +#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
  90. +
  91. +#ifndef CONFIG_MMU
  92. +extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
  93. +extern void vmr_do_fput(struct vm_region *, const char[], int);
  94. +
  95. +#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
  96. + __LINE__)
  97. +#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
  98. +#endif /* !CONFIG_MMU */
  99. +
  100. +#else
  101. +
  102. +#define vma_file_update_time(vma) file_update_time((vma)->vm_file)
  103. +#define vma_pr_or_file(vma) (vma)->vm_file
  104. +#define vma_get_file(vma) get_file((vma)->vm_file)
  105. +#define vma_fput(vma) fput((vma)->vm_file)
  106. +
  107. +#ifndef CONFIG_MMU
  108. +#define vmr_pr_or_file(region) (region)->vm_file
  109. +#define vmr_fput(region) fput((region)->vm_file)
  110. +#endif /* !CONFIG_MMU */
  111. +
  112. +#endif /* CONFIG_AUFS_FS */
  113. +
  114. extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
  115. void *buf, int len, unsigned int gup_flags);
  116. extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
  117. diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
  118. index 43c19d85dfe7..c6bdd132b7ff 100644
  119. --- a/include/linux/mm_types.h
  120. +++ b/include/linux/mm_types.h
  121. @@ -524,6 +524,9 @@ struct vm_region {
  122. unsigned long vm_top; /* region allocated to here */
  123. unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
  124. struct file *vm_file; /* the backing file or NULL */
  125. +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
  126. + struct file *vm_prfile; /* the virtual backing file or NULL */
  127. +#endif
  128. int vm_usage; /* region usage count (access under nommu_region_sem) */
  129. bool vm_icache_flushed : 1; /* true if the icache has been flushed for
  130. @@ -664,6 +667,9 @@ struct vm_area_struct {
  131. unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
  132. units */
  133. struct file * vm_file; /* File we map to (can be NULL). */
  134. +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
  135. + struct file *vm_prfile; /* shadow of vm_file */
  136. +#endif
  137. void * vm_private_data; /* was vm_pte (shared mem) */
  138. #ifdef CONFIG_ANON_VMA_NAME
  139. diff --git a/kernel/fork.c b/kernel/fork.c
  140. index 23efaa2c42e4..50b94374b715 100644
  141. --- a/kernel/fork.c
  142. +++ b/kernel/fork.c
  143. @@ -732,7 +732,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
  144. if (file) {
  145. struct address_space *mapping = file->f_mapping;
  146. - get_file(file);
  147. + vma_get_file(tmp);
  148. i_mmap_lock_write(mapping);
  149. if (tmp->vm_flags & VM_SHARED)
  150. mapping_allow_writable(mapping);
  151. diff --git a/mm/Makefile b/mm/Makefile
  152. index ec65984e2ade..d59461647ccd 100644
  153. --- a/mm/Makefile
  154. +++ b/mm/Makefile
  155. @@ -138,3 +138,4 @@ obj-$(CONFIG_IO_MAPPING) += io-mapping.o
  156. obj-$(CONFIG_HAVE_BOOTMEM_INFO_NODE) += bootmem_info.o
  157. obj-$(CONFIG_GENERIC_IOREMAP) += ioremap.o
  158. obj-$(CONFIG_SHRINKER_DEBUG) += shrinker_debug.o
  159. +obj-y += prfile.o
  160. diff --git a/mm/filemap.c b/mm/filemap.c
  161. index 2c308413387f..82051ef9f5dd 100644
  162. --- a/mm/filemap.c
  163. +++ b/mm/filemap.c
  164. @@ -3661,7 +3661,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
  165. vm_fault_t ret = VM_FAULT_LOCKED;
  166. sb_start_pagefault(mapping->host->i_sb);
  167. - file_update_time(vmf->vma->vm_file);
  168. + vma_file_update_time(vmf->vma);
  169. folio_lock(folio);
  170. if (folio->mapping != mapping) {
  171. folio_unlock(folio);
  172. diff --git a/mm/mmap.c b/mm/mmap.c
  173. index e4dfeaef668a..a15b967bb0f8 100644
  174. --- a/mm/mmap.c
  175. +++ b/mm/mmap.c
  176. @@ -139,7 +139,7 @@ static void remove_vma(struct vm_area_struct *vma, bool unreachable)
  177. might_sleep();
  178. vma_close(vma);
  179. if (vma->vm_file)
  180. - fput(vma->vm_file);
  181. + vma_fput(vma);
  182. mpol_put(vma_policy(vma));
  183. if (unreachable)
  184. __vm_area_free(vma);
  185. @@ -553,7 +553,7 @@ static inline void vma_complete(struct vma_prepare *vp,
  186. if (vp->file) {
  187. uprobe_munmap(vp->remove, vp->remove->vm_start,
  188. vp->remove->vm_end);
  189. - fput(vp->file);
  190. + vma_fput(vp->vma);
  191. }
  192. if (vp->remove->anon_vma)
  193. anon_vma_merge(vp->vma, vp->remove);
  194. @@ -2391,7 +2391,7 @@ int __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
  195. goto out_free_mpol;
  196. if (new->vm_file)
  197. - get_file(new->vm_file);
  198. + vma_get_file(new);
  199. if (new->vm_ops && new->vm_ops->open)
  200. new->vm_ops->open(new);
  201. @@ -2810,7 +2810,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr,
  202. * and cause general protection fault
  203. * ultimately.
  204. */
  205. - fput(vma->vm_file);
  206. + vma_fput(vma);
  207. vm_area_free(vma);
  208. vma = merge;
  209. /* Update vm_flags to pick up the change. */
  210. @@ -2887,7 +2887,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr,
  211. return addr;
  212. unmap_and_free_file_vma:
  213. - fput(vma->vm_file);
  214. + vma_fput(vma);
  215. vma->vm_file = NULL;
  216. vma_iter_set(&vmi, vma->vm_end);
  217. @@ -2981,6 +2981,9 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
  218. unsigned long populate = 0;
  219. unsigned long ret = -EINVAL;
  220. struct file *file;
  221. +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
  222. + struct file *prfile;
  223. +#endif
  224. pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/mm/remap_file_pages.rst.\n",
  225. current->comm, current->pid);
  226. @@ -3039,6 +3042,32 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
  227. if (vma->vm_flags & VM_LOCKED)
  228. flags |= MAP_LOCKED;
  229. +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
  230. + vma_get_file(vma);
  231. + file = vma->vm_file;
  232. + prfile = vma->vm_prfile;
  233. + ret = security_mmap_file(vma->vm_file, prot, flags);
  234. + if (!ret) {
  235. + ret = do_mmap(vma->vm_file, start, size,
  236. + prot, flags, /*vm_flags*/0, pgoff, &populate, NULL);
  237. + if (!IS_ERR_VALUE(ret) && file && prfile) {
  238. + struct vm_area_struct *new_vma;
  239. +
  240. + new_vma = find_vma(mm, ret);
  241. + if (!new_vma->vm_prfile)
  242. + new_vma->vm_prfile = prfile;
  243. + if (prfile)
  244. + get_file(prfile);
  245. + }
  246. + }
  247. + /*
  248. + * two fput()s instead of vma_fput(vma),
  249. + * coz vma may not be available anymore.
  250. + */
  251. + fput(file);
  252. + if (prfile)
  253. + fput(prfile);
  254. +#else
  255. file = get_file(vma->vm_file);
  256. ret = security_mmap_file(vma->vm_file, prot, flags);
  257. if (ret)
  258. @@ -3047,6 +3076,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
  259. prot, flags, 0, pgoff, &populate, NULL);
  260. out_fput:
  261. fput(file);
  262. +#endif /* CONFIG_AUFS_FS */
  263. out:
  264. mmap_write_unlock(mm);
  265. if (populate)
  266. @@ -3397,7 +3427,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
  267. if (anon_vma_clone(new_vma, vma))
  268. goto out_free_mempol;
  269. if (new_vma->vm_file)
  270. - get_file(new_vma->vm_file);
  271. + vma_get_file(new_vma);
  272. if (new_vma->vm_ops && new_vma->vm_ops->open)
  273. new_vma->vm_ops->open(new_vma);
  274. if (vma_link(mm, new_vma))
  275. @@ -3410,7 +3440,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
  276. vma_close(new_vma);
  277. if (new_vma->vm_file)
  278. - fput(new_vma->vm_file);
  279. + vma_fput(new_vma);
  280. unlink_anon_vmas(new_vma);
  281. out_free_mempol:
  282. diff --git a/mm/nommu.c b/mm/nommu.c
  283. index f848d98e8997..a6f5ef257fd4 100644
  284. --- a/mm/nommu.c
  285. +++ b/mm/nommu.c
  286. @@ -523,7 +523,7 @@ static void __put_nommu_region(struct vm_region *region)
  287. up_write(&nommu_region_sem);
  288. if (region->vm_file)
  289. - fput(region->vm_file);
  290. + vmr_fput(region);
  291. /* IO memory and memory shared directly out of the pagecache
  292. * from ramfs/tmpfs mustn't be released here */
  293. @@ -602,7 +602,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
  294. {
  295. vma_close(vma);
  296. if (vma->vm_file)
  297. - fput(vma->vm_file);
  298. + vma_fput(vma);
  299. put_nommu_region(vma->vm_region);
  300. vm_area_free(vma);
  301. }
  302. @@ -1134,7 +1134,7 @@ unsigned long do_mmap(struct file *file,
  303. goto error_just_free;
  304. }
  305. }
  306. - fput(region->vm_file);
  307. + vmr_fput(region);
  308. kmem_cache_free(vm_region_jar, region);
  309. region = pregion;
  310. result = start;
  311. @@ -1220,10 +1220,10 @@ unsigned long do_mmap(struct file *file,
  312. error:
  313. vma_iter_free(&vmi);
  314. if (region->vm_file)
  315. - fput(region->vm_file);
  316. + vmr_fput(region);
  317. kmem_cache_free(vm_region_jar, region);
  318. if (vma->vm_file)
  319. - fput(vma->vm_file);
  320. + vma_fput(vma);
  321. vm_area_free(vma);
  322. return ret;
  323. diff --git a/mm/prfile.c b/mm/prfile.c
  324. new file mode 100644
  325. index 000000000000..8f820a235364
  326. --- /dev/null
  327. +++ b/mm/prfile.c
  328. @@ -0,0 +1,86 @@
  329. +// SPDX-License-Identifier: GPL-2.0
  330. +/*
  331. + * Mainly for aufs which mmap(2) different file and wants to print different
  332. + * path in /proc/PID/maps.
  333. + * Call these functions via macros defined in linux/mm.h.
  334. + *
  335. + * See Documentation/filesystems/aufs/design/06mmap.txt
  336. + *
  337. + * Copyright (c) 2014-2022 Junjro R. Okajima
  338. + * Copyright (c) 2014 Ian Campbell
  339. + */
  340. +
  341. +#include <linux/mm.h>
  342. +#include <linux/file.h>
  343. +#include <linux/fs.h>
  344. +
  345. +/* #define PRFILE_TRACE */
  346. +static inline void prfile_trace(struct file *f, struct file *pr,
  347. + const char func[], int line, const char func2[])
  348. +{
  349. +#ifdef PRFILE_TRACE
  350. + if (pr)
  351. + pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
  352. +#endif
  353. +}
  354. +
  355. +void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
  356. + int line)
  357. +{
  358. + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
  359. +
  360. + prfile_trace(f, pr, func, line, __func__);
  361. + file_update_time(f);
  362. + if (f && pr)
  363. + file_update_time(pr);
  364. +}
  365. +
  366. +struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
  367. + int line)
  368. +{
  369. + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
  370. +
  371. + prfile_trace(f, pr, func, line, __func__);
  372. + return (f && pr) ? pr : f;
  373. +}
  374. +
  375. +void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
  376. +{
  377. + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
  378. +
  379. + prfile_trace(f, pr, func, line, __func__);
  380. + get_file(f);
  381. + if (f && pr)
  382. + get_file(pr);
  383. +}
  384. +
  385. +void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
  386. +{
  387. + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
  388. +
  389. + prfile_trace(f, pr, func, line, __func__);
  390. + fput(f);
  391. + if (f && pr)
  392. + fput(pr);
  393. +}
  394. +
  395. +#ifndef CONFIG_MMU
  396. +struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
  397. + int line)
  398. +{
  399. + struct file *f = region->vm_file, *pr = region->vm_prfile;
  400. +
  401. + prfile_trace(f, pr, func, line, __func__);
  402. + return (f && pr) ? pr : f;
  403. +}
  404. +
  405. +void vmr_do_fput(struct vm_region *region, const char func[], int line)
  406. +{
  407. + struct file *f = region->vm_file, *pr = region->vm_prfile;
  408. +
  409. + prfile_trace(f, pr, func, line, __func__);
  410. + fput(f);
  411. + if (f && pr)
  412. + fput(pr);
  413. +}
  414. +#endif /* !CONFIG_MMU */