wok diff linux/stuff/aufs3-loopback.patch @ rev 25037

Up glza (0.11.4)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat May 21 21:38:29 2022 +0000 (2022-05-21)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/linux/stuff/aufs3-loopback.patch	Sat May 21 21:38:29 2022 +0000
     1.3 @@ -0,0 +1,290 @@
     1.4 +aufs3.16 loopback patch
     1.5 +
     1.6 +diff --git a/drivers/block/loop.c b/drivers/block/loop.c
     1.7 +index 30efd68..77b31b4 100644
     1.8 +--- a/drivers/block/loop.c
     1.9 ++++ b/drivers/block/loop.c
    1.10 +@@ -514,7 +514,7 @@ out:
    1.11 + }
    1.12 + 
    1.13 + struct switch_request {
    1.14 +-	struct file *file;
    1.15 ++	struct file *file, *virt_file;
    1.16 + 	struct completion wait;
    1.17 + };
    1.18 + 
    1.19 +@@ -576,7 +576,8 @@ static int loop_thread(void *data)
    1.20 +  * First it needs to flush existing IO, it does this by sending a magic
    1.21 +  * BIO down the pipe. The completion of this BIO does the actual switch.
    1.22 +  */
    1.23 +-static int loop_switch(struct loop_device *lo, struct file *file)
    1.24 ++static int loop_switch(struct loop_device *lo, struct file *file,
    1.25 ++		       struct file *virt_file)
    1.26 + {
    1.27 + 	struct switch_request w;
    1.28 + 	struct bio *bio = bio_alloc(GFP_KERNEL, 0);
    1.29 +@@ -584,6 +585,7 @@ static int loop_switch(struct loop_device *lo, struct file *file)
    1.30 + 		return -ENOMEM;
    1.31 + 	init_completion(&w.wait);
    1.32 + 	w.file = file;
    1.33 ++	w.virt_file = virt_file;
    1.34 + 	bio->bi_private = &w;
    1.35 + 	bio->bi_bdev = NULL;
    1.36 + 	loop_make_request(lo->lo_queue, bio);
    1.37 +@@ -600,7 +602,7 @@ static int loop_flush(struct loop_device *lo)
    1.38 + 	if (!lo->lo_thread)
    1.39 + 		return 0;
    1.40 + 
    1.41 +-	return loop_switch(lo, NULL);
    1.42 ++	return loop_switch(lo, NULL, NULL);
    1.43 + }
    1.44 + 
    1.45 + /*
    1.46 +@@ -619,6 +621,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
    1.47 + 	mapping = file->f_mapping;
    1.48 + 	mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
    1.49 + 	lo->lo_backing_file = file;
    1.50 ++	lo->lo_backing_virt_file = p->virt_file;
    1.51 + 	lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
    1.52 + 		mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
    1.53 + 	lo->old_gfp_mask = mapping_gfp_mask(mapping);
    1.54 +@@ -627,6 +630,13 @@ out:
    1.55 + 	complete(&p->wait);
    1.56 + }
    1.57 + 
    1.58 ++static struct file *loop_real_file(struct file *file)
    1.59 ++{
    1.60 ++	struct file *f = NULL;
    1.61 ++	if (file->f_dentry->d_sb->s_op->real_loop)
    1.62 ++		f = file->f_dentry->d_sb->s_op->real_loop(file);
    1.63 ++	return f;
    1.64 ++}
    1.65 + 
    1.66 + /*
    1.67 +  * loop_change_fd switched the backing store of a loopback device to
    1.68 +@@ -640,6 +650,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
    1.69 + 			  unsigned int arg)
    1.70 + {
    1.71 + 	struct file	*file, *old_file;
    1.72 ++	struct file	*f, *virt_file = NULL, *old_virt_file;
    1.73 + 	struct inode	*inode;
    1.74 + 	int		error;
    1.75 + 
    1.76 +@@ -656,9 +667,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
    1.77 + 	file = fget(arg);
    1.78 + 	if (!file)
    1.79 + 		goto out;
    1.80 ++	f = loop_real_file(file);
    1.81 ++	if (f) {
    1.82 ++		virt_file = file;
    1.83 ++		file = f;
    1.84 ++		get_file(file);
    1.85 ++	}
    1.86 + 
    1.87 + 	inode = file->f_mapping->host;
    1.88 + 	old_file = lo->lo_backing_file;
    1.89 ++	old_virt_file = lo->lo_backing_virt_file;
    1.90 + 
    1.91 + 	error = -EINVAL;
    1.92 + 
    1.93 +@@ -670,17 +688,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
    1.94 + 		goto out_putf;
    1.95 + 
    1.96 + 	/* and ... switch */
    1.97 +-	error = loop_switch(lo, file);
    1.98 ++	error = loop_switch(lo, file, virt_file);
    1.99 + 	if (error)
   1.100 + 		goto out_putf;
   1.101 + 
   1.102 + 	fput(old_file);
   1.103 ++	if (old_virt_file)
   1.104 ++		fput(old_virt_file);
   1.105 + 	if (lo->lo_flags & LO_FLAGS_PARTSCAN)
   1.106 + 		ioctl_by_bdev(bdev, BLKRRPART, 0);
   1.107 + 	return 0;
   1.108 + 
   1.109 +  out_putf:
   1.110 + 	fput(file);
   1.111 ++	if (virt_file)
   1.112 ++		fput(virt_file);
   1.113 +  out:
   1.114 + 	return error;
   1.115 + }
   1.116 +@@ -841,7 +863,7 @@ static void loop_config_discard(struct loop_device *lo)
   1.117 + static int loop_set_fd(struct loop_device *lo, fmode_t mode,
   1.118 + 		       struct block_device *bdev, unsigned int arg)
   1.119 + {
   1.120 +-	struct file	*file, *f;
   1.121 ++	struct file	*file, *f, *virt_file = NULL;
   1.122 + 	struct inode	*inode;
   1.123 + 	struct address_space *mapping;
   1.124 + 	unsigned lo_blocksize;
   1.125 +@@ -856,6 +878,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
   1.126 + 	file = fget(arg);
   1.127 + 	if (!file)
   1.128 + 		goto out;
   1.129 ++	f = loop_real_file(file);
   1.130 ++	if (f) {
   1.131 ++		virt_file = file;
   1.132 ++		file = f;
   1.133 ++		get_file(file);
   1.134 ++	}
   1.135 + 
   1.136 + 	error = -EBUSY;
   1.137 + 	if (lo->lo_state != Lo_unbound)
   1.138 +@@ -904,6 +932,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
   1.139 + 	lo->lo_device = bdev;
   1.140 + 	lo->lo_flags = lo_flags;
   1.141 + 	lo->lo_backing_file = file;
   1.142 ++	lo->lo_backing_virt_file = virt_file;
   1.143 + 	lo->transfer = transfer_none;
   1.144 + 	lo->ioctl = NULL;
   1.145 + 	lo->lo_sizelimit = 0;
   1.146 +@@ -948,6 +977,7 @@ out_clr:
   1.147 + 	lo->lo_thread = NULL;
   1.148 + 	lo->lo_device = NULL;
   1.149 + 	lo->lo_backing_file = NULL;
   1.150 ++	lo->lo_backing_virt_file = NULL;
   1.151 + 	lo->lo_flags = 0;
   1.152 + 	set_capacity(lo->lo_disk, 0);
   1.153 + 	invalidate_bdev(bdev);
   1.154 +@@ -957,6 +987,8 @@ out_clr:
   1.155 + 	lo->lo_state = Lo_unbound;
   1.156 +  out_putf:
   1.157 + 	fput(file);
   1.158 ++	if (virt_file)
   1.159 ++		fput(virt_file);
   1.160 +  out:
   1.161 + 	/* This is safe: open() is still holding a reference. */
   1.162 + 	module_put(THIS_MODULE);
   1.163 +@@ -1003,6 +1035,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
   1.164 + static int loop_clr_fd(struct loop_device *lo)
   1.165 + {
   1.166 + 	struct file *filp = lo->lo_backing_file;
   1.167 ++	struct file *virt_filp = lo->lo_backing_virt_file;
   1.168 + 	gfp_t gfp = lo->old_gfp_mask;
   1.169 + 	struct block_device *bdev = lo->lo_device;
   1.170 + 
   1.171 +@@ -1036,6 +1069,7 @@ static int loop_clr_fd(struct loop_device *lo)
   1.172 + 
   1.173 + 	spin_lock_irq(&lo->lo_lock);
   1.174 + 	lo->lo_backing_file = NULL;
   1.175 ++	lo->lo_backing_virt_file = NULL;
   1.176 + 	spin_unlock_irq(&lo->lo_lock);
   1.177 + 
   1.178 + 	loop_release_xfer(lo);
   1.179 +@@ -1078,6 +1112,8 @@ static int loop_clr_fd(struct loop_device *lo)
   1.180 + 	 * bd_mutex which is usually taken before lo_ctl_mutex.
   1.181 + 	 */
   1.182 + 	fput(filp);
   1.183 ++	if (virt_filp)
   1.184 ++		fput(virt_filp);
   1.185 + 	return 0;
   1.186 + }
   1.187 + 
   1.188 +diff --git a/drivers/block/loop.h b/drivers/block/loop.h
   1.189 +index 90df5d6..cb91822 100644
   1.190 +--- a/drivers/block/loop.h
   1.191 ++++ b/drivers/block/loop.h
   1.192 +@@ -44,7 +44,7 @@ struct loop_device {
   1.193 + 	int		(*ioctl)(struct loop_device *, int cmd, 
   1.194 + 				 unsigned long arg); 
   1.195 + 
   1.196 +-	struct file *	lo_backing_file;
   1.197 ++	struct file *	lo_backing_file, *lo_backing_virt_file;
   1.198 + 	struct block_device *lo_device;
   1.199 + 	unsigned	lo_blocksize;
   1.200 + 	void		*key_data; 
   1.201 +diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
   1.202 +index 95ff59f..79cc7b6 100644
   1.203 +--- a/fs/aufs/f_op.c
   1.204 ++++ b/fs/aufs/f_op.c
   1.205 +@@ -398,7 +398,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
   1.206 + 	if (IS_ERR(h_file))
   1.207 + 		goto out;
   1.208 + 
   1.209 +-	if (au_test_loopback_kthread()) {
   1.210 ++	if (0 && au_test_loopback_kthread()) {
   1.211 + 		au_warn_loopback(h_file->f_dentry->d_sb);
   1.212 + 		if (file->f_mapping != h_file->f_mapping) {
   1.213 + 			file->f_mapping = h_file->f_mapping;
   1.214 +diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
   1.215 +index 2a3e245..e2ac602 100644
   1.216 +--- a/fs/aufs/loop.c
   1.217 ++++ b/fs/aufs/loop.c
   1.218 +@@ -130,3 +130,19 @@ void au_loopback_fin(void)
   1.219 + 	symbol_put(loop_backing_file);
   1.220 + 	kfree(au_warn_loopback_array);
   1.221 + }
   1.222 ++
   1.223 ++/* ---------------------------------------------------------------------- */
   1.224 ++
   1.225 ++/* support the loopback block device insude aufs */
   1.226 ++
   1.227 ++struct file *aufs_real_loop(struct file *file)
   1.228 ++{
   1.229 ++	struct file *f;
   1.230 ++
   1.231 ++	BUG_ON(!au_test_aufs(file->f_dentry->d_sb));
   1.232 ++	fi_read_lock(file);
   1.233 ++	f = au_hf_top(file);
   1.234 ++	fi_read_unlock(file);
   1.235 ++	AuDebugOn(!f);
   1.236 ++	return f;
   1.237 ++}
   1.238 +diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
   1.239 +index 6d9864d..3322557 100644
   1.240 +--- a/fs/aufs/loop.h
   1.241 ++++ b/fs/aufs/loop.h
   1.242 +@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
   1.243 + 
   1.244 + int au_loopback_init(void);
   1.245 + void au_loopback_fin(void);
   1.246 ++
   1.247 ++struct file *aufs_real_loop(struct file *file);
   1.248 + #else
   1.249 ++AuStub(struct file *, loop_backing_file, return NULL)
   1.250 ++
   1.251 + AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
   1.252 + 	   struct dentry *h_adding)
   1.253 + AuStubInt0(au_test_loopback_kthread, void)
   1.254 +@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
   1.255 + 
   1.256 + AuStubInt0(au_loopback_init, void)
   1.257 + AuStubVoid(au_loopback_fin, void)
   1.258 ++
   1.259 ++AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
   1.260 + #endif /* BLK_DEV_LOOP */
   1.261 + 
   1.262 + #endif /* __KERNEL__ */
   1.263 +diff --git a/fs/aufs/super.c b/fs/aufs/super.c
   1.264 +index 52ee100..bd545df 100644
   1.265 +--- a/fs/aufs/super.c
   1.266 ++++ b/fs/aufs/super.c
   1.267 +@@ -810,7 +810,10 @@ static const struct super_operations aufs_sop = {
   1.268 + 	.statfs		= aufs_statfs,
   1.269 + 	.put_super	= aufs_put_super,
   1.270 + 	.sync_fs	= aufs_sync_fs,
   1.271 +-	.remount_fs	= aufs_remount_fs
   1.272 ++	.remount_fs	= aufs_remount_fs,
   1.273 ++#ifdef CONFIG_AUFS_BDEV_LOOP
   1.274 ++	.real_loop	= aufs_real_loop
   1.275 ++#endif
   1.276 + };
   1.277 + 
   1.278 + /* ---------------------------------------------------------------------- */
   1.279 +diff --git a/include/linux/fs.h b/include/linux/fs.h
   1.280 +index 2f32b35..f94f0e6 100644
   1.281 +--- a/include/linux/fs.h
   1.282 ++++ b/include/linux/fs.h
   1.283 +@@ -1561,6 +1561,10 @@ struct super_operations {
   1.284 + 	int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
   1.285 + 	long (*nr_cached_objects)(struct super_block *, int);
   1.286 + 	long (*free_cached_objects)(struct super_block *, long, int);
   1.287 ++#if defined(CONFIG_BLK_DEV_LOOP) ||  defined(CONFIG_BLK_DEV_LOOP_MODULE)
   1.288 ++	/* and aufs */
   1.289 ++	struct file *(*real_loop)(struct file *);
   1.290 ++#endif
   1.291 + };
   1.292 + 
   1.293 + /*