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
22
* $Id: inode.h,v 1.2 2008/04/21 01:32:05 sfjro Exp $
25
#ifndef __AUFS_INODE_H__
26
#define __AUFS_INODE_H__
31
#include <linux/namei.h>
32
#include <linux/security.h>
33
#include <linux/aufs_type.h>
41
atomic_t ii_generation;
42
struct super_block *ii_hsb1; /* no get/put */
44
struct au_rwsem ii_rwsem;
45
aufs_bindex_t ii_bstart, ii_bend;
46
struct au_hinode *ii_hinode;
47
struct au_vdir *ii_vdir;
51
struct au_iinfo iinfo;
52
struct inode vfs_inode;
55
/* ---------------------------------------------------------------------- */
58
int au_refresh_hinode_self(struct inode *inode);
59
int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
60
struct inode *au_new_inode(struct dentry *dentry);
61
int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
63
int au_test_h_perm(struct inode *h_inode, int mask, int dlgt);
64
int au_test_h_perm_sio(struct inode *h_inode, int mask, int dlgt);
67
extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
70
#define AuWrDir_ADD_ENTRY 1
71
#define AuWrDir_LOCK_SRCDIR (1 << 1)
72
#define AuWrDir_ISDIR (1 << 2)
73
#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
74
#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; }
75
#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; }
77
struct au_wr_dir_args {
78
aufs_bindex_t force_btgt;
81
int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
82
struct au_wr_dir_args *args);
86
int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
87
struct dentry *h_parent, int isdir, struct au_ndx *ndx);
88
int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
89
int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
90
int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
91
struct nameidata *nd);
92
int aufs_link(struct dentry *src_dentry, struct inode *dir,
93
struct dentry *dentry);
94
int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
97
int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup,
98
struct dentry *locked);
99
int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
100
struct dentry *h_parent, int isdir, struct au_ndx *ndx);
101
int aufs_unlink(struct inode *dir, struct dentry *dentry);
102
int aufs_rmdir(struct inode *dir, struct dentry *dentry);
105
int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
106
int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
107
struct inode *dir, struct dentry *dentry);
109
#ifdef CONFIG_AUFS_DLGT
111
int au_security_inode_permission(struct inode *h_inode, int mask,
112
struct nameidata *fake_nd, int dlgt);
115
int au_security_inode_permission(struct inode *h_inode, int mask,
116
struct nameidata *fake_nd, int dlgt)
118
return security_inode_permission(h_inode, mask, fake_nd);
120
#endif /* CONFIG_AUFS_DLGT */
122
#ifdef CONFIG_AUFS_WORKAROUND_FUSE
124
int aufs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st);
129
int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
130
size_t sz, int flags);
131
ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
133
ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t sz);
134
int aufs_removexattr(struct dentry *dentry, const char *name);
138
struct au_iinfo *au_ii(struct inode *inode);
139
struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
140
aufs_bindex_t au_ii_br_id(struct inode *inode, aufs_bindex_t bindex);
142
void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex);
143
void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
144
struct dentry *h_wh);
145
unsigned int au_hi_flags(struct inode *inode, int isdir);
149
#define AuHi_NOTIFY (1 << 1)
150
#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
151
#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; }
152
#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; }
153
#ifndef CONFIG_AUFS_HINOTIFY
155
#define AuHi_NOTIFY 0
158
void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
159
struct inode *h_inode, unsigned int flags);
161
void au_update_iigen(struct inode *inode);
162
void au_update_brange(struct inode *inode, int do_put_zero);
164
int au_iinfo_init(struct inode *inode);
165
void au_iinfo_fin(struct inode *inode);
168
#ifdef CONFIG_AUFS_DEBUG
169
void au_plink_list(struct super_block *sb);
171
static inline void au_plink_list(struct super_block *sb)
176
int au_plink_test(struct super_block *sb, struct inode *inode);
177
struct dentry *au_plink_lkup(struct super_block *sb, aufs_bindex_t bindex,
178
struct inode *inode);
179
void au_plink_append(struct super_block *sb, struct inode *inode,
180
struct dentry *h_dentry, aufs_bindex_t bindex);
181
void au_plink_put(struct super_block *sb);
182
void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
184
/* ---------------------------------------------------------------------- */
186
/* lock subclass for iinfo */
188
AuLsc_II_CHILD, /* child first */
189
AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */
190
AuLsc_II_CHILD3, /* copyup dirs */
195
AuLsc_II_NEW /* new inode */
199
* ii_read_lock_child, ii_write_lock_child,
200
* ii_read_lock_child2, ii_write_lock_child2,
201
* ii_read_lock_child3, ii_write_lock_child3,
202
* ii_read_lock_parent, ii_write_lock_parent,
203
* ii_read_lock_parent2, ii_write_lock_parent2,
204
* ii_read_lock_parent3, ii_write_lock_parent3,
205
* ii_read_lock_parent4, ii_write_lock_parent4,
206
* ii_read_lock_new, ii_write_lock_new
208
#define AuReadLockFunc(name, lsc) \
209
static inline void ii_read_lock_##name(struct inode *i) \
210
{ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); }
212
#define AuWriteLockFunc(name, lsc) \
213
static inline void ii_write_lock_##name(struct inode *i) \
214
{ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); }
216
#define AuRWLockFuncs(name, lsc) \
217
AuReadLockFunc(name, lsc) \
218
AuWriteLockFunc(name, lsc)
220
AuRWLockFuncs(child, CHILD);
221
AuRWLockFuncs(child2, CHILD2);
222
AuRWLockFuncs(child3, CHILD3);
223
AuRWLockFuncs(parent, PARENT);
224
AuRWLockFuncs(parent2, PARENT2);
225
AuRWLockFuncs(parent3, PARENT3);
226
AuRWLockFuncs(parent4, PARENT4);
227
AuRWLockFuncs(new, NEW);
229
#undef AuReadLockFunc
230
#undef AuWriteLockFunc
234
* ii_read_unlock, ii_write_unlock, ii_downgrade_lock
236
AuSimpleUnlockRwsemFuncs(ii, struct inode *i, au_ii(i)->ii_rwsem);
238
/* to debug easier, do not make them inlined functions */
239
#define IiMustReadLock(i) do { \
240
SiMustAnyLock((i)->i_sb); \
241
AuRwMustReadLock(&au_ii(i)->ii_rwsem); \
244
#define IiMustWriteLock(i) do { \
245
SiMustAnyLock((i)->i_sb); \
246
AuRwMustWriteLock(&au_ii(i)->ii_rwsem); \
249
#define IiMustAnyLock(i) do { \
250
SiMustAnyLock((i)->i_sb); \
251
AuRwMustAnyLock(&au_ii(i)->ii_rwsem); \
254
#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
256
/* ---------------------------------------------------------------------- */
258
static inline aufs_bindex_t au_ibstart(struct inode *inode)
260
IiMustAnyLock(inode);
261
return au_ii(inode)->ii_bstart;
264
static inline aufs_bindex_t au_ibend(struct inode *inode)
266
IiMustAnyLock(inode);
267
return au_ii(inode)->ii_bend;
270
static inline struct au_vdir *au_ivdir(struct inode *inode)
272
IiMustAnyLock(inode);
273
AuDebugOn(!S_ISDIR(inode->i_mode));
274
return au_ii(inode)->ii_vdir;
277
static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
279
struct au_hinode *hinode;
280
IiMustAnyLock(inode);
281
hinode = au_ii(inode)->ii_hinode + bindex;
282
return hinode->hi_whdentry;
285
static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
287
IiMustWriteLock(inode);
288
AuDebugOn(au_sbend(inode->i_sb) < bindex || bindex < au_ibstart(inode));
289
au_ii(inode)->ii_bend = bindex;
292
static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
294
IiMustWriteLock(inode);
295
AuDebugOn(!S_ISDIR(inode->i_mode) || (au_ii(inode)->ii_vdir && vdir));
296
au_ii(inode)->ii_vdir = vdir;
299
static inline void au_hiput(struct au_hinode *hinode)
302
dput(hinode->hi_whdentry);
303
iput(hinode->hi_inode);
306
static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
308
//todo: this lock check causes some unnecessary locks in callers.
309
IiMustAnyLock(inode);
310
return au_ii(inode)->ii_hinode + bindex;
313
/* tiny test for inode number */
314
/* tmpfs generation is too rough */
315
static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
317
IiMustAnyLock(inode);
318
return !(au_ii(inode)->ii_hsb1 == h_inode->i_sb
319
&& inode->i_generation == h_inode->i_generation);
322
static inline au_gen_t au_iigen(struct inode *inode)
324
return atomic_read(&au_ii(inode)->ii_generation);
327
#ifdef CONFIG_AUFS_HINOTIFY
328
static inline au_gen_t au_iigen_dec(struct inode *inode)
330
//AuDbg("i%lu\n", inode->i_ino);
331
return atomic_dec_return(&au_ii(inode)->ii_generation);
335
#endif /* __KERNEL__ */
336
#endif /* __AUFS_INODE_H__ */