2 * Copyright (C) 2005-2013 Junjiro R. 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
25 void au_di_init_once(void *_dinfo)
27 struct au_dinfo *dinfo = _dinfo;
28 static struct lock_class_key aufs_di;
30 au_rw_init(&dinfo->di_rwsem);
31 au_rw_class(&dinfo->di_rwsem, &aufs_di);
34 struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
36 struct au_dinfo *dinfo;
39 dinfo = au_cache_alloc_dinfo();
43 nbr = au_sbend(sb) + 1;
46 dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
47 if (dinfo->di_hdentry) {
48 au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
49 dinfo->di_bstart = -1;
52 dinfo->di_bdiropq = -1;
53 for (i = 0; i < nbr; i++)
54 dinfo->di_hdentry[i].hd_id = -1;
58 au_cache_free_dinfo(dinfo);
65 void au_di_free(struct au_dinfo *dinfo)
68 aufs_bindex_t bend, bindex;
70 /* dentry may not be revalidated */
71 bindex = dinfo->di_bstart;
73 bend = dinfo->di_bend;
74 p = dinfo->di_hdentry + bindex;
75 while (bindex++ <= bend)
78 kfree(dinfo->di_hdentry);
79 au_cache_free_dinfo(dinfo);
82 void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
87 AuRwMustWriteLock(&a->di_rwsem);
88 AuRwMustWriteLock(&b->di_rwsem);
90 #define DiSwap(v, name) \
93 a->di_##name = b->di_##name; \
107 void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
109 AuRwMustWriteLock(&dst->di_rwsem);
110 AuRwMustWriteLock(&src->di_rwsem);
112 dst->di_bstart = src->di_bstart;
113 dst->di_bend = src->di_bend;
114 dst->di_bwh = src->di_bwh;
115 dst->di_bdiropq = src->di_bdiropq;
119 int au_di_init(struct dentry *dentry)
122 struct super_block *sb;
123 struct au_dinfo *dinfo;
127 dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
129 atomic_set(&dinfo->di_generation, au_sigen(sb));
130 /* smp_mb(); */ /* atomic_set */
131 dentry->d_fsdata = dinfo;
138 void au_di_fin(struct dentry *dentry)
140 struct au_dinfo *dinfo;
142 dinfo = au_di(dentry);
143 AuRwDestroy(&dinfo->di_rwsem);
147 int au_di_realloc(struct au_dinfo *dinfo, int nbr)
150 struct au_hdentry *hdp;
152 AuRwMustWriteLock(&dinfo->di_rwsem);
155 sz = sizeof(*hdp) * (dinfo->di_bend + 1);
158 hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
160 dinfo->di_hdentry = hdp;
167 /* ---------------------------------------------------------------------- */
169 static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
173 ii_write_lock_child(inode);
175 case AuLsc_DI_CHILD2:
176 ii_write_lock_child2(inode);
178 case AuLsc_DI_CHILD3:
179 ii_write_lock_child3(inode);
181 case AuLsc_DI_PARENT:
182 ii_write_lock_parent(inode);
184 case AuLsc_DI_PARENT2:
185 ii_write_lock_parent2(inode);
187 case AuLsc_DI_PARENT3:
188 ii_write_lock_parent3(inode);
195 static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
199 ii_read_lock_child(inode);
201 case AuLsc_DI_CHILD2:
202 ii_read_lock_child2(inode);
204 case AuLsc_DI_CHILD3:
205 ii_read_lock_child3(inode);
207 case AuLsc_DI_PARENT:
208 ii_read_lock_parent(inode);
210 case AuLsc_DI_PARENT2:
211 ii_read_lock_parent2(inode);
213 case AuLsc_DI_PARENT3:
214 ii_read_lock_parent3(inode);
221 void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
223 au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
225 if (au_ftest_lock(flags, IW))
226 do_ii_write_lock(d->d_inode, lsc);
227 else if (au_ftest_lock(flags, IR))
228 do_ii_read_lock(d->d_inode, lsc);
232 void di_read_unlock(struct dentry *d, int flags)
235 if (au_ftest_lock(flags, IW)) {
236 au_dbg_verify_dinode(d);
237 ii_write_unlock(d->d_inode);
238 } else if (au_ftest_lock(flags, IR)) {
239 au_dbg_verify_dinode(d);
240 ii_read_unlock(d->d_inode);
243 au_rw_read_unlock(&au_di(d)->di_rwsem);
246 void di_downgrade_lock(struct dentry *d, int flags)
248 if (d->d_inode && au_ftest_lock(flags, IR))
249 ii_downgrade_lock(d->d_inode);
250 au_rw_dgrade_lock(&au_di(d)->di_rwsem);
253 void di_write_lock(struct dentry *d, unsigned int lsc)
255 au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
257 do_ii_write_lock(d->d_inode, lsc);
260 void di_write_unlock(struct dentry *d)
262 au_dbg_verify_dinode(d);
264 ii_write_unlock(d->d_inode);
265 au_rw_write_unlock(&au_di(d)->di_rwsem);
268 void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
271 || d1->d_inode == d2->d_inode
272 || d1->d_sb != d2->d_sb);
274 if (isdir && au_test_subdir(d1, d2)) {
275 di_write_lock_child(d1);
276 di_write_lock_child2(d2);
278 /* there should be no races */
279 di_write_lock_child(d2);
280 di_write_lock_child2(d1);
284 void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
287 || d1->d_inode == d2->d_inode
288 || d1->d_sb != d2->d_sb);
290 if (isdir && au_test_subdir(d1, d2)) {
291 di_write_lock_parent(d1);
292 di_write_lock_parent2(d2);
294 /* there should be no races */
295 di_write_lock_parent(d2);
296 di_write_lock_parent2(d1);
300 void di_write_unlock2(struct dentry *d1, struct dentry *d2)
303 if (d1->d_inode == d2->d_inode)
304 au_rw_write_unlock(&au_di(d2)->di_rwsem);
309 /* ---------------------------------------------------------------------- */
311 struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
315 DiMustAnyLock(dentry);
317 if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
319 AuDebugOn(bindex < 0);
320 d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
321 AuDebugOn(d && d->d_count <= 0);
326 * extended version of au_h_dptr().
327 * returns a hashed and positive h_dentry in bindex, NULL, or error.
329 struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
331 struct dentry *h_dentry;
332 struct inode *inode, *h_inode;
334 inode = dentry->d_inode;
338 if (au_dbstart(dentry) <= bindex
339 && bindex <= au_dbend(dentry))
340 h_dentry = au_h_dptr(dentry, bindex);
341 if (h_dentry && !au_d_hashed_positive(h_dentry)) {
343 goto out; /* success */
346 AuDebugOn(bindex < au_ibstart(inode));
347 AuDebugOn(au_ibend(inode) < bindex);
348 h_inode = au_h_iptr(inode, bindex);
349 h_dentry = d_find_alias(h_inode);
351 if (!IS_ERR(h_dentry)) {
352 if (!au_d_hashed_positive(h_dentry))
353 goto out; /* success */
359 if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
360 h_dentry = au_plink_lkup(inode, bindex);
361 AuDebugOn(!h_dentry);
362 if (!IS_ERR(h_dentry)) {
363 if (!au_d_hashed_positive(h_dentry))
364 goto out; /* success */
371 AuDbgDentry(h_dentry);
375 aufs_bindex_t au_dbtail(struct dentry *dentry)
377 aufs_bindex_t bend, bwh;
379 bend = au_dbend(dentry);
381 bwh = au_dbwh(dentry);
384 if (0 < bwh && bwh < bend)
390 aufs_bindex_t au_dbtaildir(struct dentry *dentry)
392 aufs_bindex_t bend, bopq;
394 bend = au_dbtail(dentry);
396 bopq = au_dbdiropq(dentry);
397 if (0 <= bopq && bopq < bend)
403 /* ---------------------------------------------------------------------- */
405 void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
406 struct dentry *h_dentry)
408 struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
409 struct au_branch *br;
411 DiMustWriteLock(dentry);
414 hd->hd_dentry = h_dentry;
416 br = au_sbr(dentry->d_sb, bindex);
417 hd->hd_id = br->br_id;
421 int au_dbrange_test(struct dentry *dentry)
424 aufs_bindex_t bstart, bend;
427 bstart = au_dbstart(dentry);
428 bend = au_dbend(dentry);
430 AuDebugOn(bend < 0 && bstart > bend);
433 AuDebugOn(bend >= 0);
439 int au_digen_test(struct dentry *dentry, unsigned int sigen)
444 if (unlikely(au_digen(dentry) != sigen
445 || au_iigen_test(dentry->d_inode, sigen)))
451 void au_update_digen(struct dentry *dentry)
453 atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
454 /* smp_mb(); */ /* atomic_set */
457 void au_update_dbrange(struct dentry *dentry, int do_put_zero)
459 struct au_dinfo *dinfo;
461 struct au_hdentry *hdp;
463 DiMustWriteLock(dentry);
465 dinfo = au_di(dentry);
466 if (!dinfo || dinfo->di_bstart < 0)
469 hdp = dinfo->di_hdentry;
471 aufs_bindex_t bindex, bend;
473 bend = dinfo->di_bend;
474 for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
475 h_d = hdp[0 + bindex].hd_dentry;
476 if (h_d && !h_d->d_inode)
477 au_set_h_dptr(dentry, bindex, NULL);
481 dinfo->di_bstart = -1;
482 while (++dinfo->di_bstart <= dinfo->di_bend)
483 if (hdp[0 + dinfo->di_bstart].hd_dentry)
485 if (dinfo->di_bstart > dinfo->di_bend) {
486 dinfo->di_bstart = -1;
492 while (0 <= --dinfo->di_bend)
493 if (hdp[0 + dinfo->di_bend].hd_dentry)
495 AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
498 void au_update_dbstart(struct dentry *dentry)
500 aufs_bindex_t bindex, bend;
501 struct dentry *h_dentry;
503 bend = au_dbend(dentry);
504 for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
505 h_dentry = au_h_dptr(dentry, bindex);
508 if (h_dentry->d_inode) {
509 au_set_dbstart(dentry, bindex);
512 au_set_h_dptr(dentry, bindex, NULL);
516 void au_update_dbend(struct dentry *dentry)
518 aufs_bindex_t bindex, bstart;
519 struct dentry *h_dentry;
521 bstart = au_dbstart(dentry);
522 for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
523 h_dentry = au_h_dptr(dentry, bindex);
526 if (h_dentry->d_inode) {
527 au_set_dbend(dentry, bindex);
530 au_set_h_dptr(dentry, bindex, NULL);
534 int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
536 aufs_bindex_t bindex, bend;
538 bend = au_dbend(dentry);
539 for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
540 if (au_h_dptr(dentry, bindex) == h_dentry)