wok-current view linux/stuff/aufs3-mmap.patch @ rev 24401
updated check and check-dev (0.13.0 -> 0.15.2)
author | Hans-G?nter Theisgen |
---|---|
date | Tue Feb 08 17:05:29 2022 +0100 (2022-02-08) |
parents | |
children |
line source
1 aufs3.16 mmap patch
3 diff --git a/fs/buffer.c b/fs/buffer.c
4 index eba6e4f..31f0b2d 100644
5 --- a/fs/buffer.c
6 +++ b/fs/buffer.c
7 @@ -2460,7 +2460,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
8 * Update file times before taking page lock. We may end up failing the
9 * fault so this update may be superfluous but who really cares...
10 */
11 - file_update_time(vma->vm_file);
12 + vma_file_update_time(vma);
14 ret = __block_page_mkwrite(vma, vmf, get_block);
15 sb_end_pagefault(sb);
16 diff --git a/fs/proc/base.c b/fs/proc/base.c
17 index 2d696b0..fb92686 100644
18 --- a/fs/proc/base.c
19 +++ b/fs/proc/base.c
20 @@ -1799,7 +1799,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
21 down_read(&mm->mmap_sem);
22 vma = find_exact_vma(mm, vm_start, vm_end);
23 if (vma && vma->vm_file) {
24 - *path = vma->vm_file->f_path;
25 + *path = vma_pr_or_file(vma)->f_path;
26 path_get(path);
27 rc = 0;
28 }
29 diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
30 index d4a3574..1397181 100644
31 --- a/fs/proc/nommu.c
32 +++ b/fs/proc/nommu.c
33 @@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
34 file = region->vm_file;
36 if (file) {
37 - struct inode *inode = file_inode(region->vm_file);
38 + struct inode *inode;
39 +
40 + file = vmr_pr_or_file(region);
41 + inode = file_inode(file);
42 dev = inode->i_sb->s_dev;
43 ino = inode->i_ino;
44 }
45 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
46 index cfa63ee..bf4919e 100644
47 --- a/fs/proc/task_mmu.c
48 +++ b/fs/proc/task_mmu.c
49 @@ -265,7 +265,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
50 const char *name = NULL;
52 if (file) {
53 - struct inode *inode = file_inode(vma->vm_file);
54 + struct inode *inode;
55 +
56 + file = vma_pr_or_file(vma);
57 + inode = file_inode(file);
58 dev = inode->i_sb->s_dev;
59 ino = inode->i_ino;
60 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
61 @@ -1390,7 +1393,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
62 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
63 struct vm_area_struct *vma = v;
64 struct numa_maps *md = &numa_priv->md;
65 - struct file *file = vma->vm_file;
66 + struct file *file = vma_pr_or_file(vma);
67 struct task_struct *task = proc_priv->task;
68 struct mm_struct *mm = vma->vm_mm;
69 struct mm_walk walk = {};
70 diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
71 index 678455d..ebd34ba 100644
72 --- a/fs/proc/task_nommu.c
73 +++ b/fs/proc/task_nommu.c
74 @@ -141,7 +141,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
75 file = vma->vm_file;
77 if (file) {
78 - struct inode *inode = file_inode(vma->vm_file);
79 + struct inode *inode;
80 +
81 + file = vma_pr_or_file(vma);
82 + inode = file_inode(file);
83 dev = inode->i_sb->s_dev;
84 ino = inode->i_ino;
85 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
86 diff --git a/include/linux/mm.h b/include/linux/mm.h
87 index e03dd29..b576690 100644
88 --- a/include/linux/mm.h
89 +++ b/include/linux/mm.h
90 @@ -1184,6 +1184,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
91 }
92 #endif
94 +extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
95 +extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
96 + int);
97 +extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
98 +extern void vma_do_fput(struct vm_area_struct *, const char[], int);
99 +
100 +#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
101 + __LINE__)
102 +#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
103 + __LINE__)
104 +#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
105 +#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
106 +
107 +#ifndef CONFIG_MMU
108 +extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
109 +extern void vmr_do_fput(struct vm_region *, const char[], int);
110 +
111 +#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
112 + __LINE__)
113 +#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
114 +#endif /* !CONFIG_MMU */
115 +
116 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
117 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
118 void *buf, int len, int write);
119 diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
120 index 96c5750..a087ecd 100644
121 --- a/include/linux/mm_types.h
122 +++ b/include/linux/mm_types.h
123 @@ -232,6 +232,7 @@ struct vm_region {
124 unsigned long vm_top; /* region allocated to here */
125 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
126 struct file *vm_file; /* the backing file or NULL */
127 + struct file *vm_prfile; /* the virtual backing file or NULL */
129 int vm_usage; /* region usage count (access under nommu_region_sem) */
130 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
131 @@ -300,6 +301,7 @@ struct vm_area_struct {
132 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
133 units, *not* PAGE_CACHE_SIZE */
134 struct file * vm_file; /* File we map to (can be NULL). */
135 + struct file *vm_prfile; /* shadow of vm_file */
136 void * vm_private_data; /* was vm_pte (shared mem) */
138 #ifndef CONFIG_MMU
139 diff --git a/kernel/fork.c b/kernel/fork.c
140 index 6a13c46..714302c 100644
141 --- a/kernel/fork.c
142 +++ b/kernel/fork.c
143 @@ -416,7 +416,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
144 struct inode *inode = file_inode(file);
145 struct address_space *mapping = file->f_mapping;
147 - get_file(file);
148 + vma_get_file(tmp);
149 if (tmp->vm_flags & VM_DENYWRITE)
150 atomic_dec(&inode->i_writecount);
151 mutex_lock(&mapping->i_mmap_mutex);
152 diff --git a/mm/Makefile b/mm/Makefile
153 index 4064f3e..0003fdf 100644
154 --- a/mm/Makefile
155 +++ b/mm/Makefile
156 @@ -18,7 +18,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \
157 mm_init.o mmu_context.o percpu.o slab_common.o \
158 compaction.o balloon_compaction.o vmacache.o \
159 interval_tree.o list_lru.o workingset.o \
160 - iov_iter.o $(mmu-y)
161 + iov_iter.o prfile.o $(mmu-y)
163 obj-y += init-mm.o
165 diff --git a/mm/filemap.c b/mm/filemap.c
166 index 900edfa..f4dda0c 100644
167 --- a/mm/filemap.c
168 +++ b/mm/filemap.c
169 @@ -2040,7 +2040,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
170 int ret = VM_FAULT_LOCKED;
172 sb_start_pagefault(inode->i_sb);
173 - file_update_time(vma->vm_file);
174 + vma_file_update_time(vma);
175 lock_page(page);
176 if (page->mapping != inode->i_mapping) {
177 unlock_page(page);
178 diff --git a/mm/fremap.c b/mm/fremap.c
179 index 72b8fa3..a00bbf0 100644
180 --- a/mm/fremap.c
181 +++ b/mm/fremap.c
182 @@ -224,16 +224,28 @@ get_write_lock:
183 */
184 if (mapping_cap_account_dirty(mapping)) {
185 unsigned long addr;
186 - struct file *file = get_file(vma->vm_file);
187 + struct file *file = vma->vm_file,
188 + *prfile = vma->vm_prfile;
189 +
190 /* mmap_region may free vma; grab the info now */
191 vm_flags = vma->vm_flags;
193 + vma_get_file(vma);
194 addr = mmap_region(file, start, size, vm_flags, pgoff);
195 - fput(file);
196 + vma_fput(vma);
197 if (IS_ERR_VALUE(addr)) {
198 err = addr;
199 } else {
200 BUG_ON(addr != start);
201 + if (prfile) {
202 + struct vm_area_struct *new_vma;
203 +
204 + new_vma = find_vma(mm, addr);
205 + if (!new_vma->vm_prfile)
206 + new_vma->vm_prfile = prfile;
207 + if (new_vma != vma)
208 + get_file(prfile);
209 + }
210 err = 0;
211 }
212 goto out_freed;
213 diff --git a/mm/memory.c b/mm/memory.c
214 index 8b44f76..69a72bf 100644
215 --- a/mm/memory.c
216 +++ b/mm/memory.c
217 @@ -2161,7 +2161,7 @@ reuse:
218 set_page_dirty_balance(dirty_page);
219 /* file_update_time outside page_lock */
220 if (vma->vm_file)
221 - file_update_time(vma->vm_file);
222 + vma_file_update_time(vma);
223 }
224 put_page(dirty_page);
225 if (page_mkwrite) {
226 diff --git a/mm/mmap.c b/mm/mmap.c
227 index 129b847..869d1d7 100644
228 --- a/mm/mmap.c
229 +++ b/mm/mmap.c
230 @@ -253,7 +253,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
231 if (vma->vm_ops && vma->vm_ops->close)
232 vma->vm_ops->close(vma);
233 if (vma->vm_file)
234 - fput(vma->vm_file);
235 + vma_fput(vma);
236 mpol_put(vma_policy(vma));
237 kmem_cache_free(vm_area_cachep, vma);
238 return next;
239 @@ -863,7 +863,7 @@ again: remove_next = 1 + (end > next->vm_end);
240 if (remove_next) {
241 if (file) {
242 uprobe_munmap(next, next->vm_start, next->vm_end);
243 - fput(file);
244 + vma_fput(vma);
245 }
246 if (next->anon_vma)
247 anon_vma_merge(vma, next);
248 @@ -1643,8 +1643,8 @@ out:
249 unmap_and_free_vma:
250 if (vm_flags & VM_DENYWRITE)
251 allow_write_access(file);
252 + vma_fput(vma);
253 vma->vm_file = NULL;
254 - fput(file);
256 /* Undo any partial mapping done by a device driver. */
257 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
258 @@ -2434,7 +2434,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
259 goto out_free_mpol;
261 if (new->vm_file)
262 - get_file(new->vm_file);
263 + vma_get_file(new);
265 if (new->vm_ops && new->vm_ops->open)
266 new->vm_ops->open(new);
267 @@ -2453,7 +2453,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
268 if (new->vm_ops && new->vm_ops->close)
269 new->vm_ops->close(new);
270 if (new->vm_file)
271 - fput(new->vm_file);
272 + vma_fput(new);
273 unlink_anon_vmas(new);
274 out_free_mpol:
275 mpol_put(vma_policy(new));
276 @@ -2842,7 +2842,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
277 if (anon_vma_clone(new_vma, vma))
278 goto out_free_mempol;
279 if (new_vma->vm_file)
280 - get_file(new_vma->vm_file);
281 + vma_get_file(new_vma);
282 if (new_vma->vm_ops && new_vma->vm_ops->open)
283 new_vma->vm_ops->open(new_vma);
284 vma_link(mm, new_vma, prev, rb_link, rb_parent);
285 diff --git a/mm/nommu.c b/mm/nommu.c
286 index 4a852f6..b369644 100644
287 --- a/mm/nommu.c
288 +++ b/mm/nommu.c
289 @@ -658,7 +658,7 @@ static void __put_nommu_region(struct vm_region *region)
290 up_write(&nommu_region_sem);
292 if (region->vm_file)
293 - fput(region->vm_file);
294 + vmr_fput(region);
296 /* IO memory and memory shared directly out of the pagecache
297 * from ramfs/tmpfs mustn't be released here */
298 @@ -823,7 +823,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
299 if (vma->vm_ops && vma->vm_ops->close)
300 vma->vm_ops->close(vma);
301 if (vma->vm_file)
302 - fput(vma->vm_file);
303 + vma_fput(vma);
304 put_nommu_region(vma->vm_region);
305 kmem_cache_free(vm_area_cachep, vma);
306 }
307 @@ -1385,7 +1385,7 @@ unsigned long do_mmap_pgoff(struct file *file,
308 goto error_just_free;
309 }
310 }
311 - fput(region->vm_file);
312 + vmr_fput(region);
313 kmem_cache_free(vm_region_jar, region);
314 region = pregion;
315 result = start;
316 @@ -1461,10 +1461,10 @@ error_just_free:
317 up_write(&nommu_region_sem);
318 error:
319 if (region->vm_file)
320 - fput(region->vm_file);
321 + vmr_fput(region);
322 kmem_cache_free(vm_region_jar, region);
323 if (vma->vm_file)
324 - fput(vma->vm_file);
325 + vma_fput(vma);
326 kmem_cache_free(vm_area_cachep, vma);
327 kleave(" = %d", ret);
328 return ret;
329 diff --git a/mm/prfile.c b/mm/prfile.c
330 new file mode 100644
331 index 0000000..532e518
332 --- /dev/null
333 +++ b/mm/prfile.c
334 @@ -0,0 +1,86 @@
335 +/*
336 + * Mainly for aufs which mmap(2) diffrent file and wants to print different path
337 + * in /proc/PID/maps.
338 + * Call these functions via macros defined in linux/mm.h.
339 + *
340 + * See Documentation/filesystems/aufs/design/06mmap.txt
341 + *
342 + * Copyright (c) 2014 Junjro R. Okajima
343 + * Copyright (c) 2014 Ian Campbell
344 + */
345 +
346 +#include <linux/mm.h>
347 +#include <linux/file.h>
348 +#include <linux/fs.h>
349 +
350 +/* #define PRFILE_TRACE */
351 +static inline void prfile_trace(struct file *f, struct file *pr,
352 + const char func[], int line, const char func2[])
353 +{
354 +#ifdef PRFILE_TRACE
355 + if (pr)
356 + pr_info("%s:%d: %s, %s\n", func, line, func2,
357 + f ? (char *)f->f_dentry->d_name.name : "(null)");
358 +#endif
359 +}
360 +
361 +void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
362 + int line)
363 +{
364 + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
365 +
366 + prfile_trace(f, pr, func, line, __func__);
367 + file_update_time(f);
368 + if (f && pr)
369 + file_update_time(pr);
370 +}
371 +
372 +struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
373 + int line)
374 +{
375 + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
376 +
377 + prfile_trace(f, pr, func, line, __func__);
378 + return (f && pr) ? pr : f;
379 +}
380 +
381 +void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
382 +{
383 + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
384 +
385 + prfile_trace(f, pr, func, line, __func__);
386 + get_file(f);
387 + if (f && pr)
388 + get_file(pr);
389 +}
390 +
391 +void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
392 +{
393 + struct file *f = vma->vm_file, *pr = vma->vm_prfile;
394 +
395 + prfile_trace(f, pr, func, line, __func__);
396 + fput(f);
397 + if (f && pr)
398 + fput(pr);
399 +}
400 +
401 +#ifndef CONFIG_MMU
402 +struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
403 + int line)
404 +{
405 + struct file *f = region->vm_file, *pr = region->vm_prfile;
406 +
407 + prfile_trace(f, pr, func, line, __func__);
408 + return (f && pr) ? pr : f;
409 +}
410 +
411 +void vmr_do_fput(struct vm_region *region, const char func[], int line)
412 +{
413 + struct file *f = region->vm_file, *pr = region->vm_prfile;
414 +
415 + prfile_trace(f, pr, func, line, __func__);
416 + fput(f);
417 + if (f && pr)
418 + fput(pr);
419 +}
420 +#endif /* !CONFIG_MMU */