wok-6.x diff linux/stuff/aufs3-loopback.patch @ rev 24640
updated help2man (1.47.12 -> 1.49.1)
author | Hans-G?nter Theisgen |
---|---|
date | Wed Mar 09 15:53:44 2022 +0100 (2022-03-09) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/linux/stuff/aufs3-loopback.patch Wed Mar 09 15:53:44 2022 +0100 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 + /*