aufs4-loopback.patch 7.0 KB

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