]>
git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - fs/aufs/loop.c
52c441cb30669f003408c3b6eb32ee76dd6c4692
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2005-2019 Junjiro R. Okajima
5 * This program, aufs is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * support for loopback block device as a branch
25 /* added into drivers/block/loop.c */
26 static struct file
*(*backing_file_func
)(struct super_block
*sb
);
29 * test if two lower dentries have overlapping branches.
31 int au_test_loopback_overlap(struct super_block
*sb
, struct dentry
*h_adding
)
33 struct super_block
*h_sb
;
34 struct file
*backing_file
;
36 if (unlikely(!backing_file_func
)) {
37 /* don't load "loop" module here */
38 backing_file_func
= symbol_get(loop_backing_file
);
39 if (unlikely(!backing_file_func
))
40 /* "loop" module is not loaded */
44 h_sb
= h_adding
->d_sb
;
45 backing_file
= backing_file_func(h_sb
);
49 h_adding
= backing_file
->f_path
.dentry
;
51 * h_adding can be local NFS.
52 * in this case aufs cannot detect the loop.
54 if (unlikely(h_adding
->d_sb
== sb
))
56 return !!au_test_subdir(h_adding
, sb
->s_root
);
59 /* true if a kernel thread named 'loop[0-9].*' accesses a file */
60 int au_test_loopback_kthread(void)
63 struct task_struct
*tsk
= current
;
64 char c
, comm
[sizeof(tsk
->comm
)];
67 if (tsk
->flags
& PF_KTHREAD
) {
68 get_task_comm(comm
, tsk
);
70 ret
= ('0' <= c
&& c
<= '9'
71 && !strncmp(comm
, "loop", 4));
77 /* ---------------------------------------------------------------------- */
79 #define au_warn_loopback_step 16
80 static int au_warn_loopback_nelem
= au_warn_loopback_step
;
81 static unsigned long *au_warn_loopback_array
;
83 void au_warn_loopback(struct super_block
*h_sb
)
86 unsigned long *a
, magic
;
87 static DEFINE_SPINLOCK(spin
);
89 magic
= h_sb
->s_magic
;
91 a
= au_warn_loopback_array
;
92 for (i
= 0; i
< au_warn_loopback_nelem
&& *a
; i
++)
98 /* h_sb is new to us, print it */
99 if (i
< au_warn_loopback_nelem
) {
104 /* expand the array */
105 new_nelem
= au_warn_loopback_nelem
+ au_warn_loopback_step
;
106 a
= au_kzrealloc(au_warn_loopback_array
,
107 au_warn_loopback_nelem
* sizeof(unsigned long),
108 new_nelem
* sizeof(unsigned long), GFP_ATOMIC
,
111 au_warn_loopback_nelem
= new_nelem
;
112 au_warn_loopback_array
= a
;
118 AuWarn1("realloc failed, ignored\n");
123 pr_warn("you may want to try another patch for loopback file "
124 "on %s(0x%lx) branch\n", au_sbtype(h_sb
), magic
);
127 int au_loopback_init(void)
130 struct super_block
*sb __maybe_unused
;
132 BUILD_BUG_ON(sizeof(sb
->s_magic
) != sizeof(*au_warn_loopback_array
));
135 au_warn_loopback_array
= kcalloc(au_warn_loopback_step
,
136 sizeof(unsigned long), GFP_NOFS
);
137 if (unlikely(!au_warn_loopback_array
))
143 void au_loopback_fin(void)
145 if (backing_file_func
)
146 symbol_put(loop_backing_file
);
147 au_kfree_try_rcu(au_warn_loopback_array
);
150 /* ---------------------------------------------------------------------- */
152 /* support the loopback block device insude aufs */
154 struct file
*aufs_real_loop(struct file
*file
)
158 BUG_ON(!au_test_aufs(file
->f_path
.dentry
->d_sb
));
161 fi_read_unlock(file
);