wok-current view linux/stuff/aufs5-mmap.patch @ rev 25728

Merge wok for both arch and few updates
author Stanislas Leduc <shann@slitaz.org>
date Thu Dec 05 08:39:45 2024 +0000 (9 months ago)
parents
children
line source
1 SPDX-License-Identifier: GPL-2.0
2 aufs5.10.140 mmap patch
4 diff --git a/fs/proc/base.c b/fs/proc/base.c
5 index 5d52aea8d7e7..2fbf0ad30eaa 100644
6 --- a/fs/proc/base.c
7 +++ b/fs/proc/base.c
8 @@ -2184,7 +2184,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
9 rc = -ENOENT;
10 vma = find_exact_vma(mm, vm_start, vm_end);
11 if (vma && vma->vm_file) {
12 - *path = vma->vm_file->f_path;
13 + *path = vma_pr_or_file(vma)->f_path;
14 path_get(path);
15 rc = 0;
16 }
17 diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
18 index 13452b32e2bd..38acccfef9d4 100644
19 --- a/fs/proc/nommu.c
20 +++ b/fs/proc/nommu.c
21 @@ -40,7 +40,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
22 file = region->vm_file;
24 if (file) {
25 - struct inode *inode = file_inode(region->vm_file);
26 + struct inode *inode;
27 +
28 + file = vmr_pr_or_file(region);
29 + inode = file_inode(file);
30 dev = inode->i_sb->s_dev;
31 ino = inode->i_ino;
32 }
33 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
34 index ef18f0d71b11..3c52843db20b 100644
35 --- a/fs/proc/task_mmu.c
36 +++ b/fs/proc/task_mmu.c
37 @@ -280,7 +280,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
38 const char *name = NULL;
40 if (file) {
41 - struct inode *inode = file_inode(vma->vm_file);
42 + struct inode *inode;
43 +
44 + file = vma_pr_or_file(vma);
45 + inode = file_inode(file);
46 dev = inode->i_sb->s_dev;
47 ino = inode->i_ino;
48 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
49 @@ -1885,7 +1888,7 @@ static int show_numa_map(struct seq_file *m, void *v)
50 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
51 struct vm_area_struct *vma = v;
52 struct numa_maps *md = &numa_priv->md;
53 - struct file *file = vma->vm_file;
54 + struct file *file = vma_pr_or_file(vma);
55 struct mm_struct *mm = vma->vm_mm;
56 struct mempolicy *pol;
57 char buffer[64];
58 diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
59 index a6d21fc0033c..02c2de31196e 100644
60 --- a/fs/proc/task_nommu.c
61 +++ b/fs/proc/task_nommu.c
62 @@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
63 file = vma->vm_file;
65 if (file) {
66 - struct inode *inode = file_inode(vma->vm_file);
67 + struct inode *inode;
68 +
69 + file = vma_pr_or_file(vma);
70 + inode = file_inode(file);
71 dev = inode->i_sb->s_dev;
72 ino = inode->i_ino;
73 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
74 diff --git a/include/linux/mm.h b/include/linux/mm.h
75 index b8b677f47a8d..18c07145ed7e 100644
76 --- a/include/linux/mm.h
77 +++ b/include/linux/mm.h
78 @@ -1732,6 +1732,43 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
79 unmap_mapping_range(mapping, holebegin, holelen, 0);
80 }
82 +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
83 +extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
84 +extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
85 + int);
86 +extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
87 +extern void vma_do_fput(struct vm_area_struct *, const char[], int);
88 +
89 +#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
90 + __LINE__)
91 +#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
92 + __LINE__)
93 +#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
94 +#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
95 +
96 +#ifndef CONFIG_MMU
97 +extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
98 +extern void vmr_do_fput(struct vm_region *, const char[], int);
99 +
100 +#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
101 + __LINE__)
102 +#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
103 +#endif /* !CONFIG_MMU */
104 +
105 +#else
106 +
107 +#define vma_file_update_time(vma) file_update_time((vma)->vm_file)
108 +#define vma_pr_or_file(vma) (vma)->vm_file
109 +#define vma_get_file(vma) get_file((vma)->vm_file)
110 +#define vma_fput(vma) fput((vma)->vm_file)
111 +
112 +#ifndef CONFIG_MMU
113 +#define vmr_pr_or_file(region) (region)->vm_file
114 +#define vmr_fput(region) fput((region)->vm_file)
115 +#endif /* !CONFIG_MMU */
116 +
117 +#endif /* CONFIG_AUFS_FS */
118 +
119 extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
120 void *buf, int len, unsigned int gup_flags);
121 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
122 diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
123 index 4eb38918da8f..ed87c1ba3cf9 100644
124 --- a/include/linux/mm_types.h
125 +++ b/include/linux/mm_types.h
126 @@ -282,6 +282,9 @@ struct vm_region {
127 unsigned long vm_top; /* region allocated to here */
128 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
129 struct file *vm_file; /* the backing file or NULL */
130 +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
131 + struct file *vm_prfile; /* the virtual backing file or NULL */
132 +#endif
134 int vm_usage; /* region usage count (access under nommu_region_sem) */
135 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
136 @@ -361,6 +364,9 @@ struct vm_area_struct {
137 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
138 units */
139 struct file * vm_file; /* File we map to (can be NULL). */
140 +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
141 + struct file *vm_prfile; /* shadow of vm_file */
142 +#endif
143 void * vm_private_data; /* was vm_pte (shared mem) */
145 #ifdef CONFIG_SWAP
146 diff --git a/kernel/fork.c b/kernel/fork.c
147 index a78c0b02edd5..e5874ec6b430 100644
148 --- a/kernel/fork.c
149 +++ b/kernel/fork.c
150 @@ -554,7 +554,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
151 struct inode *inode = file_inode(file);
152 struct address_space *mapping = file->f_mapping;
154 - get_file(file);
155 + vma_get_file(tmp);
156 if (tmp->vm_flags & VM_DENYWRITE)
157 put_write_access(inode);
158 i_mmap_lock_write(mapping);
159 diff --git a/mm/Makefile b/mm/Makefile
160 index d73aed0fc99c..bf0989e5043d 100644
161 --- a/mm/Makefile
162 +++ b/mm/Makefile
163 @@ -120,3 +120,4 @@ obj-$(CONFIG_MEMFD_CREATE) += memfd.o
164 obj-$(CONFIG_MAPPING_DIRTY_HELPERS) += mapping_dirty_helpers.o
165 obj-$(CONFIG_PTDUMP_CORE) += ptdump.o
166 obj-$(CONFIG_PAGE_REPORTING) += page_reporting.o
167 +obj-y += prfile.o
168 diff --git a/mm/filemap.c b/mm/filemap.c
169 index 125b69f59caa..00bfb23c599f 100644
170 --- a/mm/filemap.c
171 +++ b/mm/filemap.c
172 @@ -2913,7 +2913,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
173 vm_fault_t ret = VM_FAULT_LOCKED;
175 sb_start_pagefault(inode->i_sb);
176 - file_update_time(vmf->vma->vm_file);
177 + vma_file_update_time(vmf->vma);
178 lock_page(page);
179 if (page->mapping != inode->i_mapping) {
180 unlock_page(page);
181 diff --git a/mm/mmap.c b/mm/mmap.c
182 index a1ee93f55ceb..2baefbc409b4 100644
183 --- a/mm/mmap.c
184 +++ b/mm/mmap.c
185 @@ -179,7 +179,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
186 if (vma->vm_ops && vma->vm_ops->close)
187 vma->vm_ops->close(vma);
188 if (vma->vm_file)
189 - fput(vma->vm_file);
190 + vma_fput(vma);
191 mpol_put(vma_policy(vma));
192 vm_area_free(vma);
193 return next;
194 @@ -951,7 +951,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
195 if (remove_next) {
196 if (file) {
197 uprobe_munmap(next, next->vm_start, next->vm_end);
198 - fput(file);
199 + vma_fput(vma);
200 }
201 if (next->anon_vma)
202 anon_vma_merge(vma, next);
203 @@ -1834,7 +1834,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
204 * fput the vma->vm_file here or we would add an extra fput for file
205 * and cause general protection fault ultimately.
206 */
207 - fput(vma->vm_file);
208 + vma_fput(vma);
209 vm_area_free(vma);
210 vma = merge;
211 /* Update vm_flags to pick up the change. */
212 @@ -1901,8 +1901,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
213 return addr;
215 unmap_and_free_vma:
216 + vma_fput(vma);
217 vma->vm_file = NULL;
218 - fput(file);
220 /* Undo any partial mapping done by a device driver. */
221 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
222 @@ -2752,7 +2752,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
223 goto out_free_mpol;
225 if (new->vm_file)
226 - get_file(new->vm_file);
227 + vma_get_file(new);
229 if (new->vm_ops && new->vm_ops->open)
230 new->vm_ops->open(new);
231 @@ -2771,7 +2771,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
232 if (new->vm_ops && new->vm_ops->close)
233 new->vm_ops->close(new);
234 if (new->vm_file)
235 - fput(new->vm_file);
236 + vma_fput(new);
237 unlink_anon_vmas(new);
238 out_free_mpol:
239 mpol_put(vma_policy(new));
240 @@ -2965,6 +2965,9 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
241 unsigned long populate = 0;
242 unsigned long ret = -EINVAL;
243 struct file *file;
244 +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
245 + struct file *prfile;
246 +#endif
248 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n",
249 current->comm, current->pid);
250 @@ -3039,10 +3042,34 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
251 }
252 }
254 +#if 1 /* IS_ENABLED(CONFIG_AUFS_FS) */
255 + vma_get_file(vma);
256 + file = vma->vm_file;
257 + prfile = vma->vm_prfile;
258 + ret = do_mmap(vma->vm_file, start, size,
259 + prot, flags, pgoff, &populate, NULL);
260 + if (!IS_ERR_VALUE(ret) && file && prfile) {
261 + struct vm_area_struct *new_vma;
262 +
263 + new_vma = find_vma(mm, ret);
264 + if (!new_vma->vm_prfile)
265 + new_vma->vm_prfile = prfile;
266 + if (prfile)
267 + get_file(prfile);
268 + }
269 + /*
270 + * two fput()s instead of vma_fput(vma),
271 + * coz vma may not be available anymore.
272 + */
273 + fput(file);
274 + if (prfile)
275 + fput(prfile);
276 +#else
277 file = get_file(vma->vm_file);
278 ret = do_mmap(vma->vm_file, start, size,
279 prot, flags, pgoff, &populate, NULL);
280 fput(file);
281 +#endif /* CONFIG_AUFS_FS */
282 out:
283 mmap_write_unlock(mm);
284 if (populate)
285 @@ -3329,7 +3356,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
286 if (anon_vma_clone(new_vma, vma))
287 goto out_free_mempol;
288 if (new_vma->vm_file)
289 - get_file(new_vma->vm_file);
290 + vma_get_file(new_vma);
291 if (new_vma->vm_ops && new_vma->vm_ops->open)
292 new_vma->vm_ops->open(new_vma);
293 vma_link(mm, new_vma, prev, rb_link, rb_parent);
294 diff --git a/mm/nommu.c b/mm/nommu.c
295 index 0faf39b32cdb..78ecad7204c8 100644
296 --- a/mm/nommu.c
297 +++ b/mm/nommu.c
298 @@ -533,7 +533,7 @@ static void __put_nommu_region(struct vm_region *region)
299 up_write(&nommu_region_sem);
301 if (region->vm_file)
302 - fput(region->vm_file);
303 + vmr_fput(region);
305 /* IO memory and memory shared directly out of the pagecache
306 * from ramfs/tmpfs mustn't be released here */
307 @@ -665,7 +665,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
308 if (vma->vm_ops && vma->vm_ops->close)
309 vma->vm_ops->close(vma);
310 if (vma->vm_file)
311 - fput(vma->vm_file);
312 + vma_fput(vma);
313 put_nommu_region(vma->vm_region);
314 vm_area_free(vma);
315 }
316 @@ -1188,7 +1188,7 @@ unsigned long do_mmap(struct file *file,
317 goto error_just_free;
318 }
319 }
320 - fput(region->vm_file);
321 + vmr_fput(region);
322 kmem_cache_free(vm_region_jar, region);
323 region = pregion;
324 result = start;
325 @@ -1265,10 +1265,10 @@ unsigned long do_mmap(struct file *file,
326 up_write(&nommu_region_sem);
327 error:
328 if (region->vm_file)
329 - fput(region->vm_file);
330 + vmr_fput(region);
331 kmem_cache_free(vm_region_jar, region);
332 if (vma->vm_file)
333 - fput(vma->vm_file);
334 + vma_fput(vma);
335 vm_area_free(vma);
336 return ret;
338 diff --git a/mm/prfile.c b/mm/prfile.c
339 new file mode 100644
340 index 000000000000..511543ab1b41
341 --- /dev/null
342 +++ b/mm/prfile.c
343 @@ -0,0 +1,86 @@
344 +// SPDX-License-Identifier: GPL-2.0
345 +/*
346 + * Mainly for aufs which mmap(2) different file and wants to print different
347 + * path in /proc/PID/maps.
348 + * Call these functions via macros defined in linux/mm.h.
349 + *
350 + * See Documentation/filesystems/aufs/design/06mmap.txt
351 + *
352 + * Copyright (c) 2014-2021 Junjro R. Okajima
353 + * Copyright (c) 2014 Ian Campbell
354 + */
355 +
356 +#include <linux/mm.h>
357 +#include <linux/file.h>
358 +#include <linux/fs.h>
359 +
360 +/* #define PRFILE_TRACE */
361 +static inline void prfile_trace(struct file *f, struct file *pr,
362 + const char func[], int line, const char func2[])
363 +{
364 +#ifdef PRFILE_TRACE
365 + if (pr)
366 + pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
367 +#endif
368 +}
369 +
370 +void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
371 + int line)
372 +{
373 + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
374 +
375 + prfile_trace(f, pr, func, line, __func__);
376 + file_update_time(f);
377 + if (f && pr)
378 + file_update_time(pr);
379 +}
380 +
381 +struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
382 + int line)
383 +{
384 + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
385 +
386 + prfile_trace(f, pr, func, line, __func__);
387 + return (f && pr) ? pr : f;
388 +}
389 +
390 +void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
391 +{
392 + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
393 +
394 + prfile_trace(f, pr, func, line, __func__);
395 + get_file(f);
396 + if (f && pr)
397 + get_file(pr);
398 +}
399 +
400 +void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
401 +{
402 + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
403 +
404 + prfile_trace(f, pr, func, line, __func__);
405 + fput(f);
406 + if (f && pr)
407 + fput(pr);
408 +}
409 +
410 +#ifndef CONFIG_MMU
411 +struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
412 + int line)
413 +{
414 + struct file *f = region->vm_file, *pr = region->vm_prfile;
415 +
416 + prfile_trace(f, pr, func, line, __func__);
417 + return (f && pr) ? pr : f;
418 +}
419 +
420 +void vmr_do_fput(struct vm_region *region, const char func[], int line)
421 +{
422 + struct file *f = region->vm_file, *pr = region->vm_prfile;
423 +
424 + prfile_trace(f, pr, func, line, __func__);
425 + fput(f);
426 + if (f && pr)
427 + fput(pr);
428 +}
429 +#endif /* !CONFIG_MMU */