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
* superblock private data
22
* $Id: sbinfo.c,v 1.3 2008/05/04 23:52:41 sfjro Exp $
25
#include <linux/mnt_namespace.h>
26
#include <linux/smp_lock.h>
30
* they are necessary regardless sysfs is disabled.
32
void au_si_free(struct kobject *kobj)
34
struct au_sbinfo *sbinfo;
35
struct super_block *sb;
37
LKTRTrace("kobj %p\n", kobj);
38
sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
39
LKTRTrace("sbinfo %p\n", sbinfo);
40
AuDebugOn(!list_empty(&sbinfo->si_plink));
43
if (unlikely(!au_ftest_si(sbinfo, FAILED_INIT))) {
45
au_sbilist_del(sbinfo);
52
kfree(sbinfo->si_branch);
59
int au_si_alloc(struct super_block *sb)
62
struct au_sbinfo *sbinfo;
67
sbinfo = kmalloc(sizeof(*sbinfo), GFP_KERNEL);
68
//if (LktrCond) {kfree(sbinfo); sbinfo = NULL;}
69
if (unlikely(!sbinfo))
71
sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_KERNEL);
72
//if (LktrCond) {kfree(sbinfo->si_branch); sbinfo->si_branch = NULL;}
73
if (unlikely(!sbinfo->si_branch))
76
memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj));
77
err = sysaufs_si_init(sbinfo);
81
au_rw_init_wlock(&sbinfo->si_rwsem);
82
sbinfo->si_generation = 0;
83
//sbinfo->si_generation = INT_MAX - 2;
84
sbinfo->au_si_status = 0;
86
sbinfo->si_last_br_id = 0;
88
sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
89
sbinfo->si_wbr_create = AuWbrCreate_Def;
90
sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def;
91
sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def;
93
sbinfo->si_mntflags = AuOpt_Def;
95
sbinfo->si_xread = NULL;
96
sbinfo->si_xwrite = NULL;
97
sbinfo->si_xib = NULL;
98
mutex_init(&sbinfo->si_xib_mtx);
99
sbinfo->si_xib_buf = NULL;
100
/* leave si_xib_last_pindex and si_xib_next_bit */
102
au_nwt_init(&sbinfo->si_nowait);
104
sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ;
105
sbinfo->si_dirwh = AUFS_DIRWH_DEF;
107
spin_lock_init(&sbinfo->si_plink_lock);
108
INIT_LIST_HEAD(&sbinfo->si_plink);
110
/* leave other members for sysaufs and si_mnt. */
112
au_robr_lvma_init(sbinfo);
113
sb->s_fs_info = sbinfo;
114
//sysaufs_si_get(sb);
116
au_debug_sbinfo_init(sbinfo);
117
return 0; /* success */
120
kfree(sbinfo->si_branch);
128
/* ---------------------------------------------------------------------- */
130
struct au_branch *au_sbr(struct super_block *sb, aufs_bindex_t bindex)
132
struct au_branch *br;
135
AuDebugOn(bindex < 0 || au_sbend(sb) < bindex);
136
br = au_sbi(sb)->si_branch[0 + bindex];
141
au_gen_t au_sigen_inc(struct super_block *sb)
146
gen = ++au_sbi(sb)->si_generation;
147
au_update_digen(sb->s_root);
148
au_update_iigen(sb->s_root->d_inode);
149
sb->s_root->d_inode->i_version++;
153
int au_find_bindex(struct super_block *sb, struct au_branch *br)
155
aufs_bindex_t bindex, bend;
158
for (bindex = 0; bindex <= bend; bindex++)
159
if (au_sbr(sb, bindex) == br)
164
/* ---------------------------------------------------------------------- */
166
/* dentry and super_block lock. call at entry point */
167
void aufs_read_lock(struct dentry *dentry, int flags)
169
si_read_lock(dentry->d_sb, flags);
170
if (au_ftest_lock(flags, DW))
171
di_write_lock_child(dentry);
173
di_read_lock_child(dentry, flags);
176
void aufs_read_unlock(struct dentry *dentry, int flags)
178
if (au_ftest_lock(flags, DW))
179
di_write_unlock(dentry);
181
di_read_unlock(dentry, flags);
182
si_read_unlock(dentry->d_sb);
185
void aufs_write_lock(struct dentry *dentry)
187
si_write_lock(dentry->d_sb);
188
di_write_lock_child(dentry);
191
void aufs_write_unlock(struct dentry *dentry)
193
di_write_unlock(dentry);
194
si_write_unlock(dentry->d_sb);
197
void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
199
AuDebugOn(d1 == d2 || d1->d_sb != d2->d_sb);
200
si_read_lock(d1->d_sb, flags);
201
di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
204
void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
206
AuDebugOn(d1 == d2 || d1->d_sb != d2->d_sb);
207
di_write_unlock2(d1, d2);
208
si_read_unlock(d1->d_sb);
211
/* ---------------------------------------------------------------------- */
213
aufs_bindex_t au_new_br_id(struct super_block *sb)
216
struct au_sbinfo *sbinfo;
223
br_id = ++sbinfo->si_last_br_id;
224
if (br_id && au_br_index(sb, br_id) < 0)
230
struct vfsmount *au_mntcache_get(struct super_block *sb)
232
struct au_sbinfo *sbinfo;
233
struct mnt_namespace *ns;
234
struct vfsmount *pos;
237
//todo: check lock again
240
if (sbinfo->si_mntcache)
243
/* update si_mnt without sbinfo write lock */
244
//todo: big kernel lock?
245
/* vfsmount_lock is not exported */
246
//root_mnt = current->fs->root.mnt;
248
AuDebugOn(!current->nsproxy);
249
ns = current->nsproxy->mnt_ns;
251
list_for_each_entry(pos, &ns->list, mnt_list)
252
if (pos->mnt_sb == sb) {
253
sbinfo->si_mntcache = pos;
259
AuDebugOn(!sbinfo->si_mntcache);
260
return mntget(sbinfo->si_mntcache);