rev |
line source |
shann@25629
|
1 SPDX-License-Identifier: GPL-2.0
|
shann@25629
|
2 aufs4.19 loopback patch
|
shann@25629
|
3
|
shann@25629
|
4 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
|
shann@25629
|
5 index 9e534a36c5941..74cd74e6374b0 100644
|
shann@25629
|
6 --- a/drivers/block/loop.c
|
shann@25629
|
7 +++ b/drivers/block/loop.c
|
shann@25629
|
8 @@ -626,6 +626,15 @@ static inline void loop_update_dio(struct loop_device *lo)
|
shann@25629
|
9 lo->use_dio);
|
shann@25629
|
10 }
|
shann@25629
|
11
|
shann@25629
|
12 +static struct file *loop_real_file(struct file *file)
|
shann@25629
|
13 +{
|
shann@25629
|
14 + struct file *f = NULL;
|
shann@25629
|
15 +
|
shann@25629
|
16 + if (file->f_path.dentry->d_sb->s_op->real_loop)
|
shann@25629
|
17 + f = file->f_path.dentry->d_sb->s_op->real_loop(file);
|
shann@25629
|
18 + return f;
|
shann@25629
|
19 +}
|
shann@25629
|
20 +
|
shann@25629
|
21 static void loop_reread_partitions(struct loop_device *lo,
|
shann@25629
|
22 struct block_device *bdev)
|
shann@25629
|
23 {
|
shann@25629
|
24 @@ -690,6 +699,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
|
shann@25629
|
25 unsigned int arg)
|
shann@25629
|
26 {
|
shann@25629
|
27 struct file *file, *old_file;
|
shann@25629
|
28 + struct file *f, *virt_file = NULL, *old_virt_file;
|
shann@25629
|
29 int error;
|
shann@25629
|
30
|
shann@25629
|
31 error = -ENXIO;
|
shann@25629
|
32 @@ -705,12 +715,19 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
|
shann@25629
|
33 file = fget(arg);
|
shann@25629
|
34 if (!file)
|
shann@25629
|
35 goto out;
|
shann@25629
|
36 + f = loop_real_file(file);
|
shann@25629
|
37 + if (f) {
|
shann@25629
|
38 + virt_file = file;
|
shann@25629
|
39 + file = f;
|
shann@25629
|
40 + get_file(file);
|
shann@25629
|
41 + }
|
shann@25629
|
42
|
shann@25629
|
43 error = loop_validate_file(file, bdev);
|
shann@25629
|
44 if (error)
|
shann@25629
|
45 goto out_putf;
|
shann@25629
|
46
|
shann@25629
|
47 old_file = lo->lo_backing_file;
|
shann@25629
|
48 + old_virt_file = lo->lo_backing_virt_file;
|
shann@25629
|
49
|
shann@25629
|
50 error = -EINVAL;
|
shann@25629
|
51
|
shann@25629
|
52 @@ -722,6 +739,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
|
shann@25629
|
53 blk_mq_freeze_queue(lo->lo_queue);
|
shann@25629
|
54 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
|
shann@25629
|
55 lo->lo_backing_file = file;
|
shann@25629
|
56 + lo->lo_backing_virt_file = virt_file;
|
shann@25629
|
57 lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping);
|
shann@25629
|
58 mapping_set_gfp_mask(file->f_mapping,
|
shann@25629
|
59 lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
|
shann@25629
|
60 @@ -729,12 +747,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
|
shann@25629
|
61 blk_mq_unfreeze_queue(lo->lo_queue);
|
shann@25629
|
62
|
shann@25629
|
63 fput(old_file);
|
shann@25629
|
64 + if (old_virt_file)
|
shann@25629
|
65 + fput(old_virt_file);
|
shann@25629
|
66 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
|
shann@25629
|
67 loop_reread_partitions(lo, bdev);
|
shann@25629
|
68 return 0;
|
shann@25629
|
69
|
shann@25629
|
70 out_putf:
|
shann@25629
|
71 fput(file);
|
shann@25629
|
72 + if (virt_file)
|
shann@25629
|
73 + fput(virt_file);
|
shann@25629
|
74 out:
|
shann@25629
|
75 return error;
|
shann@25629
|
76 }
|
shann@25629
|
77 @@ -922,7 +944,7 @@ static int loop_prepare_queue(struct loop_device *lo)
|
shann@25629
|
78 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
shann@25629
|
79 struct block_device *bdev, unsigned int arg)
|
shann@25629
|
80 {
|
shann@25629
|
81 - struct file *file;
|
shann@25629
|
82 + struct file *file, *f, *virt_file = NULL;
|
shann@25629
|
83 struct inode *inode;
|
shann@25629
|
84 struct address_space *mapping;
|
shann@25629
|
85 int lo_flags = 0;
|
shann@25629
|
86 @@ -936,6 +958,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
shann@25629
|
87 file = fget(arg);
|
shann@25629
|
88 if (!file)
|
shann@25629
|
89 goto out;
|
shann@25629
|
90 + f = loop_real_file(file);
|
shann@25629
|
91 + if (f) {
|
shann@25629
|
92 + virt_file = file;
|
shann@25629
|
93 + file = f;
|
shann@25629
|
94 + get_file(file);
|
shann@25629
|
95 + }
|
shann@25629
|
96
|
shann@25629
|
97 error = -EBUSY;
|
shann@25629
|
98 if (lo->lo_state != Lo_unbound)
|
shann@25629
|
99 @@ -968,6 +996,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
shann@25629
|
100 lo->lo_device = bdev;
|
shann@25629
|
101 lo->lo_flags = lo_flags;
|
shann@25629
|
102 lo->lo_backing_file = file;
|
shann@25629
|
103 + lo->lo_backing_virt_file = virt_file;
|
shann@25629
|
104 lo->transfer = NULL;
|
shann@25629
|
105 lo->ioctl = NULL;
|
shann@25629
|
106 lo->lo_sizelimit = 0;
|
shann@25629
|
107 @@ -1001,6 +1030,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
shann@25629
|
108
|
shann@25629
|
109 out_putf:
|
shann@25629
|
110 fput(file);
|
shann@25629
|
111 + if (virt_file)
|
shann@25629
|
112 + fput(virt_file);
|
shann@25629
|
113 out:
|
shann@25629
|
114 /* This is safe: open() is still holding a reference. */
|
shann@25629
|
115 module_put(THIS_MODULE);
|
shann@25629
|
116 @@ -1047,6 +1078,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
|
shann@25629
|
117 static int loop_clr_fd(struct loop_device *lo)
|
shann@25629
|
118 {
|
shann@25629
|
119 struct file *filp = lo->lo_backing_file;
|
shann@25629
|
120 + struct file *virt_filp = lo->lo_backing_virt_file;
|
shann@25629
|
121 gfp_t gfp = lo->old_gfp_mask;
|
shann@25629
|
122 struct block_device *bdev = lo->lo_device;
|
shann@25629
|
123
|
shann@25629
|
124 @@ -1078,6 +1110,7 @@ static int loop_clr_fd(struct loop_device *lo)
|
shann@25629
|
125 spin_lock_irq(&lo->lo_lock);
|
shann@25629
|
126 lo->lo_state = Lo_rundown;
|
shann@25629
|
127 lo->lo_backing_file = NULL;
|
shann@25629
|
128 + lo->lo_backing_virt_file = NULL;
|
shann@25629
|
129 spin_unlock_irq(&lo->lo_lock);
|
shann@25629
|
130
|
shann@25629
|
131 loop_release_xfer(lo);
|
shann@25629
|
132 @@ -1126,6 +1159,8 @@ static int loop_clr_fd(struct loop_device *lo)
|
shann@25629
|
133 * bd_mutex which is usually taken before lo_ctl_mutex.
|
shann@25629
|
134 */
|
shann@25629
|
135 fput(filp);
|
shann@25629
|
136 + if (virt_filp)
|
shann@25629
|
137 + fput(virt_filp);
|
shann@25629
|
138 return 0;
|
shann@25629
|
139 }
|
shann@25629
|
140
|
shann@25629
|
141 diff --git a/drivers/block/loop.h b/drivers/block/loop.h
|
shann@25629
|
142 index 4d42c7af7de75..a15dd5bff5eae 100644
|
shann@25629
|
143 --- a/drivers/block/loop.h
|
shann@25629
|
144 +++ b/drivers/block/loop.h
|
shann@25629
|
145 @@ -46,7 +46,7 @@ struct loop_device {
|
shann@25629
|
146 int (*ioctl)(struct loop_device *, int cmd,
|
shann@25629
|
147 unsigned long arg);
|
shann@25629
|
148
|
shann@25629
|
149 - struct file * lo_backing_file;
|
shann@25629
|
150 + struct file *lo_backing_file, *lo_backing_virt_file;
|
shann@25629
|
151 struct block_device *lo_device;
|
shann@25629
|
152 void *key_data;
|
shann@25629
|
153
|
shann@25629
|
154 diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
|
shann@25629
|
155 index 6fb4a4ed8cc7f..ba9a959f2db27 100644
|
shann@25629
|
156 --- a/fs/aufs/f_op.c
|
shann@25629
|
157 +++ b/fs/aufs/f_op.c
|
shann@25629
|
158 @@ -359,7 +359,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
|
shann@25629
|
159 if (IS_ERR(h_file))
|
shann@25629
|
160 goto out;
|
shann@25629
|
161
|
shann@25629
|
162 - if (au_test_loopback_kthread()) {
|
shann@25629
|
163 + if (0 && au_test_loopback_kthread()) {
|
shann@25629
|
164 au_warn_loopback(h_file->f_path.dentry->d_sb);
|
shann@25629
|
165 if (file->f_mapping != h_file->f_mapping) {
|
shann@25629
|
166 file->f_mapping = h_file->f_mapping;
|
shann@25629
|
167 diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
|
shann@25629
|
168 index 50e80bd1d589d..d0f9777267f99 100644
|
shann@25629
|
169 --- a/fs/aufs/loop.c
|
shann@25629
|
170 +++ b/fs/aufs/loop.c
|
shann@25629
|
171 @@ -133,3 +133,19 @@ void au_loopback_fin(void)
|
shann@25629
|
172 symbol_put(loop_backing_file);
|
shann@25629
|
173 au_kfree_try_rcu(au_warn_loopback_array);
|
shann@25629
|
174 }
|
shann@25629
|
175 +
|
shann@25629
|
176 +/* ---------------------------------------------------------------------- */
|
shann@25629
|
177 +
|
shann@25629
|
178 +/* support the loopback block device insude aufs */
|
shann@25629
|
179 +
|
shann@25629
|
180 +struct file *aufs_real_loop(struct file *file)
|
shann@25629
|
181 +{
|
shann@25629
|
182 + struct file *f;
|
shann@25629
|
183 +
|
shann@25629
|
184 + BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
|
shann@25629
|
185 + fi_read_lock(file);
|
shann@25629
|
186 + f = au_hf_top(file);
|
shann@25629
|
187 + fi_read_unlock(file);
|
shann@25629
|
188 + AuDebugOn(!f);
|
shann@25629
|
189 + return f;
|
shann@25629
|
190 +}
|
shann@25629
|
191 diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
|
shann@25629
|
192 index 94f4f80ae33bf..ca1194354aff4 100644
|
shann@25629
|
193 --- a/fs/aufs/loop.h
|
shann@25629
|
194 +++ b/fs/aufs/loop.h
|
shann@25629
|
195 @@ -26,6 +26,8 @@ void au_warn_loopback(struct super_block *h_sb);
|
shann@25629
|
196
|
shann@25629
|
197 int au_loopback_init(void);
|
shann@25629
|
198 void au_loopback_fin(void);
|
shann@25629
|
199 +
|
shann@25629
|
200 +struct file *aufs_real_loop(struct file *file);
|
shann@25629
|
201 #else
|
shann@25629
|
202 AuStub(struct file *, loop_backing_file, return NULL, struct super_block *sb)
|
shann@25629
|
203
|
shann@25629
|
204 @@ -36,6 +38,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
|
shann@25629
|
205
|
shann@25629
|
206 AuStubInt0(au_loopback_init, void)
|
shann@25629
|
207 AuStubVoid(au_loopback_fin, void)
|
shann@25629
|
208 +
|
shann@25629
|
209 +AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
|
shann@25629
|
210 #endif /* BLK_DEV_LOOP */
|
shann@25629
|
211
|
shann@25629
|
212 #endif /* __KERNEL__ */
|
shann@25629
|
213 diff --git a/fs/aufs/super.c b/fs/aufs/super.c
|
shann@25629
|
214 index e3b81808a78a7..eff4f475de060 100644
|
shann@25629
|
215 --- a/fs/aufs/super.c
|
shann@25629
|
216 +++ b/fs/aufs/super.c
|
shann@25629
|
217 @@ -846,7 +846,10 @@ static const struct super_operations aufs_sop = {
|
shann@25629
|
218 .statfs = aufs_statfs,
|
shann@25629
|
219 .put_super = aufs_put_super,
|
shann@25629
|
220 .sync_fs = aufs_sync_fs,
|
shann@25629
|
221 - .remount_fs = aufs_remount_fs
|
shann@25629
|
222 + .remount_fs = aufs_remount_fs,
|
shann@25629
|
223 +#ifdef CONFIG_AUFS_BDEV_LOOP
|
shann@25629
|
224 + .real_loop = aufs_real_loop
|
shann@25629
|
225 +#endif
|
shann@25629
|
226 };
|
shann@25629
|
227
|
shann@25629
|
228 /* ---------------------------------------------------------------------- */
|
shann@25629
|
229 diff --git a/include/linux/fs.h b/include/linux/fs.h
|
shann@25629
|
230 index 41da4219febfe..72fe934fd55b0 100644
|
shann@25629
|
231 --- a/include/linux/fs.h
|
shann@25629
|
232 +++ b/include/linux/fs.h
|
shann@25629
|
233 @@ -1882,6 +1882,10 @@ struct super_operations {
|
shann@25629
|
234 struct shrink_control *);
|
shann@25629
|
235 long (*free_cached_objects)(struct super_block *,
|
shann@25629
|
236 struct shrink_control *);
|
shann@25629
|
237 +#if IS_ENABLED(CONFIG_BLK_DEV_LOOP) || IS_ENABLED(CONFIG_BLK_DEV_LOOP_MODULE)
|
shann@25629
|
238 + /* and aufs */
|
shann@25629
|
239 + struct file *(*real_loop)(struct file *);
|
shann@25629
|
240 +#endif
|
shann@25629
|
241 };
|
shann@25629
|
242
|
shann@25629
|
243 /*
|