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: iinfo.c,v 1.10 2008/10/13 03:09:48 sfjro Exp $
27 struct au_iinfo
*au_ii(struct inode
*inode
)
29 struct au_iinfo
*iinfo
;
31 iinfo
= &(container_of(inode
, struct aufs_icntnr
, vfs_inode
)->iinfo
);
33 if (unlikely(!iinfo
->ii_hinode
))
35 AuDebugOn(!iinfo
->ii_hinode
36 /* || au_sbi(inode->i_sb)->si_bend < iinfo->ii_bend */
37 || iinfo
->ii_bend
< iinfo
->ii_bstart
);
41 struct inode
*au_h_iptr(struct inode
*inode
, aufs_bindex_t bindex
)
43 struct inode
*hidden_inode
;
45 /* lock free root dinfo/inode */
46 if (inode
->i_ino
!= AUFS_ROOT_INO
) {
48 AuDebugOn(bindex
< 0 || au_ibend(inode
) < bindex
);
50 SiMustAnyLock(inode
->i_sb
);
51 AuDebugOn(bindex
< 0 || au_sbend(inode
->i_sb
) < bindex
);
53 hidden_inode
= au_ii(inode
)->ii_hinode
[0 + bindex
].hi_inode
;
54 AuDebugOn(hidden_inode
&& atomic_read(&hidden_inode
->i_count
) <= 0);
58 aufs_bindex_t
au_ii_br_id(struct inode
*inode
, aufs_bindex_t bindex
)
62 || au_ibend(inode
) < bindex
63 || !au_ii(inode
)->ii_hinode
[0 + bindex
].hi_inode
);
64 return au_ii(inode
)->ii_hinode
[0 + bindex
].hi_id
;
67 /* todo: hard/soft set? */
68 void au_set_ibstart(struct inode
*inode
, aufs_bindex_t bindex
)
70 struct au_iinfo
*iinfo
= au_ii(inode
);
71 struct inode
*h_inode
;
73 IiMustWriteLock(inode
);
74 AuDebugOn(au_sbend(inode
->i_sb
) < bindex
);
75 iinfo
->ii_bstart
= bindex
;
76 h_inode
= iinfo
->ii_hinode
[bindex
+ 0].hi_inode
;
78 au_cpup_igen(inode
, h_inode
);
81 unsigned int au_hi_flags(struct inode
*inode
, int isdir
)
84 const unsigned int mnt_flags
= au_mntflags(inode
->i_sb
);
87 if (au_opt_test_xino(mnt_flags
))
88 au_fset_hi(flags
, XINO
);
89 if (unlikely(isdir
&& au_opt_test(mnt_flags
, UDBA_INOTIFY
)))
90 au_fset_hi(flags
, NOTIFY
);
94 void au_set_h_iptr(struct inode
*inode
, aufs_bindex_t bindex
,
95 struct inode
*h_inode
, unsigned int flags
)
97 struct au_hinode
*hinode
;
99 struct au_iinfo
*iinfo
= au_ii(inode
);
101 LKTRTrace("i%lu, b%d, hi%lu, flags 0x%x\n",
102 inode
->i_ino
, bindex
, h_inode
? h_inode
->i_ino
: 0, flags
);
103 IiMustWriteLock(inode
);
104 hinode
= iinfo
->ii_hinode
+ bindex
;
105 hi
= hinode
->hi_inode
;
106 AuDebugOn(bindex
< au_ibstart(inode
) || au_ibend(inode
) < bindex
);
107 AuDebugOn(h_inode
&& atomic_read(&h_inode
->i_count
) <= 0);
108 AuDebugOn(h_inode
&& hi
);
112 hinode
->hi_inode
= h_inode
;
115 struct super_block
*sb
= inode
->i_sb
;
117 if (bindex
== iinfo
->ii_bstart
)
118 au_cpup_igen(inode
, h_inode
);
119 hinode
->hi_id
= au_sbr_id(sb
, bindex
);
120 if (au_ftest_hi(flags
, XINO
)) {
121 struct au_xino_entry xinoe
= {
123 /* .h_gen = h_inode->i_generation */
125 err
= au_xino_write(sb
, bindex
, h_inode
->i_ino
, &xinoe
);
127 AuIOErr1("failed au_xino_write() %d\n", err
);
130 if (unlikely(au_ftest_hi(flags
, NOTIFY
)
131 && au_br_hinotifyable(au_sbr_perm(sb
, bindex
)))) {
132 err
= au_hin_alloc(hinode
, inode
, h_inode
);
134 AuIOErr1("au_hin_alloc() %d\n", err
);
139 void au_set_hi_wh(struct inode
*inode
, aufs_bindex_t bindex
,
142 struct au_hinode
*hinode
;
144 IiMustWriteLock(inode
);
145 hinode
= au_ii(inode
)->ii_hinode
+ bindex
;
146 AuDebugOn(hinode
->hi_whdentry
);
147 hinode
->hi_whdentry
= h_wh
;
150 void au_update_iigen(struct inode
*inode
)
152 AuDebugOn(!inode
->i_sb
);
153 atomic_set(&au_ii(inode
)->ii_generation
, au_sigen(inode
->i_sb
));
154 /* smp_mb(); */ /* atomic_set */
157 /* it may be called at remount time, too */
158 void au_update_brange(struct inode
*inode
, int do_put_zero
)
160 struct au_iinfo
*iinfo
;
162 LKTRTrace("i%lu, %d\n", inode
->i_ino
, do_put_zero
);
163 IiMustWriteLock(inode
);
165 iinfo
= au_ii(inode
);
166 if (unlikely(!iinfo
) || iinfo
->ii_bstart
< 0)
170 aufs_bindex_t bindex
;
171 for (bindex
= iinfo
->ii_bstart
; bindex
<= iinfo
->ii_bend
;
174 h_i
= iinfo
->ii_hinode
[0 + bindex
].hi_inode
;
175 if (h_i
&& !h_i
->i_nlink
)
176 au_set_h_iptr(inode
, bindex
, NULL
, 0);
180 iinfo
->ii_bstart
= -1;
181 while (++iinfo
->ii_bstart
<= iinfo
->ii_bend
)
182 if (iinfo
->ii_hinode
[0 + iinfo
->ii_bstart
].hi_inode
)
184 if (iinfo
->ii_bstart
> iinfo
->ii_bend
) {
185 iinfo
->ii_bstart
= -1;
191 while (0 <= --iinfo
->ii_bend
)
192 if (iinfo
->ii_hinode
[0 + iinfo
->ii_bend
].hi_inode
)
194 AuDebugOn(iinfo
->ii_bstart
> iinfo
->ii_bend
|| iinfo
->ii_bend
< 0);
197 /* ---------------------------------------------------------------------- */
199 int au_iinfo_init(struct inode
*inode
)
201 struct au_iinfo
*iinfo
;
202 struct super_block
*sb
;
207 iinfo
= &(container_of(inode
, struct aufs_icntnr
, vfs_inode
)->iinfo
);
208 AuDebugOn(iinfo
->ii_hinode
);
209 nbr
= au_sbend(sb
) + 1;
210 if (unlikely(nbr
<= 0))
212 iinfo
->ii_hinode
= kcalloc(nbr
, sizeof(*iinfo
->ii_hinode
), GFP_NOFS
);
213 if (iinfo
->ii_hinode
) {
214 for (i
= 0; i
< nbr
; i
++)
215 iinfo
->ii_hinode
[i
].hi_id
= -1;
216 atomic_set(&iinfo
->ii_generation
, au_sigen(sb
));
217 /* smp_mb(); */ /* atomic_set */
218 au_rw_init_nolock(&iinfo
->ii_rwsem
);
219 iinfo
->ii_bstart
= -1;
221 iinfo
->ii_vdir
= NULL
;
222 iinfo
->ii_nfsd_readdir
= NULL
;
228 static int au_iinfo_write0(struct super_block
*sb
, struct au_hinode
*hinode
,
232 aufs_bindex_t bindex
;
235 locked
= si_noflush_read_trylock(sb
); /* crucio! */
236 bindex
= au_br_index(sb
, hinode
->hi_id
);
238 err
= au_xino_write0(sb
, bindex
, hinode
->hi_inode
->i_ino
, ino
);
245 void au_iinfo_fin(struct inode
*inode
)
247 struct au_iinfo
*iinfo
;
249 unsigned char unlinked
;
250 struct au_hinode
*hi
;
251 struct super_block
*sb
;
254 iinfo
= au_ii(inode
);
256 if (unlikely(!iinfo
))
259 if (unlikely(iinfo
->ii_vdir
))
260 au_vdir_free(iinfo
->ii_vdir
);
261 if (unlikely(iinfo
->ii_nfsd_readdir
))
262 au_nfsd_readdir_free(inode
);
264 if (iinfo
->ii_bstart
>= 0) {
266 unlinked
= !inode
->i_nlink
;
270 hi
= iinfo
->ii_hinode
+ iinfo
->ii_bstart
;
271 bend
= iinfo
->ii_bend
;
272 while (iinfo
->ii_bstart
++ <= bend
) {
274 if (unlinked
|| !hi
->hi_inode
->i_nlink
) {
275 au_iinfo_write0(sb
, hi
, ino
);
276 /* ignore this error */
285 kfree(iinfo
->ii_hinode
);
286 au_rwsem_destroy(&iinfo
->ii_rwsem
);