2
* Copyright (C) 2005-2008 Junjiro 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, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
* lookup and dentry operations
22
* $Id: dentry.h,v 1.4 2008/05/04 23:54:53 sfjro Exp $
25
#ifndef __AUFS_DENTRY_H__
26
#define __AUFS_DENTRY_H__
31
#include <linux/namei.h>
32
#include <linux/aufs_type.h>
37
/* nameidata open_intent */
45
struct list_head hdi_list;
46
struct file *hdi_file[AuIntent_Last];
50
struct dentry *hd_dentry;
52
#ifdef CONFIG_AUFS_BR_NFS
53
spinlock_t hd_lock; /* intest_list */
54
struct list_head *hd_intent_list;
59
atomic_t di_generation;
61
struct au_rwsem di_rwsem;
62
aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
63
struct au_hdentry *di_hdentry;
66
/* nameidata extension flags */
68
#define AuNdx_DIRPERM1 (1 << 1)
69
#define au_ftest_ndx(flags, name) ((flags) & AuNdx_##name)
70
#define au_fset_ndx(flags, name) { (flags) |= AuNdx_##name; }
71
#define au_fclr_ndx(flags, name) { (flags) &= ~AuNdx_##name; }
72
#ifndef CONFIG_AUFS_DLGT
76
#define AuNdx_DIRPERM1 0
80
struct vfsmount *nfsmnt;
87
/* ---------------------------------------------------------------------- */
89
static inline void au_do_h_dentry_init(struct au_hdentry *hdentry)
91
hdentry->hd_dentry = NULL;
94
#ifdef CONFIG_AUFS_BR_NFS
95
static inline void au_h_dentry_init(struct au_hdentry *hdentry)
97
au_do_h_dentry_init(hdentry);
98
spin_lock_init(&hdentry->hd_lock);
101
static inline void au_h_dentry_init_all(struct au_hdentry *hdentry, int n)
104
spin_lock_init(&hdentry[n].hd_lock);
108
struct file *au_h_intent(struct dentry *dentry, aufs_bindex_t bindex,
110
int au_br_nfs_h_intent(struct file *nd_file, struct dentry *dentry,
111
aufs_bindex_t bindex, struct nameidata *nd);
112
void au_hintent_put(struct au_hdentry *hd, int do_free);
113
int au_fake_intent(struct nameidata *nd, int perm);
114
int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry,
115
aufs_bindex_t bindex, struct file *file);
116
struct dentry *au_lkup_hash(const char *name, struct dentry *parent, int len,
120
static inline void au_h_dentry_init(struct au_hdentry *hdentry)
122
au_do_h_dentry_init(hdentry);
125
static inline void au_h_dentry_init_all(struct au_hdentry *hdentry, int n)
131
struct file *au_h_intent(struct dentry *dentry, aufs_bindex_t bindex,
134
//return ERR_PTR(-ENOSYS);
139
int au_br_nfs_h_intent(struct file *nd_file, struct dentry *dentry,
140
aufs_bindex_t bindex, struct nameidata *nd)
145
static inline void au_hintent_put(struct au_hdentry *hd, int do_free)
150
static inline int au_fake_intent(struct nameidata *nd, int perm)
156
int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry,
157
aufs_bindex_t bindex, struct file *file)
162
#ifdef CONFIG_AUFS_DLGT
164
struct dentry *au_lkup_hash(const char *name, struct dentry *parent, int len,
167
//return ERR_PTR(-ENOSYS);
168
return vfsub_lookup_one_len(name, parent, len);
171
#endif /* CONFIG_AUFS_BR_NFS */
173
#ifdef CONFIG_AUFS_DLGT
175
struct dentry *au_lkup_one_dlgt(const char *name, struct dentry *parent,
176
int len, unsigned int flags);
177
#elif defined(CONFIG_AUFS_BR_NFS)
178
/* regardelss kernel version */
180
struct dentry *au_lkup_one_dlgt(const char *name, struct dentry *parent,
181
int len, unsigned int flags)
183
return vfsub_lookup_one_len(name, parent, len);
188
extern struct dentry_operations aufs_dop;
189
#if defined(CONFIG_AUFS_BR_NFS) || defined(CONFIG_AUFS_DLGT)
190
struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len,
194
struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len,
197
//todo: ndx->nd_file = NULL;
198
return vfsub_lookup_one_len(name, parent, len);
201
struct dentry *au_sio_lkup_one(const char *name, struct dentry *parent, int len,
203
int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
204
struct nameidata *nd);
205
int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex);
206
int au_refresh_hdentry(struct dentry *dentry, mode_t type);
207
int au_reval_dpath(struct dentry *dentry, au_gen_t sgen);
210
int au_alloc_dinfo(struct dentry *dentry);
211
struct au_dinfo *au_di(struct dentry *dentry);
213
void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
214
void di_read_unlock(struct dentry *d, int flags);
215
void di_downgrade_lock(struct dentry *d, int flags);
216
void di_write_lock(struct dentry *d, unsigned int lsc);
217
void di_write_unlock(struct dentry *d);
218
void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
219
void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
220
void di_write_unlock2(struct dentry *d1, struct dentry *d2);
222
struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
224
aufs_bindex_t au_dbtail(struct dentry *dentry);
225
aufs_bindex_t au_dbtaildir(struct dentry *dentry);
227
aufs_bindex_t au_dbtail_generic(struct dentry *dentry);
230
void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex);
231
void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
232
struct dentry *h_dentry);
234
void au_update_dbrange(struct dentry *dentry, int do_put_zero);
235
void au_update_dbstart(struct dentry *dentry);
236
void au_update_dbend(struct dentry *dentry);
237
int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
239
/* ---------------------------------------------------------------------- */
241
//todo: memory barrier?
242
static inline au_gen_t au_digen(struct dentry *d)
244
return atomic_read(&au_di(d)->di_generation);
247
#ifdef CONFIG_AUFS_HINOTIFY
248
static inline au_gen_t au_digen_dec(struct dentry *d)
250
return atomic_dec_return(&au_di(d)->di_generation);
252
#endif /* CONFIG_AUFS_HINOTIFY */
254
/* ---------------------------------------------------------------------- */
256
/* lock subclass for dinfo */
258
AuLsc_DI_CHILD, /* child first */
259
AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hinotify */
260
AuLsc_DI_CHILD3, /* copyup dirs */
267
* di_read_lock_child, di_write_lock_child,
268
* di_read_lock_child2, di_write_lock_child2,
269
* di_read_lock_child3, di_write_lock_child3,
270
* di_read_lock_parent, di_write_lock_parent,
271
* di_read_lock_parent2, di_write_lock_parent2,
272
* di_read_lock_parent3, di_write_lock_parent3,
274
#define AuReadLockFunc(name, lsc) \
275
static inline void di_read_lock_##name(struct dentry *d, int flags) \
276
{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
278
#define AuWriteLockFunc(name, lsc) \
279
static inline void di_write_lock_##name(struct dentry *d) \
280
{ di_write_lock(d, AuLsc_DI_##lsc); }
282
#define AuRWLockFuncs(name, lsc) \
283
AuReadLockFunc(name, lsc) \
284
AuWriteLockFunc(name, lsc)
286
AuRWLockFuncs(child, CHILD);
287
AuRWLockFuncs(child2, CHILD2);
288
AuRWLockFuncs(child3, CHILD3);
289
AuRWLockFuncs(parent, PARENT);
290
AuRWLockFuncs(parent2, PARENT2);
291
AuRWLockFuncs(parent3, PARENT3);
293
#undef AuReadLockFunc
294
#undef AuWriteLockFunc
297
/* to debug easier, do not make them inlined functions */
298
#define DiMustReadLock(d) do { \
299
SiMustAnyLock((d)->d_sb); \
300
AuRwMustReadLock(&au_di(d)->di_rwsem); \
303
#define DiMustWriteLock(d) do { \
304
SiMustAnyLock((d)->d_sb); \
305
AuRwMustWriteLock(&au_di(d)->di_rwsem); \
308
#define DiMustAnyLock(d) do { \
309
SiMustAnyLock((d)->d_sb); \
310
AuRwMustAnyLock(&au_di(d)->di_rwsem); \
313
#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
315
/* ---------------------------------------------------------------------- */
317
static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
319
DiMustAnyLock(dentry);
320
return au_di(dentry)->di_bstart;
323
static inline aufs_bindex_t au_dbend(struct dentry *dentry)
325
DiMustAnyLock(dentry);
326
return au_di(dentry)->di_bend;
329
static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
331
DiMustAnyLock(dentry);
332
return au_di(dentry)->di_bwh;
335
static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
337
DiMustAnyLock(dentry);
338
AuDebugOn(dentry->d_inode
339
&& dentry->d_inode->i_mode
340
&& !S_ISDIR(dentry->d_inode->i_mode));
341
return au_di(dentry)->di_bdiropq;
345
static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
347
DiMustWriteLock(dentry);
348
AuDebugOn(au_sbend(dentry->d_sb) < bindex);
350
au_di(dentry)->di_bstart = bindex;
353
static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
355
DiMustWriteLock(dentry);
356
AuDebugOn(au_sbend(dentry->d_sb) < bindex
357
|| bindex < au_dbstart(dentry));
358
au_di(dentry)->di_bend = bindex;
361
static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
363
DiMustWriteLock(dentry);
364
AuDebugOn(au_sbend(dentry->d_sb) < bindex);
365
/* dbwh can be outside of bstart - bend range */
366
au_di(dentry)->di_bwh = bindex;
369
static inline void au_hdput(struct au_hdentry *hd, int do_free)
371
au_hintent_put(hd, do_free);
375
static inline void au_update_digen(struct dentry *dentry)
377
//DiMustWriteLock(dentry);
378
AuDebugOn(!dentry->d_sb);
379
atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
380
//smp_mb(); /* atomic_set */
383
#endif /* __KERNEL__ */
384
#endif /* __AUFS_DENTRY_H__ */