]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - fs/aufs/loop.c
2 * Copyright (C) 2005-2017 Junjiro R. Okajima
4 * This program, aufs is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * support for loopback block device as a branch
24 /* added into drivers/block/loop.c */
25 static struct file
*(*backing_file_func
)(struct super_block
*sb
);
28 * test if two lower dentries have overlapping branches.
30 int au_test_loopback_overlap(struct super_block
*sb
, struct dentry
*h_adding
)
32 struct super_block
*h_sb
;
33 struct file
*backing_file
;
35 if (unlikely(!backing_file_func
)) {
36 /* don't load "loop" module here */
37 backing_file_func
= symbol_get(loop_backing_file
);
38 if (unlikely(!backing_file_func
))
39 /* "loop" module is not loaded */
43 h_sb
= h_adding
->d_sb
;
44 backing_file
= backing_file_func(h_sb
);
48 h_adding
= backing_file
->f_path
.dentry
;
50 * h_adding can be local NFS.
51 * in this case aufs cannot detect the loop.
53 if (unlikely(h_adding
->d_sb
== sb
))
55 return !!au_test_subdir(h_adding
, sb
->s_root
);
58 /* true if a kernel thread named 'loop[0-9].*' accesses a file */
59 int au_test_loopback_kthread(void)
62 struct task_struct
*tsk
= current
;
63 char c
, comm
[sizeof(tsk
->comm
)];
66 if (tsk
->flags
& PF_KTHREAD
) {
67 get_task_comm(comm
, tsk
);
69 ret
= ('0' <= c
&& c
<= '9'
70 && !strncmp(comm
, "loop", 4));
76 /* ---------------------------------------------------------------------- */
78 #define au_warn_loopback_step 16
79 static int au_warn_loopback_nelem
= au_warn_loopback_step
;
80 static unsigned long *au_warn_loopback_array
;
82 void au_warn_loopback(struct super_block
*h_sb
)
85 unsigned long *a
, magic
;
86 static DEFINE_SPINLOCK(spin
);
88 magic
= h_sb
->s_magic
;
90 a
= au_warn_loopback_array
;
91 for (i
= 0; i
< au_warn_loopback_nelem
&& *a
; i
++)
97 /* h_sb is new to us, print it */
98 if (i
< au_warn_loopback_nelem
) {
103 /* expand the array */
104 new_nelem
= au_warn_loopback_nelem
+ au_warn_loopback_step
;
105 a
= au_kzrealloc(au_warn_loopback_array
,
106 au_warn_loopback_nelem
* sizeof(unsigned long),
107 new_nelem
* sizeof(unsigned long), GFP_ATOMIC
,
110 au_warn_loopback_nelem
= new_nelem
;
111 au_warn_loopback_array
= a
;
117 AuWarn1("realloc failed, ignored\n");
122 pr_warn("you may want to try another patch for loopback file "
123 "on %s(0x%lx) branch\n", au_sbtype(h_sb
), magic
);
126 int au_loopback_init(void)
129 struct super_block
*sb __maybe_unused
;
131 BUILD_BUG_ON(sizeof(sb
->s_magic
) != sizeof(unsigned long));
134 au_warn_loopback_array
= kcalloc(au_warn_loopback_step
,
135 sizeof(unsigned long), GFP_NOFS
);
136 if (unlikely(!au_warn_loopback_array
))
142 void au_loopback_fin(void)
144 if (backing_file_func
)
145 symbol_put(loop_backing_file
);
146 kfree(au_warn_loopback_array
);
149 /* ---------------------------------------------------------------------- */
151 /* support the loopback block device insude aufs */
153 struct file
*aufs_real_loop(struct file
*file
)
157 BUG_ON(!au_test_aufs(file
->f_path
.dentry
->d_sb
));
160 fi_read_unlock(file
);