]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/aufs/dentry.h
perf xyarray: Fix wrong processing when closing evsel fd
[mirror_ubuntu-artful-kernel.git] / fs / aufs / dentry.h
CommitLineData
b6450630
SF
1/*
2 * Copyright (C) 2005-2017 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 * lookup and dentry operations
20 */
21
22#ifndef __AUFS_DENTRY_H__
23#define __AUFS_DENTRY_H__
24
25#ifdef __KERNEL__
26
27#include <linux/dcache.h>
28#include "rwsem.h"
29
30struct au_hdentry {
31 struct dentry *hd_dentry;
32 aufs_bindex_t hd_id;
33};
34
35struct au_dinfo {
36 atomic_t di_generation;
37
38 struct au_rwsem di_rwsem;
39 aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq;
40 unsigned char di_tmpfile; /* to allow the different name */
41 struct au_hdentry *di_hdentry;
42} ____cacheline_aligned_in_smp;
43
44/* ---------------------------------------------------------------------- */
45
46/* flags for au_lkup_dentry() */
47#define AuLkup_ALLOW_NEG 1
48#define AuLkup_IGNORE_PERM (1 << 1)
49#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
50#define au_fset_lkup(flags, name) \
51 do { (flags) |= AuLkup_##name; } while (0)
52#define au_fclr_lkup(flags, name) \
53 do { (flags) &= ~AuLkup_##name; } while (0)
54
55/* ---------------------------------------------------------------------- */
56
57/* dentry.c */
58extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
59struct au_branch;
60struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
61int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
62 struct dentry *h_parent, struct au_branch *br);
63
64int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
65 unsigned int flags);
66int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
67int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
68int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
69void au_refresh_dop(struct dentry *dentry, int force_reval);
70
71/* dinfo.c */
72void au_di_init_once(void *_di);
73struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
74void au_di_free(struct au_dinfo *dinfo);
75void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
76void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
77int au_di_init(struct dentry *dentry);
78void au_di_fin(struct dentry *dentry);
79int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink);
80
81void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
82void di_read_unlock(struct dentry *d, int flags);
83void di_downgrade_lock(struct dentry *d, int flags);
84void di_write_lock(struct dentry *d, unsigned int lsc);
85void di_write_unlock(struct dentry *d);
86void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
87void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
88void di_write_unlock2(struct dentry *d1, struct dentry *d2);
89
90struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
91struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
92aufs_bindex_t au_dbtail(struct dentry *dentry);
93aufs_bindex_t au_dbtaildir(struct dentry *dentry);
94
95void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
96 struct dentry *h_dentry);
97int au_digen_test(struct dentry *dentry, unsigned int sigen);
98int au_dbrange_test(struct dentry *dentry);
99void au_update_digen(struct dentry *dentry);
100void au_update_dbrange(struct dentry *dentry, int do_put_zero);
101void au_update_dbtop(struct dentry *dentry);
102void au_update_dbbot(struct dentry *dentry);
103int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
104
105/* ---------------------------------------------------------------------- */
106
107static inline struct au_dinfo *au_di(struct dentry *dentry)
108{
109 return dentry->d_fsdata;
110}
111
112/* ---------------------------------------------------------------------- */
113
114/* lock subclass for dinfo */
115enum {
116 AuLsc_DI_CHILD, /* child first */
117 AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
118 AuLsc_DI_CHILD3, /* copyup dirs */
119 AuLsc_DI_PARENT,
120 AuLsc_DI_PARENT2,
121 AuLsc_DI_PARENT3,
122 AuLsc_DI_TMP /* temp for replacing dinfo */
123};
124
125/*
126 * di_read_lock_child, di_write_lock_child,
127 * di_read_lock_child2, di_write_lock_child2,
128 * di_read_lock_child3, di_write_lock_child3,
129 * di_read_lock_parent, di_write_lock_parent,
130 * di_read_lock_parent2, di_write_lock_parent2,
131 * di_read_lock_parent3, di_write_lock_parent3,
132 */
133#define AuReadLockFunc(name, lsc) \
134static inline void di_read_lock_##name(struct dentry *d, int flags) \
135{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
136
137#define AuWriteLockFunc(name, lsc) \
138static inline void di_write_lock_##name(struct dentry *d) \
139{ di_write_lock(d, AuLsc_DI_##lsc); }
140
141#define AuRWLockFuncs(name, lsc) \
142 AuReadLockFunc(name, lsc) \
143 AuWriteLockFunc(name, lsc)
144
145AuRWLockFuncs(child, CHILD);
146AuRWLockFuncs(child2, CHILD2);
147AuRWLockFuncs(child3, CHILD3);
148AuRWLockFuncs(parent, PARENT);
149AuRWLockFuncs(parent2, PARENT2);
150AuRWLockFuncs(parent3, PARENT3);
151
152#undef AuReadLockFunc
153#undef AuWriteLockFunc
154#undef AuRWLockFuncs
155
156#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
157#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
158#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
159
160/* ---------------------------------------------------------------------- */
161
162/* todo: memory barrier? */
163static inline unsigned int au_digen(struct dentry *d)
164{
165 return atomic_read(&au_di(d)->di_generation);
166}
167
168static inline void au_h_dentry_init(struct au_hdentry *hdentry)
169{
170 hdentry->hd_dentry = NULL;
171}
172
173static inline struct au_hdentry *au_hdentry(struct au_dinfo *di,
174 aufs_bindex_t bindex)
175{
176 return di->di_hdentry + bindex;
177}
178
179static inline void au_hdput(struct au_hdentry *hd)
180{
181 if (hd)
182 dput(hd->hd_dentry);
183}
184
185static inline aufs_bindex_t au_dbtop(struct dentry *dentry)
186{
187 DiMustAnyLock(dentry);
188 return au_di(dentry)->di_btop;
189}
190
191static inline aufs_bindex_t au_dbbot(struct dentry *dentry)
192{
193 DiMustAnyLock(dentry);
194 return au_di(dentry)->di_bbot;
195}
196
197static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
198{
199 DiMustAnyLock(dentry);
200 return au_di(dentry)->di_bwh;
201}
202
203static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
204{
205 DiMustAnyLock(dentry);
206 return au_di(dentry)->di_bdiropq;
207}
208
209/* todo: hard/soft set? */
210static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex)
211{
212 DiMustWriteLock(dentry);
213 au_di(dentry)->di_btop = bindex;
214}
215
216static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex)
217{
218 DiMustWriteLock(dentry);
219 au_di(dentry)->di_bbot = bindex;
220}
221
222static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
223{
224 DiMustWriteLock(dentry);
225 /* dbwh can be outside of btop - bbot range */
226 au_di(dentry)->di_bwh = bindex;
227}
228
229static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
230{
231 DiMustWriteLock(dentry);
232 au_di(dentry)->di_bdiropq = bindex;
233}
234
235/* ---------------------------------------------------------------------- */
236
237#ifdef CONFIG_AUFS_HNOTIFY
238static inline void au_digen_dec(struct dentry *d)
239{
240 atomic_dec(&au_di(d)->di_generation);
241}
242
243static inline void au_hn_di_reinit(struct dentry *dentry)
244{
245 dentry->d_fsdata = NULL;
246}
247#else
248AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
249#endif /* CONFIG_AUFS_HNOTIFY */
250
251#endif /* __KERNEL__ */
252#endif /* __AUFS_DENTRY_H__ */