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
* super_block operations
22
* $Id: super.h,v 1.4 2008/05/04 23:52:41 sfjro Exp $
25
#ifndef __AUFS_SUPER_H__
26
#define __AUFS_SUPER_H__
31
#include <linux/cramfs_fs.h>
32
#include <linux/kobject.h>
33
#include <linux/magic.h>
34
#include <linux/aufs_type.h>
40
typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
41
typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
44
struct au_wbr_copyup_operations {
45
int (*copyup)(struct dentry *dentry);
48
struct au_wbr_create_operations {
49
int (*create)(struct dentry *dentry, int isdir);
50
int (*init)(struct super_block *sb);
51
int (*fin)(struct super_block *sb);
55
struct mutex mfs_lock; /* protect this structure */
56
unsigned long mfs_jiffy;
57
unsigned long mfs_expire;
58
aufs_bindex_t mfs_bindex;
64
/* sbinfo status flags */
66
* set true when refresh_dirs() failed at remount time.
67
* then try refreshing dirs at access time again.
68
* if it is false, refreshing dirs at access time is unnecesary
70
#define AuSi_FAILED_REFRESH_DIRS 1
71
#define AuSi_FAILED_INIT (1 << 1)
72
#define au_ftest_si(sbinfo, name) ((sbinfo)->au_si_status & AuSi_##name)
73
#define au_fset_si(sbinfo, name) \
74
{ (sbinfo)->au_si_status |= AuSi_##name; }
75
#define au_fclr_si(sbinfo, name) \
76
{ (sbinfo)->au_si_status &= ~AuSi_##name; }
80
/* nowait tasks in the system-wide workqueue */
81
struct au_nowait_tasks si_nowait;
83
struct au_rwsem si_rwsem;
85
/* branch management */
86
au_gen_t si_generation;
89
unsigned char au_si_status;
91
aufs_bindex_t si_bend;
92
aufs_bindex_t si_last_br_id;
93
struct au_branch **si_branch;
95
/* policy to select a writable branch */
96
unsigned char si_wbr_copyup;
97
unsigned char si_wbr_create;
98
struct au_wbr_copyup_operations *si_wbr_copyup_ops;
99
struct au_wbr_create_operations *si_wbr_create_ops;
102
atomic_t si_wbr_rr_next;
104
/* most free space */
105
struct au_wbr_mfs si_wbr_mfs;
108
/* include/asm-ia64/siginfo.h defines a macro named si_flags */
109
unsigned int si_mntflags;
111
/* external inode number (bitmap and translation table) */
113
au_writef_t si_xwrite;
115
struct mutex si_xib_mtx; /* protect xib members */
116
unsigned long *si_xib_buf;
117
unsigned long si_xib_last_pindex;
119
//unsigned long long si_xib_limit; /* Max xib file size */
121
/* readdir cache time, max, in HZ */
122
unsigned long si_rdcache;
125
* If the number of whiteouts are larger than si_dirwh, leave all of
126
* them after au_whtmp_ren to reduce the cost of rmdir(2).
127
* future fsck.aufs or kernel thread will remove them later.
128
* Otherwise, remove all whiteouts and the dir in rmdir(2).
130
unsigned int si_dirwh;
133
* rename(2) a directory with all children.
137
/* pseudo_link list */ // dirty
138
spinlock_t si_plink_lock;
139
struct list_head si_plink;
141
/* dirty, for export, async ops, and sysfs */
142
struct vfsmount *si_mntcache; /* no get/put */
145
* sysfs and lifetime management.
146
* this is not a small structure and it may be a waste of memory in case
147
* of sysfs is disabled, particulary when many aufs-es are mounted.
149
struct kobject si_kobj;
151
//todo: remove this list.
152
/* super_blocks list is not exported */
153
struct list_head si_list;
155
#ifdef CONFIG_AUFS_ROBR
156
/* locked vma list for mmap() */ // dirty
157
spinlock_t si_lvma_lock;
158
struct list_head si_lvma;
161
/* dirty, necessary for unmounting, sysfs and sysrq */
162
struct super_block *si_sb;
165
/* ---------------------------------------------------------------------- */
167
/* policy to select one among writable branches */
168
#define AuWbrCopyup(sbinfo, args... ) \
169
(sbinfo)->si_wbr_copyup_ops->copyup(args)
170
#define AuWbrCreate(sbinfo, args... ) \
171
(sbinfo)->si_wbr_create_ops->create(args)
173
/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
174
#define AuLock_DW 1 /* write-lock dentry */
175
#define AuLock_IR (1 << 1) /* read-lock inode */
176
#define AuLock_IW (1 << 2) /* write-lock inode */
177
#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
178
#define AuLock_DIR (1 << 4) /* target is a dir */
179
#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
180
#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; }
181
#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; }
183
/* ---------------------------------------------------------------------- */
186
extern struct file_system_type aufs_fs_type;
187
struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
190
void au_si_free(struct kobject *kobj);
191
int au_si_alloc(struct super_block *sb);
192
struct au_branch *au_sbr(struct super_block *sb, aufs_bindex_t bindex);
193
au_gen_t au_sigen_inc(struct super_block *sb);
194
int au_find_bindex(struct super_block *sb, struct au_branch *br);
196
void aufs_read_lock(struct dentry *dentry, int flags);
197
void aufs_read_unlock(struct dentry *dentry, int flags);
198
void aufs_write_lock(struct dentry *dentry);
199
void aufs_write_unlock(struct dentry *dentry);
200
void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir);
201
void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
203
aufs_bindex_t au_new_br_id(struct super_block *sb);
204
struct vfsmount *au_mntcache_get(struct super_block *sb);
207
extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
208
extern struct au_wbr_create_operations au_wbr_create_ops[];
209
int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst,
210
struct dentry *locked);
212
/* ---------------------------------------------------------------------- */
214
static inline struct au_sbinfo *au_sbi(struct super_block *sb)
216
return sb->s_fs_info;
219
static inline const char *au_sbtype(struct super_block *sb)
221
return sb->s_type->name;
224
static inline int au_test_aufs(struct super_block *sb)
226
return (sb->s_magic == AUFS_SUPER_MAGIC);
229
static inline int au_test_nfs(struct super_block *sb)
231
#ifdef CONFIG_AUFS_BR_NFS
232
return (sb->s_magic == NFS_SUPER_MAGIC);
238
static inline int au_test_fuse(struct super_block *sb)
240
#ifdef CONFIG_AUFS_WORKAROUND_FUSE
241
#ifdef FUSE_SUPER_MAGIC
242
BUILD_BUG_ON(FUSE_SUPER_MAGIC != 0x65735546);
243
return (sb->s_magic == FUSE_SUPER_MAGIC);
245
return !strcmp(au_sbtype(sb), "fuse");
251
static inline int au_test_xfs(struct super_block *sb)
253
#ifdef CONFIG_AUFS_BR_XFS
255
BUILD_BUG_ON(XFS_SB_MAGIC != 0x58465342);
256
return (sb->s_magic == XFS_SB_MAGIC);
258
return !strcmp(au_sbtype(sb), "xfs");
264
static inline int au_test_tmpfs(struct super_block *sb)
268
BUILD_BUG_ON(TMPFS_MAGIC != 0x01021994);
269
return (sb->s_magic == TMPFS_MAGIC);
271
return !strcmp(au_sbtype(sb), "tmpfs");
277
/* ---------------------------------------------------------------------- */
279
#ifdef CONFIG_AUFS_EXPORT
280
extern struct export_operations aufs_export_op;
281
static inline void au_init_export_op(struct super_block *sb)
283
sb->s_export_op = &aufs_export_op;
286
static inline int au_test_nfsd(struct task_struct *tsk)
288
return (!tsk->mm && !strcmp(tsk->comm, "nfsd"));
291
static inline void au_nfsd_lockdep_off(void)
293
if (au_test_nfsd(current))
297
static inline void au_nfsd_lockdep_on(void)
299
if (au_test_nfsd(current))
303
static inline int au_test_nfsd(struct task_struct *tsk)
308
static inline void au_init_export_op(struct super_block *sb)
313
#define au_nfsd_lockdep_off() do {} while (0)
314
#define au_nfsd_lockdep_on() do {} while (0)
315
#endif /* CONFIG_AUFS_EXPORT */
317
#ifdef CONFIG_AUFS_ROBR
318
static inline int au_test_nested(struct super_block *h_sb)
323
static inline void au_robr_lvma_init(struct au_sbinfo *sbinfo)
325
spin_lock_init(&sbinfo->si_lvma_lock);
326
INIT_LIST_HEAD(&sbinfo->si_lvma);
329
static inline int au_test_nested(struct super_block *h_sb)
332
if (unlikely(au_test_aufs(h_sb))) {
339
static inline void au_robr_lvma_init(struct au_sbinfo *sbinfo)
343
#endif /* CONFIG_AUFS_ROBR */
345
/* ---------------------------------------------------------------------- */
347
/* lock superblock. mainly for entry point functions */
349
* si_noflush_read_lock, si_noflush_write_lock,
350
* si_read_unlock, si_write_unlock, si_downgrade_lock
352
AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb,
353
au_sbi(sb)->si_rwsem);
354
AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, au_sbi(sb)->si_rwsem);
356
static inline void si_read_lock(struct super_block *sb, int flags)
358
if (au_ftest_lock(flags, FLUSH))
359
au_nwt_flush(&au_sbi(sb)->si_nowait);
360
si_noflush_read_lock(sb);
363
static inline void si_write_lock(struct super_block *sb)
365
au_nwt_flush(&au_sbi(sb)->si_nowait);
366
si_noflush_write_lock(sb);
369
static inline int si_read_trylock(struct super_block *sb, int flags)
371
if (au_ftest_lock(flags, FLUSH))
372
au_nwt_flush(&au_sbi(sb)->si_nowait);
373
return si_noflush_read_trylock(sb);
376
static inline int si_write_trylock(struct super_block *sb, int flags)
378
if (au_ftest_lock(flags, FLUSH))
379
au_nwt_flush(&au_sbi(sb)->si_nowait);
380
return si_noflush_write_trylock(sb);
383
/* to debug easier, do not make them inlined functions */
384
#define SiMustReadLock(sb) AuRwMustReadLock(&au_sbi(sb)->si_rwsem)
385
#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
386
#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
388
/* ---------------------------------------------------------------------- */
390
static inline aufs_bindex_t au_sbend(struct super_block *sb)
393
return au_sbi(sb)->si_bend;
396
static inline unsigned int au_mntflags(struct super_block *sb)
399
return au_sbi(sb)->si_mntflags;
402
static inline au_gen_t au_sigen(struct super_block *sb)
405
return au_sbi(sb)->si_generation;
408
#endif /* __KERNEL__ */
409
#endif /* __AUFS_SUPER_H__ */