]>
git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - fs/aufs/module.c
2 * Copyright (C) 2005-2016 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 * module global variables and operations
22 #include <linux/module.h>
23 #include <linux/seq_file.h>
26 /* shrinkable realloc */
27 void *au_krealloc(void *p
, unsigned int new_sz
, gfp_t gfp
, int may_shrink
)
45 diff
= au_kmidx_sub(sz
, new_sz
);
52 p
= krealloc(p
, new_sz
, gfp
);
53 else if (new_sz
< sz
&& may_shrink
) {
57 q
= kmalloc(new_sz
, gfp
);
72 void *au_kzrealloc(void *p
, unsigned int nused
, unsigned int new_sz
, gfp_t gfp
,
75 p
= au_krealloc(p
, new_sz
, gfp
, may_shrink
);
76 if (p
&& new_sz
> nused
)
77 memset(p
+ nused
, 0, new_sz
- nused
);
81 /* ---------------------------------------------------------------------- */
86 struct au_dfree au_dfree
;
89 static void au_do_dfree(struct work_struct
*work __maybe_unused
)
91 struct llist_head
*head
;
92 struct llist_node
*node
, *next
;
94 #define AU_CACHE_DFREE_DO_BODY(name, idx, lnode) do { \
95 head = &au_dfree.cache[AuCache_##idx].llist; \
96 node = llist_del_all(head); \
97 for (; node; node = next) { \
99 = llist_entry(node, struct au_##name, \
101 next = llist_next(node); \
102 au_cache_free_##name(p); \
106 AU_CACHE_DFREE_DO_BODY(dinfo
, DINFO
, di_lnode
);
107 AU_CACHE_DFREE_DO_BODY(icntnr
, ICNTNR
, lnode
);
108 AU_CACHE_DFREE_DO_BODY(finfo
, FINFO
, fi_lnode
);
109 AU_CACHE_DFREE_DO_BODY(vdir
, VDIR
, vd_lnode
);
110 AU_CACHE_DFREE_DO_BODY(vdir_dehstr
, DEHSTR
, lnode
);
111 #ifdef CONFIG_AUFS_HNOTIFY
112 AU_CACHE_DFREE_DO_BODY(hnotify
, HNOTIFY
, hn_lnode
);
115 #define AU_DFREE_DO_BODY(llist, func) do { \
116 node = llist_del_all(llist); \
117 for (; node; node = next) { \
118 next = llist_next(node); \
123 AU_DFREE_DO_BODY(au_dfree
.llist
+ AU_DFREE_KFREE
, kfree
);
124 AU_DFREE_DO_BODY(au_dfree
.llist
+ AU_DFREE_FREE_PAGE
, au_free_page
);
126 #undef AU_CACHE_DFREE_DO_BODY
127 #undef AU_DFREE_DO_BODY
130 AU_CACHE_DFREE_FUNC(dinfo
, DINFO
, di_lnode
);
131 AU_CACHE_DFREE_FUNC(icntnr
, ICNTNR
, lnode
);
132 AU_CACHE_DFREE_FUNC(finfo
, FINFO
, fi_lnode
);
133 AU_CACHE_DFREE_FUNC(vdir
, VDIR
, vd_lnode
);
134 AU_CACHE_DFREE_FUNC(vdir_dehstr
, DEHSTR
, lnode
);
136 static void au_cache_fin(void)
142 * Make sure all delayed rcu free inodes are flushed before we
147 /* excluding AuCache_HNOTIFY */
148 BUILD_BUG_ON(AuCache_HNOTIFY
+ 1 != AuCache_Last
);
149 flush_delayed_work(&au_dfree
.dwork
);
150 for (i
= 0; i
< AuCache_HNOTIFY
; i
++) {
151 cp
= au_dfree
.cache
+ i
;
152 AuDebugOn(!llist_empty(&cp
->llist
));
153 kmem_cache_destroy(cp
->cache
);
158 static int __init
au_cache_init(void)
163 cp
[AuCache_DINFO
].cache
= AuCacheCtor(au_dinfo
, au_di_init_once
);
164 if (cp
[AuCache_DINFO
].cache
)
165 /* SLAB_DESTROY_BY_RCU */
166 cp
[AuCache_ICNTNR
].cache
= AuCacheCtor(au_icntnr
,
167 au_icntnr_init_once
);
168 if (cp
[AuCache_ICNTNR
].cache
)
169 cp
[AuCache_FINFO
].cache
= AuCacheCtor(au_finfo
,
171 if (cp
[AuCache_FINFO
].cache
)
172 cp
[AuCache_VDIR
].cache
= AuCache(au_vdir
);
173 if (cp
[AuCache_VDIR
].cache
)
174 cp
[AuCache_DEHSTR
].cache
= AuCache(au_vdir_dehstr
);
175 if (cp
[AuCache_DEHSTR
].cache
)
182 /* ---------------------------------------------------------------------- */
186 #ifdef CONFIG_AUFS_SBILIST
188 * iterate_supers_type() doesn't protect us from
189 * remounting (branch management)
191 struct au_sphlhead au_sbilist
;
195 * functions for module interface.
197 MODULE_LICENSE("GPL");
198 /* MODULE_LICENSE("GPL v2"); */
199 MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
200 MODULE_DESCRIPTION(AUFS_NAME
201 " -- Advanced multi layered unification filesystem");
202 MODULE_VERSION(AUFS_VERSION
);
203 MODULE_ALIAS_FS(AUFS_NAME
);
205 /* this module parameter has no meaning when SYSFS is disabled */
207 MODULE_PARM_DESC(brs
, "use <sysfs>/fs/aufs/si_*/brN");
208 module_param_named(brs
, sysaufs_brs
, int, S_IRUGO
);
210 /* this module parameter has no meaning when USER_NS is disabled */
212 MODULE_PARM_DESC(allow_userns
, "allow unprivileged to mount under userns");
213 module_param_named(allow_userns
, au_userns
, bool, S_IRUGO
);
215 /* ---------------------------------------------------------------------- */
217 static char au_esc_chars
[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
219 int au_seq_path(struct seq_file
*seq
, struct path
*path
)
223 err
= seq_path(seq
, path
, au_esc_chars
);
232 /* ---------------------------------------------------------------------- */
234 static int __init
aufs_init(void)
241 for (i
= 1; i
<= ' '; i
++)
247 au_dir_roflags
= au_file_roflags(O_DIRECTORY
| O_LARGEFILE
);
249 memcpy(aufs_iop_nogetattr
, aufs_iop
, sizeof(aufs_iop
));
250 for (i
= 0; i
< AuIop_Last
; i
++)
251 aufs_iop_nogetattr
[i
].getattr
= NULL
;
253 /* First, initialize au_dfree */
254 for (i
= 0; i
< AuCache_Last
; i
++) { /* including hnotify */
255 cp
= au_dfree
.cache
+ i
;
257 init_llist_head(&cp
->llist
);
259 for (i
= 0; i
< AU_DFREE_Last
; i
++)
260 init_llist_head(au_dfree
.llist
+ i
);
261 INIT_DELAYED_WORK(&au_dfree
.dwork
, au_do_dfree
);
267 err
= sysaufs_init();
270 err
= au_procfs_init();
276 err
= au_loopback_init();
279 err
= au_hnotify_init();
282 err
= au_sysrq_init();
285 err
= au_cache_init();
289 aufs_fs_type
.fs_flags
|= au_userns
? FS_USERNS_MOUNT
: 0;
290 err
= register_filesystem(&aufs_fs_type
);
294 /* since we define pr_fmt, call printk directly */
295 printk(KERN_INFO AUFS_NAME
" " AUFS_VERSION
"\n");
296 goto out
; /* success */
313 flush_delayed_work(&au_dfree
.dwork
);
318 static void __exit
aufs_exit(void)
320 unregister_filesystem(&aufs_fs_type
);
329 flush_delayed_work(&au_dfree
.dwork
);
332 module_init(aufs_init
);
333 module_exit(aufs_exit
);