wok diff linux/stuff/aufs3-mmap.patch @ rev 25682

Up libqcow (20240308)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Mar 24 18:25:46 2024 +0000 (2 months ago)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/linux/stuff/aufs3-mmap.patch	Sun Mar 24 18:25:46 2024 +0000
     1.3 @@ -0,0 +1,420 @@
     1.4 +aufs3.16 mmap patch
     1.5 +
     1.6 +diff --git a/fs/buffer.c b/fs/buffer.c
     1.7 +index eba6e4f..31f0b2d 100644
     1.8 +--- a/fs/buffer.c
     1.9 ++++ b/fs/buffer.c
    1.10 +@@ -2460,7 +2460,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
    1.11 + 	 * Update file times before taking page lock. We may end up failing the
    1.12 + 	 * fault so this update may be superfluous but who really cares...
    1.13 + 	 */
    1.14 +-	file_update_time(vma->vm_file);
    1.15 ++	vma_file_update_time(vma);
    1.16 + 
    1.17 + 	ret = __block_page_mkwrite(vma, vmf, get_block);
    1.18 + 	sb_end_pagefault(sb);
    1.19 +diff --git a/fs/proc/base.c b/fs/proc/base.c
    1.20 +index 2d696b0..fb92686 100644
    1.21 +--- a/fs/proc/base.c
    1.22 ++++ b/fs/proc/base.c
    1.23 +@@ -1799,7 +1799,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
    1.24 + 	down_read(&mm->mmap_sem);
    1.25 + 	vma = find_exact_vma(mm, vm_start, vm_end);
    1.26 + 	if (vma && vma->vm_file) {
    1.27 +-		*path = vma->vm_file->f_path;
    1.28 ++		*path = vma_pr_or_file(vma)->f_path;
    1.29 + 		path_get(path);
    1.30 + 		rc = 0;
    1.31 + 	}
    1.32 +diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
    1.33 +index d4a3574..1397181 100644
    1.34 +--- a/fs/proc/nommu.c
    1.35 ++++ b/fs/proc/nommu.c
    1.36 +@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
    1.37 + 	file = region->vm_file;
    1.38 + 
    1.39 + 	if (file) {
    1.40 +-		struct inode *inode = file_inode(region->vm_file);
    1.41 ++		struct inode *inode;
    1.42 ++
    1.43 ++		file = vmr_pr_or_file(region);
    1.44 ++		inode = file_inode(file);
    1.45 + 		dev = inode->i_sb->s_dev;
    1.46 + 		ino = inode->i_ino;
    1.47 + 	}
    1.48 +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
    1.49 +index cfa63ee..bf4919e 100644
    1.50 +--- a/fs/proc/task_mmu.c
    1.51 ++++ b/fs/proc/task_mmu.c
    1.52 +@@ -265,7 +265,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
    1.53 + 	const char *name = NULL;
    1.54 + 
    1.55 + 	if (file) {
    1.56 +-		struct inode *inode = file_inode(vma->vm_file);
    1.57 ++		struct inode *inode;
    1.58 ++
    1.59 ++		file = vma_pr_or_file(vma);
    1.60 ++		inode = file_inode(file);
    1.61 + 		dev = inode->i_sb->s_dev;
    1.62 + 		ino = inode->i_ino;
    1.63 + 		pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
    1.64 +@@ -1390,7 +1393,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
    1.65 + 	struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
    1.66 + 	struct vm_area_struct *vma = v;
    1.67 + 	struct numa_maps *md = &numa_priv->md;
    1.68 +-	struct file *file = vma->vm_file;
    1.69 ++	struct file *file = vma_pr_or_file(vma);
    1.70 + 	struct task_struct *task = proc_priv->task;
    1.71 + 	struct mm_struct *mm = vma->vm_mm;
    1.72 + 	struct mm_walk walk = {};
    1.73 +diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
    1.74 +index 678455d..ebd34ba 100644
    1.75 +--- a/fs/proc/task_nommu.c
    1.76 ++++ b/fs/proc/task_nommu.c
    1.77 +@@ -141,7 +141,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
    1.78 + 	file = vma->vm_file;
    1.79 + 
    1.80 + 	if (file) {
    1.81 +-		struct inode *inode = file_inode(vma->vm_file);
    1.82 ++		struct inode *inode;
    1.83 ++
    1.84 ++		file = vma_pr_or_file(vma);
    1.85 ++		inode = file_inode(file);
    1.86 + 		dev = inode->i_sb->s_dev;
    1.87 + 		ino = inode->i_ino;
    1.88 + 		pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
    1.89 +diff --git a/include/linux/mm.h b/include/linux/mm.h
    1.90 +index e03dd29..b576690 100644
    1.91 +--- a/include/linux/mm.h
    1.92 ++++ b/include/linux/mm.h
    1.93 +@@ -1184,6 +1184,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
    1.94 + }
    1.95 + #endif
    1.96 + 
    1.97 ++extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
    1.98 ++extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
    1.99 ++				      int);
   1.100 ++extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
   1.101 ++extern void vma_do_fput(struct vm_area_struct *, const char[], int);
   1.102 ++
   1.103 ++#define vma_file_update_time(vma)	vma_do_file_update_time(vma, __func__, \
   1.104 ++								__LINE__)
   1.105 ++#define vma_pr_or_file(vma)		vma_do_pr_or_file(vma, __func__, \
   1.106 ++							  __LINE__)
   1.107 ++#define vma_get_file(vma)		vma_do_get_file(vma, __func__, __LINE__)
   1.108 ++#define vma_fput(vma)			vma_do_fput(vma, __func__, __LINE__)
   1.109 ++
   1.110 ++#ifndef CONFIG_MMU
   1.111 ++extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
   1.112 ++extern void vmr_do_fput(struct vm_region *, const char[], int);
   1.113 ++
   1.114 ++#define vmr_pr_or_file(region)		vmr_do_pr_or_file(region, __func__, \
   1.115 ++							  __LINE__)
   1.116 ++#define vmr_fput(region)		vmr_do_fput(region, __func__, __LINE__)
   1.117 ++#endif /* !CONFIG_MMU */
   1.118 ++
   1.119 + extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
   1.120 + extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
   1.121 + 		void *buf, int len, int write);
   1.122 +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
   1.123 +index 96c5750..a087ecd 100644
   1.124 +--- a/include/linux/mm_types.h
   1.125 ++++ b/include/linux/mm_types.h
   1.126 +@@ -232,6 +232,7 @@ struct vm_region {
   1.127 + 	unsigned long	vm_top;		/* region allocated to here */
   1.128 + 	unsigned long	vm_pgoff;	/* the offset in vm_file corresponding to vm_start */
   1.129 + 	struct file	*vm_file;	/* the backing file or NULL */
   1.130 ++	struct file	*vm_prfile;	/* the virtual backing file or NULL */
   1.131 + 
   1.132 + 	int		vm_usage;	/* region usage count (access under nommu_region_sem) */
   1.133 + 	bool		vm_icache_flushed : 1; /* true if the icache has been flushed for
   1.134 +@@ -300,6 +301,7 @@ struct vm_area_struct {
   1.135 + 	unsigned long vm_pgoff;		/* Offset (within vm_file) in PAGE_SIZE
   1.136 + 					   units, *not* PAGE_CACHE_SIZE */
   1.137 + 	struct file * vm_file;		/* File we map to (can be NULL). */
   1.138 ++	struct file *vm_prfile;		/* shadow of vm_file */
   1.139 + 	void * vm_private_data;		/* was vm_pte (shared mem) */
   1.140 + 
   1.141 + #ifndef CONFIG_MMU
   1.142 +diff --git a/kernel/fork.c b/kernel/fork.c
   1.143 +index 6a13c46..714302c 100644
   1.144 +--- a/kernel/fork.c
   1.145 ++++ b/kernel/fork.c
   1.146 +@@ -416,7 +416,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
   1.147 + 			struct inode *inode = file_inode(file);
   1.148 + 			struct address_space *mapping = file->f_mapping;
   1.149 + 
   1.150 +-			get_file(file);
   1.151 ++			vma_get_file(tmp);
   1.152 + 			if (tmp->vm_flags & VM_DENYWRITE)
   1.153 + 				atomic_dec(&inode->i_writecount);
   1.154 + 			mutex_lock(&mapping->i_mmap_mutex);
   1.155 +diff --git a/mm/Makefile b/mm/Makefile
   1.156 +index 4064f3e..0003fdf 100644
   1.157 +--- a/mm/Makefile
   1.158 ++++ b/mm/Makefile
   1.159 +@@ -18,7 +18,7 @@ obj-y			:= filemap.o mempool.o oom_kill.o fadvise.o \
   1.160 + 			   mm_init.o mmu_context.o percpu.o slab_common.o \
   1.161 + 			   compaction.o balloon_compaction.o vmacache.o \
   1.162 + 			   interval_tree.o list_lru.o workingset.o \
   1.163 +-			   iov_iter.o $(mmu-y)
   1.164 ++			   iov_iter.o prfile.o $(mmu-y)
   1.165 + 
   1.166 + obj-y += init-mm.o
   1.167 + 
   1.168 +diff --git a/mm/filemap.c b/mm/filemap.c
   1.169 +index 900edfa..f4dda0c 100644
   1.170 +--- a/mm/filemap.c
   1.171 ++++ b/mm/filemap.c
   1.172 +@@ -2040,7 +2040,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
   1.173 + 	int ret = VM_FAULT_LOCKED;
   1.174 + 
   1.175 + 	sb_start_pagefault(inode->i_sb);
   1.176 +-	file_update_time(vma->vm_file);
   1.177 ++	vma_file_update_time(vma);
   1.178 + 	lock_page(page);
   1.179 + 	if (page->mapping != inode->i_mapping) {
   1.180 + 		unlock_page(page);
   1.181 +diff --git a/mm/fremap.c b/mm/fremap.c
   1.182 +index 72b8fa3..a00bbf0 100644
   1.183 +--- a/mm/fremap.c
   1.184 ++++ b/mm/fremap.c
   1.185 +@@ -224,16 +224,28 @@ get_write_lock:
   1.186 + 		 */
   1.187 + 		if (mapping_cap_account_dirty(mapping)) {
   1.188 + 			unsigned long addr;
   1.189 +-			struct file *file = get_file(vma->vm_file);
   1.190 ++			struct file *file = vma->vm_file,
   1.191 ++				*prfile = vma->vm_prfile;
   1.192 ++
   1.193 + 			/* mmap_region may free vma; grab the info now */
   1.194 + 			vm_flags = vma->vm_flags;
   1.195 + 
   1.196 ++			vma_get_file(vma);
   1.197 + 			addr = mmap_region(file, start, size, vm_flags, pgoff);
   1.198 +-			fput(file);
   1.199 ++			vma_fput(vma);
   1.200 + 			if (IS_ERR_VALUE(addr)) {
   1.201 + 				err = addr;
   1.202 + 			} else {
   1.203 + 				BUG_ON(addr != start);
   1.204 ++				if (prfile) {
   1.205 ++					struct vm_area_struct *new_vma;
   1.206 ++
   1.207 ++					new_vma = find_vma(mm, addr);
   1.208 ++					if (!new_vma->vm_prfile)
   1.209 ++						new_vma->vm_prfile = prfile;
   1.210 ++					if (new_vma != vma)
   1.211 ++						get_file(prfile);
   1.212 ++				}
   1.213 + 				err = 0;
   1.214 + 			}
   1.215 + 			goto out_freed;
   1.216 +diff --git a/mm/memory.c b/mm/memory.c
   1.217 +index 8b44f76..69a72bf 100644
   1.218 +--- a/mm/memory.c
   1.219 ++++ b/mm/memory.c
   1.220 +@@ -2161,7 +2161,7 @@ reuse:
   1.221 + 			set_page_dirty_balance(dirty_page);
   1.222 + 			/* file_update_time outside page_lock */
   1.223 + 			if (vma->vm_file)
   1.224 +-				file_update_time(vma->vm_file);
   1.225 ++				vma_file_update_time(vma);
   1.226 + 		}
   1.227 + 		put_page(dirty_page);
   1.228 + 		if (page_mkwrite) {
   1.229 +diff --git a/mm/mmap.c b/mm/mmap.c
   1.230 +index 129b847..869d1d7 100644
   1.231 +--- a/mm/mmap.c
   1.232 ++++ b/mm/mmap.c
   1.233 +@@ -253,7 +253,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
   1.234 + 	if (vma->vm_ops && vma->vm_ops->close)
   1.235 + 		vma->vm_ops->close(vma);
   1.236 + 	if (vma->vm_file)
   1.237 +-		fput(vma->vm_file);
   1.238 ++		vma_fput(vma);
   1.239 + 	mpol_put(vma_policy(vma));
   1.240 + 	kmem_cache_free(vm_area_cachep, vma);
   1.241 + 	return next;
   1.242 +@@ -863,7 +863,7 @@ again:			remove_next = 1 + (end > next->vm_end);
   1.243 + 	if (remove_next) {
   1.244 + 		if (file) {
   1.245 + 			uprobe_munmap(next, next->vm_start, next->vm_end);
   1.246 +-			fput(file);
   1.247 ++			vma_fput(vma);
   1.248 + 		}
   1.249 + 		if (next->anon_vma)
   1.250 + 			anon_vma_merge(vma, next);
   1.251 +@@ -1643,8 +1643,8 @@ out:
   1.252 + unmap_and_free_vma:
   1.253 + 	if (vm_flags & VM_DENYWRITE)
   1.254 + 		allow_write_access(file);
   1.255 ++	vma_fput(vma);
   1.256 + 	vma->vm_file = NULL;
   1.257 +-	fput(file);
   1.258 + 
   1.259 + 	/* Undo any partial mapping done by a device driver. */
   1.260 + 	unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
   1.261 +@@ -2434,7 +2434,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
   1.262 + 		goto out_free_mpol;
   1.263 + 
   1.264 + 	if (new->vm_file)
   1.265 +-		get_file(new->vm_file);
   1.266 ++		vma_get_file(new);
   1.267 + 
   1.268 + 	if (new->vm_ops && new->vm_ops->open)
   1.269 + 		new->vm_ops->open(new);
   1.270 +@@ -2453,7 +2453,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
   1.271 + 	if (new->vm_ops && new->vm_ops->close)
   1.272 + 		new->vm_ops->close(new);
   1.273 + 	if (new->vm_file)
   1.274 +-		fput(new->vm_file);
   1.275 ++		vma_fput(new);
   1.276 + 	unlink_anon_vmas(new);
   1.277 +  out_free_mpol:
   1.278 + 	mpol_put(vma_policy(new));
   1.279 +@@ -2842,7 +2842,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
   1.280 + 			if (anon_vma_clone(new_vma, vma))
   1.281 + 				goto out_free_mempol;
   1.282 + 			if (new_vma->vm_file)
   1.283 +-				get_file(new_vma->vm_file);
   1.284 ++				vma_get_file(new_vma);
   1.285 + 			if (new_vma->vm_ops && new_vma->vm_ops->open)
   1.286 + 				new_vma->vm_ops->open(new_vma);
   1.287 + 			vma_link(mm, new_vma, prev, rb_link, rb_parent);
   1.288 +diff --git a/mm/nommu.c b/mm/nommu.c
   1.289 +index 4a852f6..b369644 100644
   1.290 +--- a/mm/nommu.c
   1.291 ++++ b/mm/nommu.c
   1.292 +@@ -658,7 +658,7 @@ static void __put_nommu_region(struct vm_region *region)
   1.293 + 		up_write(&nommu_region_sem);
   1.294 + 
   1.295 + 		if (region->vm_file)
   1.296 +-			fput(region->vm_file);
   1.297 ++			vmr_fput(region);
   1.298 + 
   1.299 + 		/* IO memory and memory shared directly out of the pagecache
   1.300 + 		 * from ramfs/tmpfs mustn't be released here */
   1.301 +@@ -823,7 +823,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
   1.302 + 	if (vma->vm_ops && vma->vm_ops->close)
   1.303 + 		vma->vm_ops->close(vma);
   1.304 + 	if (vma->vm_file)
   1.305 +-		fput(vma->vm_file);
   1.306 ++		vma_fput(vma);
   1.307 + 	put_nommu_region(vma->vm_region);
   1.308 + 	kmem_cache_free(vm_area_cachep, vma);
   1.309 + }
   1.310 +@@ -1385,7 +1385,7 @@ unsigned long do_mmap_pgoff(struct file *file,
   1.311 + 					goto error_just_free;
   1.312 + 				}
   1.313 + 			}
   1.314 +-			fput(region->vm_file);
   1.315 ++			vmr_fput(region);
   1.316 + 			kmem_cache_free(vm_region_jar, region);
   1.317 + 			region = pregion;
   1.318 + 			result = start;
   1.319 +@@ -1461,10 +1461,10 @@ error_just_free:
   1.320 + 	up_write(&nommu_region_sem);
   1.321 + error:
   1.322 + 	if (region->vm_file)
   1.323 +-		fput(region->vm_file);
   1.324 ++		vmr_fput(region);
   1.325 + 	kmem_cache_free(vm_region_jar, region);
   1.326 + 	if (vma->vm_file)
   1.327 +-		fput(vma->vm_file);
   1.328 ++		vma_fput(vma);
   1.329 + 	kmem_cache_free(vm_area_cachep, vma);
   1.330 + 	kleave(" = %d", ret);
   1.331 + 	return ret;
   1.332 +diff --git a/mm/prfile.c b/mm/prfile.c
   1.333 +new file mode 100644
   1.334 +index 0000000..532e518
   1.335 +--- /dev/null
   1.336 ++++ b/mm/prfile.c
   1.337 +@@ -0,0 +1,86 @@
   1.338 ++/*
   1.339 ++ * Mainly for aufs which mmap(2) diffrent file and wants to print different path
   1.340 ++ * in /proc/PID/maps.
   1.341 ++ * Call these functions via macros defined in linux/mm.h.
   1.342 ++ *
   1.343 ++ * See Documentation/filesystems/aufs/design/06mmap.txt
   1.344 ++ *
   1.345 ++ * Copyright (c) 2014 Junjro R. Okajima
   1.346 ++ * Copyright (c) 2014 Ian Campbell
   1.347 ++ */
   1.348 ++
   1.349 ++#include <linux/mm.h>
   1.350 ++#include <linux/file.h>
   1.351 ++#include <linux/fs.h>
   1.352 ++
   1.353 ++/* #define PRFILE_TRACE */
   1.354 ++static inline void prfile_trace(struct file *f, struct file *pr,
   1.355 ++			      const char func[], int line, const char func2[])
   1.356 ++{
   1.357 ++#ifdef PRFILE_TRACE
   1.358 ++	if (pr)
   1.359 ++		pr_info("%s:%d: %s, %s\n", func, line, func2,
   1.360 ++			f ? (char *)f->f_dentry->d_name.name : "(null)");
   1.361 ++#endif
   1.362 ++}
   1.363 ++
   1.364 ++void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
   1.365 ++			     int line)
   1.366 ++{
   1.367 ++	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
   1.368 ++
   1.369 ++	prfile_trace(f, pr, func, line, __func__);
   1.370 ++	file_update_time(f);
   1.371 ++	if (f && pr)
   1.372 ++		file_update_time(pr);
   1.373 ++}
   1.374 ++
   1.375 ++struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
   1.376 ++			       int line)
   1.377 ++{
   1.378 ++	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
   1.379 ++
   1.380 ++	prfile_trace(f, pr, func, line, __func__);
   1.381 ++	return (f && pr) ? pr : f;
   1.382 ++}
   1.383 ++
   1.384 ++void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
   1.385 ++{
   1.386 ++	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
   1.387 ++
   1.388 ++	prfile_trace(f, pr, func, line, __func__);
   1.389 ++	get_file(f);
   1.390 ++	if (f && pr)
   1.391 ++		get_file(pr);
   1.392 ++}
   1.393 ++
   1.394 ++void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
   1.395 ++{
   1.396 ++	struct file *f = vma->vm_file, *pr = vma->vm_prfile;
   1.397 ++
   1.398 ++	prfile_trace(f, pr, func, line, __func__);
   1.399 ++	fput(f);
   1.400 ++	if (f && pr)
   1.401 ++		fput(pr);
   1.402 ++}
   1.403 ++
   1.404 ++#ifndef CONFIG_MMU
   1.405 ++struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
   1.406 ++			       int line)
   1.407 ++{
   1.408 ++	struct file *f = region->vm_file, *pr = region->vm_prfile;
   1.409 ++
   1.410 ++	prfile_trace(f, pr, func, line, __func__);
   1.411 ++	return (f && pr) ? pr : f;
   1.412 ++}
   1.413 ++
   1.414 ++void vmr_do_fput(struct vm_region *region, const char func[], int line)
   1.415 ++{
   1.416 ++	struct file *f = region->vm_file, *pr = region->vm_prfile;
   1.417 ++
   1.418 ++	prfile_trace(f, pr, func, line, __func__);
   1.419 ++	fput(f);
   1.420 ++	if (f && pr)
   1.421 ++		fput(pr);
   1.422 ++}
   1.423 ++#endif /* !CONFIG_MMU */