]>
git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - fs/aufs/dinfo.c
2 * Copyright (C) 2005-2016 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, see <http://www.gnu.org/licenses/>.
24 void au_di_init_once(void *_dinfo
)
26 struct au_dinfo
*dinfo
= _dinfo
;
28 au_rw_init(&dinfo
->di_rwsem
);
31 struct au_dinfo
*au_di_alloc(struct super_block
*sb
, unsigned int lsc
)
33 struct au_dinfo
*dinfo
;
36 dinfo
= au_cache_alloc_dinfo();
40 nbr
= au_sbbot(sb
) + 1;
43 dinfo
->di_hdentry
= kcalloc(nbr
, sizeof(*dinfo
->di_hdentry
), GFP_NOFS
);
44 if (dinfo
->di_hdentry
) {
45 au_rw_write_lock_nested(&dinfo
->di_rwsem
, lsc
);
49 dinfo
->di_bdiropq
= -1;
50 dinfo
->di_tmpfile
= 0;
51 for (i
= 0; i
< nbr
; i
++)
52 dinfo
->di_hdentry
[i
].hd_id
= -1;
56 au_cache_dfree_dinfo(dinfo
);
63 void au_di_free(struct au_dinfo
*dinfo
)
66 aufs_bindex_t bbot
, bindex
;
68 /* dentry may not be revalidated */
69 bindex
= dinfo
->di_btop
;
71 bbot
= dinfo
->di_bbot
;
72 p
= au_hdentry(dinfo
, bindex
);
73 while (bindex
++ <= bbot
)
76 au_delayed_kfree(dinfo
->di_hdentry
);
77 au_cache_dfree_dinfo(dinfo
);
80 void au_di_swap(struct au_dinfo
*a
, struct au_dinfo
*b
)
85 AuRwMustWriteLock(&a
->di_rwsem
);
86 AuRwMustWriteLock(&b
->di_rwsem
);
88 #define DiSwap(v, name) \
91 a->di_##name = b->di_##name; \
105 void au_di_cp(struct au_dinfo
*dst
, struct au_dinfo
*src
)
107 AuRwMustWriteLock(&dst
->di_rwsem
);
108 AuRwMustWriteLock(&src
->di_rwsem
);
110 dst
->di_btop
= src
->di_btop
;
111 dst
->di_bbot
= src
->di_bbot
;
112 dst
->di_bwh
= src
->di_bwh
;
113 dst
->di_bdiropq
= src
->di_bdiropq
;
117 int au_di_init(struct dentry
*dentry
)
120 struct super_block
*sb
;
121 struct au_dinfo
*dinfo
;
125 dinfo
= au_di_alloc(sb
, AuLsc_DI_CHILD
);
127 atomic_set(&dinfo
->di_generation
, au_sigen(sb
));
128 /* smp_mb(); */ /* atomic_set */
129 dentry
->d_fsdata
= dinfo
;
136 void au_di_fin(struct dentry
*dentry
)
138 struct au_dinfo
*dinfo
;
140 dinfo
= au_di(dentry
);
141 AuRwDestroy(&dinfo
->di_rwsem
);
145 int au_di_realloc(struct au_dinfo
*dinfo
, int nbr
, int may_shrink
)
148 struct au_hdentry
*hdp
;
150 AuRwMustWriteLock(&dinfo
->di_rwsem
);
153 sz
= sizeof(*hdp
) * (dinfo
->di_bbot
+ 1);
156 hdp
= au_kzrealloc(dinfo
->di_hdentry
, sz
, sizeof(*hdp
) * nbr
, GFP_NOFS
,
159 dinfo
->di_hdentry
= hdp
;
166 /* ---------------------------------------------------------------------- */
168 static void do_ii_write_lock(struct inode
*inode
, unsigned int lsc
)
172 ii_write_lock_child(inode
);
174 case AuLsc_DI_CHILD2
:
175 ii_write_lock_child2(inode
);
177 case AuLsc_DI_CHILD3
:
178 ii_write_lock_child3(inode
);
180 case AuLsc_DI_PARENT
:
181 ii_write_lock_parent(inode
);
183 case AuLsc_DI_PARENT2
:
184 ii_write_lock_parent2(inode
);
186 case AuLsc_DI_PARENT3
:
187 ii_write_lock_parent3(inode
);
194 static void do_ii_read_lock(struct inode
*inode
, unsigned int lsc
)
198 ii_read_lock_child(inode
);
200 case AuLsc_DI_CHILD2
:
201 ii_read_lock_child2(inode
);
203 case AuLsc_DI_CHILD3
:
204 ii_read_lock_child3(inode
);
206 case AuLsc_DI_PARENT
:
207 ii_read_lock_parent(inode
);
209 case AuLsc_DI_PARENT2
:
210 ii_read_lock_parent2(inode
);
212 case AuLsc_DI_PARENT3
:
213 ii_read_lock_parent3(inode
);
220 void di_read_lock(struct dentry
*d
, int flags
, unsigned int lsc
)
224 au_rw_read_lock_nested(&au_di(d
)->di_rwsem
, lsc
);
225 if (d_really_is_positive(d
)) {
227 if (au_ftest_lock(flags
, IW
))
228 do_ii_write_lock(inode
, lsc
);
229 else if (au_ftest_lock(flags
, IR
))
230 do_ii_read_lock(inode
, lsc
);
234 void di_read_unlock(struct dentry
*d
, int flags
)
238 if (d_really_is_positive(d
)) {
240 if (au_ftest_lock(flags
, IW
)) {
241 au_dbg_verify_dinode(d
);
242 ii_write_unlock(inode
);
243 } else if (au_ftest_lock(flags
, IR
)) {
244 au_dbg_verify_dinode(d
);
245 ii_read_unlock(inode
);
248 au_rw_read_unlock(&au_di(d
)->di_rwsem
);
251 void di_downgrade_lock(struct dentry
*d
, int flags
)
253 if (d_really_is_positive(d
) && au_ftest_lock(flags
, IR
))
254 ii_downgrade_lock(d_inode(d
));
255 au_rw_dgrade_lock(&au_di(d
)->di_rwsem
);
258 void di_write_lock(struct dentry
*d
, unsigned int lsc
)
260 au_rw_write_lock_nested(&au_di(d
)->di_rwsem
, lsc
);
261 if (d_really_is_positive(d
))
262 do_ii_write_lock(d_inode(d
), lsc
);
265 void di_write_unlock(struct dentry
*d
)
267 au_dbg_verify_dinode(d
);
268 if (d_really_is_positive(d
))
269 ii_write_unlock(d_inode(d
));
270 au_rw_write_unlock(&au_di(d
)->di_rwsem
);
273 void di_write_lock2_child(struct dentry
*d1
, struct dentry
*d2
, int isdir
)
276 || d_inode(d1
) == d_inode(d2
)
277 || d1
->d_sb
!= d2
->d_sb
);
279 if (isdir
&& au_test_subdir(d1
, d2
)) {
280 di_write_lock_child(d1
);
281 di_write_lock_child2(d2
);
283 /* there should be no races */
284 di_write_lock_child(d2
);
285 di_write_lock_child2(d1
);
289 void di_write_lock2_parent(struct dentry
*d1
, struct dentry
*d2
, int isdir
)
292 || d_inode(d1
) == d_inode(d2
)
293 || d1
->d_sb
!= d2
->d_sb
);
295 if (isdir
&& au_test_subdir(d1
, d2
)) {
296 di_write_lock_parent(d1
);
297 di_write_lock_parent2(d2
);
299 /* there should be no races */
300 di_write_lock_parent(d2
);
301 di_write_lock_parent2(d1
);
305 void di_write_unlock2(struct dentry
*d1
, struct dentry
*d2
)
308 if (d_inode(d1
) == d_inode(d2
))
309 au_rw_write_unlock(&au_di(d2
)->di_rwsem
);
314 /* ---------------------------------------------------------------------- */
316 struct dentry
*au_h_dptr(struct dentry
*dentry
, aufs_bindex_t bindex
)
320 DiMustAnyLock(dentry
);
322 if (au_dbtop(dentry
) < 0 || bindex
< au_dbtop(dentry
))
324 AuDebugOn(bindex
< 0);
325 d
= au_hdentry(au_di(dentry
), bindex
)->hd_dentry
;
326 AuDebugOn(d
&& au_dcount(d
) <= 0);
331 * extended version of au_h_dptr().
332 * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
335 struct dentry
*au_h_d_alias(struct dentry
*dentry
, aufs_bindex_t bindex
)
337 struct dentry
*h_dentry
;
338 struct inode
*inode
, *h_inode
;
340 AuDebugOn(d_really_is_negative(dentry
));
343 if (au_dbtop(dentry
) <= bindex
344 && bindex
<= au_dbbot(dentry
))
345 h_dentry
= au_h_dptr(dentry
, bindex
);
346 if (h_dentry
&& !au_d_linkable(h_dentry
)) {
348 goto out
; /* success */
351 inode
= d_inode(dentry
);
352 AuDebugOn(bindex
< au_ibtop(inode
));
353 AuDebugOn(au_ibbot(inode
) < bindex
);
354 h_inode
= au_h_iptr(inode
, bindex
);
355 h_dentry
= d_find_alias(h_inode
);
357 if (!IS_ERR(h_dentry
)) {
358 if (!au_d_linkable(h_dentry
))
359 goto out
; /* success */
365 if (au_opt_test(au_mntflags(dentry
->d_sb
), PLINK
)) {
366 h_dentry
= au_plink_lkup(inode
, bindex
);
367 AuDebugOn(!h_dentry
);
368 if (!IS_ERR(h_dentry
)) {
369 if (!au_d_hashed_positive(h_dentry
))
370 goto out
; /* success */
377 AuDbgDentry(h_dentry
);
381 aufs_bindex_t
au_dbtail(struct dentry
*dentry
)
383 aufs_bindex_t bbot
, bwh
;
385 bbot
= au_dbbot(dentry
);
387 bwh
= au_dbwh(dentry
);
390 if (0 < bwh
&& bwh
< bbot
)
396 aufs_bindex_t
au_dbtaildir(struct dentry
*dentry
)
398 aufs_bindex_t bbot
, bopq
;
400 bbot
= au_dbtail(dentry
);
402 bopq
= au_dbdiropq(dentry
);
403 if (0 <= bopq
&& bopq
< bbot
)
409 /* ---------------------------------------------------------------------- */
411 void au_set_h_dptr(struct dentry
*dentry
, aufs_bindex_t bindex
,
412 struct dentry
*h_dentry
)
414 struct au_dinfo
*dinfo
;
415 struct au_hdentry
*hd
;
416 struct au_branch
*br
;
418 DiMustWriteLock(dentry
);
420 dinfo
= au_di(dentry
);
421 hd
= au_hdentry(dinfo
, bindex
);
423 hd
->hd_dentry
= h_dentry
;
425 br
= au_sbr(dentry
->d_sb
, bindex
);
426 hd
->hd_id
= br
->br_id
;
430 int au_dbrange_test(struct dentry
*dentry
)
433 aufs_bindex_t btop
, bbot
;
436 btop
= au_dbtop(dentry
);
437 bbot
= au_dbbot(dentry
);
439 AuDebugOn(bbot
< 0 && btop
> bbot
);
442 AuDebugOn(bbot
>= 0);
448 int au_digen_test(struct dentry
*dentry
, unsigned int sigen
)
453 if (unlikely(au_digen(dentry
) != sigen
454 || au_iigen_test(d_inode(dentry
), sigen
)))
460 void au_update_digen(struct dentry
*dentry
)
462 atomic_set(&au_di(dentry
)->di_generation
, au_sigen(dentry
->d_sb
));
463 /* smp_mb(); */ /* atomic_set */
466 void au_update_dbrange(struct dentry
*dentry
, int do_put_zero
)
468 struct au_dinfo
*dinfo
;
470 struct au_hdentry
*hdp
;
471 aufs_bindex_t bindex
, bbot
;
473 DiMustWriteLock(dentry
);
475 dinfo
= au_di(dentry
);
476 if (!dinfo
|| dinfo
->di_btop
< 0)
480 bbot
= dinfo
->di_bbot
;
481 bindex
= dinfo
->di_btop
;
482 hdp
= au_hdentry(dinfo
, bindex
);
483 for (; bindex
<= bbot
; bindex
++, hdp
++) {
484 h_d
= hdp
->hd_dentry
;
485 if (h_d
&& d_is_negative(h_d
))
486 au_set_h_dptr(dentry
, bindex
, NULL
);
491 hdp
= au_hdentry(dinfo
, dinfo
->di_btop
);
492 for (; dinfo
->di_btop
<= dinfo
->di_bbot
; dinfo
->di_btop
++, hdp
++)
495 if (dinfo
->di_btop
> dinfo
->di_bbot
) {
501 hdp
= au_hdentry(dinfo
, dinfo
->di_bbot
);
502 for (; dinfo
->di_bbot
>= 0; dinfo
->di_bbot
--, hdp
--)
505 AuDebugOn(dinfo
->di_btop
> dinfo
->di_bbot
|| dinfo
->di_bbot
< 0);
508 void au_update_dbtop(struct dentry
*dentry
)
510 aufs_bindex_t bindex
, bbot
;
511 struct dentry
*h_dentry
;
513 bbot
= au_dbbot(dentry
);
514 for (bindex
= au_dbtop(dentry
); bindex
<= bbot
; bindex
++) {
515 h_dentry
= au_h_dptr(dentry
, bindex
);
518 if (d_is_positive(h_dentry
)) {
519 au_set_dbtop(dentry
, bindex
);
522 au_set_h_dptr(dentry
, bindex
, NULL
);
526 void au_update_dbbot(struct dentry
*dentry
)
528 aufs_bindex_t bindex
, btop
;
529 struct dentry
*h_dentry
;
531 btop
= au_dbtop(dentry
);
532 for (bindex
= au_dbbot(dentry
); bindex
>= btop
; bindex
--) {
533 h_dentry
= au_h_dptr(dentry
, bindex
);
536 if (d_is_positive(h_dentry
)) {
537 au_set_dbbot(dentry
, bindex
);
540 au_set_h_dptr(dentry
, bindex
, NULL
);
544 int au_find_dbindex(struct dentry
*dentry
, struct dentry
*h_dentry
)
546 aufs_bindex_t bindex
, bbot
;
548 bbot
= au_dbbot(dentry
);
549 for (bindex
= au_dbtop(dentry
); bindex
<= bbot
; bindex
++)
550 if (au_h_dptr(dentry
, bindex
) == h_dentry
)