]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - fs/aufs/module.h
UBUNTU: SAUCE: aufs: bugfix, for v4.10, copy-up on XFS branch
[mirror_ubuntu-zesty-kernel.git] / fs / aufs / module.h
CommitLineData
e14748e8
SF
1/*
2 * Copyright (C) 2005-2016 Junjiro R. Okajima
3 *
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.
8 *
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.
13 *
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/>.
16 */
17
18/*
19 * module initialization and module-global
20 */
21
22#ifndef __AUFS_MODULE_H__
23#define __AUFS_MODULE_H__
24
25#ifdef __KERNEL__
26
27#include <linux/slab.h>
28#include "debug.h"
29
30struct path;
31struct seq_file;
32
33/* module parameters */
34extern int sysaufs_brs;
35extern bool au_userns;
36
37/* ---------------------------------------------------------------------- */
38
39extern int au_dir_roflags;
40
41void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink);
42void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
43 int may_shrink);
44
45static inline int au_kmidx_sub(size_t sz, size_t new_sz)
46{
47#ifndef CONFIG_SLOB
48 return kmalloc_index(sz) - kmalloc_index(new_sz);
49#else
50 return -1; /* SLOB is untested */
51#endif
52}
53
54int au_seq_path(struct seq_file *seq, struct path *path);
55
56#ifdef CONFIG_PROC_FS
57/* procfs.c */
58int __init au_procfs_init(void);
59void au_procfs_fin(void);
60#else
61AuStubInt0(au_procfs_init, void);
62AuStubVoid(au_procfs_fin, void);
63#endif
64
65/* ---------------------------------------------------------------------- */
66
67/* kmem cache and delayed free */
68enum {
69 AuCache_DINFO,
70 AuCache_ICNTNR,
71 AuCache_FINFO,
72 AuCache_VDIR,
73 AuCache_DEHSTR,
74 AuCache_HNOTIFY, /* must be last */
75 AuCache_Last
76};
77
78enum {
79 AU_DFREE_KFREE,
80 AU_DFREE_FREE_PAGE,
81 AU_DFREE_Last
82};
83
84struct au_cache {
85 struct kmem_cache *cache;
86 struct llist_head llist; /* delayed free */
87};
88
89/*
90 * in order to reduce the cost of the internal timer, consolidate all the
91 * delayed free works into a single delayed_work.
92 */
93struct au_dfree {
94 struct au_cache cache[AuCache_Last];
95 struct llist_head llist[AU_DFREE_Last];
96 struct delayed_work dwork;
97};
98
99extern struct au_dfree au_dfree;
100
101#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
102#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
103#define AuCacheCtor(type, ctor) \
104 kmem_cache_create(#type, sizeof(struct type), \
105 __alignof__(struct type), AuCacheFlags, ctor)
106
107#define AU_DFREE_DELAY msecs_to_jiffies(10)
108#define AU_DFREE_BODY(lnode, llist) do { \
109 if (llist_add(lnode, llist)) \
110 schedule_delayed_work(&au_dfree.dwork, \
111 AU_DFREE_DELAY); \
112 } while (0)
113#define AU_CACHE_DFREE_FUNC(name, idx, lnode) \
114 void au_cache_dfree_##name(struct au_##name *p) \
115 { \
116 struct au_cache *cp = au_dfree.cache + AuCache_##idx; \
117 AU_DFREE_BODY(&p->lnode, &cp->llist); \
118 }
119
120#define AuCacheFuncs(name, index) \
121static inline struct au_##name *au_cache_alloc_##name(void) \
122{ return kmem_cache_alloc(au_dfree.cache[AuCache_##index].cache, GFP_NOFS); } \
123static inline void au_cache_free_##name(struct au_##name *p) \
124{ kmem_cache_free(au_dfree.cache[AuCache_##index].cache, p); } \
125void au_cache_dfree_##name(struct au_##name *p)
126
127AuCacheFuncs(dinfo, DINFO);
128AuCacheFuncs(icntnr, ICNTNR);
129AuCacheFuncs(finfo, FINFO);
130AuCacheFuncs(vdir, VDIR);
131AuCacheFuncs(vdir_dehstr, DEHSTR);
132#ifdef CONFIG_AUFS_HNOTIFY
133AuCacheFuncs(hnotify, HNOTIFY);
134#endif
135
136static inline void au_delayed_kfree(const void *p)
137{
138 AuDebugOn(!p);
139 AuDebugOn(ksize(p) < sizeof(struct llist_node));
140
141 AU_DFREE_BODY((void *)p, au_dfree.llist + AU_DFREE_KFREE);
142}
143
144/* cast only */
145static inline void au_free_page(void *p)
146{
147 free_page((unsigned long)p);
148}
149
150static inline void au_delayed_free_page(unsigned long addr)
151{
152 AU_DFREE_BODY((void *)addr, au_dfree.llist + AU_DFREE_FREE_PAGE);
153}
154
155#endif /* __KERNEL__ */
156#endif /* __AUFS_MODULE_H__ */