wok view linux/stuff/aufs3-loopback.patch @ rev 15743

linux: update modules.list
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Jan 02 15:04:05 2014 +0100 (2014-01-02)
parents f4df390821bc
children
line source
1 aufs3.2 loopback patch
3 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
4 index 1e888c9..17b3109 100644
5 --- a/drivers/block/loop.c
6 +++ b/drivers/block/loop.c
7 @@ -499,7 +499,7 @@ out:
8 }
10 struct switch_request {
11 - struct file *file;
12 + struct file *file, *virt_file;
13 struct completion wait;
14 };
16 @@ -559,7 +559,8 @@ static int loop_thread(void *data)
17 * First it needs to flush existing IO, it does this by sending a magic
18 * BIO down the pipe. The completion of this BIO does the actual switch.
19 */
20 -static int loop_switch(struct loop_device *lo, struct file *file)
21 +static int loop_switch(struct loop_device *lo, struct file *file,
22 + struct file *virt_file)
23 {
24 struct switch_request w;
25 struct bio *bio = bio_alloc(GFP_KERNEL, 0);
26 @@ -567,6 +568,7 @@ static int loop_switch(struct loop_device *lo, struct file *file)
27 return -ENOMEM;
28 init_completion(&w.wait);
29 w.file = file;
30 + w.virt_file = virt_file;
31 bio->bi_private = &w;
32 bio->bi_bdev = NULL;
33 loop_make_request(lo->lo_queue, bio);
34 @@ -583,7 +585,7 @@ static int loop_flush(struct loop_device *lo)
35 if (!lo->lo_thread)
36 return 0;
38 - return loop_switch(lo, NULL);
39 + return loop_switch(lo, NULL, NULL);
40 }
42 /*
43 @@ -602,6 +604,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
44 mapping = file->f_mapping;
45 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
46 lo->lo_backing_file = file;
47 + lo->lo_backing_virt_file = p->virt_file;
48 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
49 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
50 lo->old_gfp_mask = mapping_gfp_mask(mapping);
51 @@ -610,6 +613,13 @@ out:
52 complete(&p->wait);
53 }
55 +static struct file *loop_real_file(struct file *file)
56 +{
57 + struct file *f = NULL;
58 + if (file->f_dentry->d_sb->s_op->real_loop)
59 + f = file->f_dentry->d_sb->s_op->real_loop(file);
60 + return f;
61 +}
63 /*
64 * loop_change_fd switched the backing store of a loopback device to
65 @@ -623,6 +633,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
66 unsigned int arg)
67 {
68 struct file *file, *old_file;
69 + struct file *f, *virt_file = NULL, *old_virt_file;
70 struct inode *inode;
71 int error;
73 @@ -639,9 +650,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
74 file = fget(arg);
75 if (!file)
76 goto out;
77 + f = loop_real_file(file);
78 + if (f) {
79 + virt_file = file;
80 + file = f;
81 + get_file(file);
82 + }
84 inode = file->f_mapping->host;
85 old_file = lo->lo_backing_file;
86 + old_virt_file = lo->lo_backing_virt_file;
88 error = -EINVAL;
90 @@ -653,17 +671,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
91 goto out_putf;
93 /* and ... switch */
94 - error = loop_switch(lo, file);
95 + error = loop_switch(lo, file, virt_file);
96 if (error)
97 goto out_putf;
99 fput(old_file);
100 + if (old_virt_file)
101 + fput(old_virt_file);
102 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
103 ioctl_by_bdev(bdev, BLKRRPART, 0);
104 return 0;
106 out_putf:
107 fput(file);
108 + if (virt_file)
109 + fput(virt_file);
110 out:
111 return error;
112 }
113 @@ -806,7 +828,7 @@ static void loop_config_discard(struct loop_device *lo)
114 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
115 struct block_device *bdev, unsigned int arg)
116 {
117 - struct file *file, *f;
118 + struct file *file, *f, *virt_file = NULL;
119 struct inode *inode;
120 struct address_space *mapping;
121 unsigned lo_blocksize;
122 @@ -821,6 +843,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
123 file = fget(arg);
124 if (!file)
125 goto out;
126 + f = loop_real_file(file);
127 + if (f) {
128 + virt_file = file;
129 + file = f;
130 + get_file(file);
131 + }
133 error = -EBUSY;
134 if (lo->lo_state != Lo_unbound)
135 @@ -869,6 +897,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
136 lo->lo_device = bdev;
137 lo->lo_flags = lo_flags;
138 lo->lo_backing_file = file;
139 + lo->lo_backing_virt_file = virt_file;
140 lo->transfer = transfer_none;
141 lo->ioctl = NULL;
142 lo->lo_sizelimit = 0;
143 @@ -919,6 +948,7 @@ out_clr:
144 lo->lo_thread = NULL;
145 lo->lo_device = NULL;
146 lo->lo_backing_file = NULL;
147 + lo->lo_backing_virt_file = NULL;
148 lo->lo_flags = 0;
149 set_capacity(lo->lo_disk, 0);
150 invalidate_bdev(bdev);
151 @@ -928,6 +958,8 @@ out_clr:
152 lo->lo_state = Lo_unbound;
153 out_putf:
154 fput(file);
155 + if (virt_file)
156 + fput(virt_file);
157 out:
158 /* This is safe: open() is still holding a reference. */
159 module_put(THIS_MODULE);
160 @@ -974,6 +1006,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
161 static int loop_clr_fd(struct loop_device *lo)
162 {
163 struct file *filp = lo->lo_backing_file;
164 + struct file *virt_filp = lo->lo_backing_virt_file;
165 gfp_t gfp = lo->old_gfp_mask;
166 struct block_device *bdev = lo->lo_device;
168 @@ -994,6 +1027,7 @@ static int loop_clr_fd(struct loop_device *lo)
170 spin_lock_irq(&lo->lo_lock);
171 lo->lo_backing_file = NULL;
172 + lo->lo_backing_virt_file = NULL;
173 spin_unlock_irq(&lo->lo_lock);
175 loop_release_xfer(lo);
176 @@ -1036,6 +1070,8 @@ static int loop_clr_fd(struct loop_device *lo)
177 * bd_mutex which is usually taken before lo_ctl_mutex.
178 */
179 fput(filp);
180 + if (virt_filp)
181 + fput(virt_filp);
182 return 0;
183 }
185 diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
186 index d6318f08b..56555de 100644
187 --- a/fs/aufs/f_op.c
188 +++ b/fs/aufs/f_op.c
189 @@ -355,7 +355,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
190 err = -EINVAL;
191 h_file = au_hf_top(file);
192 get_file(h_file);
193 - if (au_test_loopback_kthread()) {
194 + if (0 && au_test_loopback_kthread()) {
195 au_warn_loopback(h_file->f_dentry->d_sb);
196 if (file->f_mapping != h_file->f_mapping) {
197 file->f_mapping = h_file->f_mapping;
198 diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
199 index ccae19c..15dc5c2 100644
200 --- a/fs/aufs/loop.c
201 +++ b/fs/aufs/loop.c
202 @@ -133,3 +133,19 @@ void au_loopback_fin(void)
203 {
204 kfree(au_warn_loopback_array);
205 }
206 +
207 +/* ---------------------------------------------------------------------- */
208 +
209 +/* support the loopback block device insude aufs */
210 +
211 +struct file *aufs_real_loop(struct file *file)
212 +{
213 + struct file *f;
214 +
215 + BUG_ON(!au_test_aufs(file->f_dentry->d_sb));
216 + fi_read_lock(file);
217 + f = au_hf_top(file);
218 + fi_read_unlock(file);
219 + AuDebugOn(!f);
220 + return f;
221 +}
222 diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
223 index 88d019c..8707c3a 100644
224 --- a/fs/aufs/loop.h
225 +++ b/fs/aufs/loop.h
226 @@ -36,6 +36,8 @@ void au_warn_loopback(struct super_block *h_sb);
228 int au_loopback_init(void);
229 void au_loopback_fin(void);
230 +
231 +struct file *aufs_real_loop(struct file *file);
232 #else
233 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
234 struct dentry *h_adding)
235 @@ -44,6 +46,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
237 AuStubInt0(au_loopback_init, void)
238 AuStubVoid(au_loopback_fin, void)
239 +
240 +AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
241 #endif /* BLK_DEV_LOOP */
243 #endif /* __KERNEL__ */
244 diff --git a/fs/aufs/super.c b/fs/aufs/super.c
245 index d105672..304f2e5 100644
246 --- a/fs/aufs/super.c
247 +++ b/fs/aufs/super.c
248 @@ -823,7 +823,10 @@ static const struct super_operations aufs_sop = {
249 .statfs = aufs_statfs,
250 .put_super = aufs_put_super,
251 .sync_fs = aufs_sync_fs,
252 - .remount_fs = aufs_remount_fs
253 + .remount_fs = aufs_remount_fs,
254 +#ifdef CONFIG_AUFS_BDEV_LOOP
255 + .real_loop = aufs_real_loop
256 +#endif
257 };
259 /* ---------------------------------------------------------------------- */
260 diff --git a/include/linux/fs.h b/include/linux/fs.h
261 index e0bc4ff..bd7b3a4 100644
262 --- a/include/linux/fs.h
263 +++ b/include/linux/fs.h
264 @@ -1699,6 +1699,10 @@ struct super_operations {
265 int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
266 int (*nr_cached_objects)(struct super_block *);
267 void (*free_cached_objects)(struct super_block *, int);
268 +#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
269 + /* and aufs */
270 + struct file *(*real_loop)(struct file *);
271 +#endif
272 };
274 /*
275 diff --git a/include/linux/loop.h b/include/linux/loop.h
276 index 11a41a8..c190b78 100644
277 --- a/include/linux/loop.h
278 +++ b/include/linux/loop.h
279 @@ -48,7 +48,7 @@ struct loop_device {
280 int (*ioctl)(struct loop_device *, int cmd,
281 unsigned long arg);
283 - struct file * lo_backing_file;
284 + struct file * lo_backing_file, *lo_backing_virt_file;
285 struct block_device *lo_device;
286 unsigned lo_blocksize;
287 void *key_data;