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