2
* Copyright (C) 2005, 2006, 2007 Junjiro Okajima
2
* Copyright (C) 2005, 2006, 2007, 2008 Junjiro Okajima
4
4
* This program, aufs is free software; you can redistribute it and/or modify
5
5
* it under the terms of the GNU General Public License as published by
16
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
/* $Id: vdir.c,v 1.31 2007/12/10 01:19:07 sfjro Exp $ */
19
/* $Id: vdir.c,v 1.35 2008/03/31 07:43:41 sfjro Exp $ */
178
178
int nhash_append_wh(struct aufs_nhash *whlist, char *name, int namelen,
179
aufs_bindex_t bindex)
179
ino_t ino, unsigned int d_type, aufs_bindex_t bindex,
182
183
struct aufs_destr *str;
400
403
/* ---------------------------------------------------------------------- */
405
static int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
409
struct xino_entry xinoe;
410
static DEFINE_MUTEX(mtx);
412
/* a race condition for hardlinks */
414
err = xino_read(sb, bindex, h_ino, &xinoe);
419
//struct inode *h_inode;
421
xinoe.ino = xino_new_ino(sb);
422
if (unlikely(!xinoe.ino))
425
//xinoe.h_gen = AuXino_INVALID_HGEN;
426
h_inode = ilookup(sbr_sb(sb, bindex), h_ino);
428
if (!is_bad_inode(h_inode)) {
429
xinoe.h_gen = h_inode->i_generation;
430
WARN_ON(xinoe.h_gen == AuXino_INVALID_HGEN);
435
err = xino_write(sb, bindex, h_ino, &xinoe);
448
static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
454
#ifdef CONFIG_AUFS_SHWH
455
err = au_ino(sb, bindex, h_ino, ino);
460
#define AuFillVdir_CALLED 1
461
#define AuFillVdir_SHWH (1 << 1)
462
#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
463
#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; }
464
#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; }
402
466
struct fillvdir_arg {
403
467
struct file *file;
404
468
struct aufs_vdir *vdir;
405
469
struct aufs_nhash *delist;
406
470
struct aufs_nhash *whlist;
407
471
aufs_bindex_t bindex;
412
476
static int fillvdir(void *__arg, const char *__name, int namelen, loff_t offset,
415
479
struct fillvdir_arg *arg = __arg;
416
480
char *name = (void *)__name;
417
481
aufs_bindex_t bindex, bend;
418
struct xino_entry xinoe;
419
482
struct super_block *sb;
421
485
LKTRTrace("%.*s, namelen %d, i%Lu, dt%u\n",
422
486
namelen, name, namelen, (u64)h_ino, d_type);
424
488
sb = arg->file->f_dentry->d_sb;
425
489
bend = arg->bindex;
491
au_fset_fillvdir(arg->flags, CALLED);
429
493
if (namelen <= AUFS_WH_PFX_LEN
430
494
|| memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
435
499
goto out; /* already exists or whiteouted */
437
arg->err = xino_read(sb, bend, h_ino, &xinoe);
438
if (!arg->err && !xinoe.ino) {
439
//struct inode *h_inode;
440
xinoe.ino = xino_new_ino(sb);
441
if (unlikely(!xinoe.ino))
444
//xinoe.h_gen = AuXino_INVALID_HGEN;
445
h_inode = ilookup(sbr_sb(sb, bend), h_ino);
447
if (!is_bad_inode(h_inode)) {
448
xinoe.h_gen = h_inode->i_generation;
450
== AuXino_INVALID_HGEN);
455
arg->err = xino_write(sb, bend, h_ino, &xinoe);
501
ino = 1; /* why does gcc warns? */
502
arg->err = au_ino(sb, bend, h_ino, &ino);
458
504
arg->err = append_de
459
(arg->vdir, name, namelen, xinoe.ino, d_type,
505
(arg->vdir, name, namelen, ino, d_type,
460
506
arg->delist + bend);
462
508
name += AUFS_WH_PFX_LEN;
465
511
if (nhash_test_known_wh(arg->whlist + bend, name,
467
513
goto out; /* already whiteouted */
468
arg->err = nhash_append_wh(arg->whlist + bend, name, namelen,
516
if (unlikely(au_ftest_fillvdir(arg->flags, SHWH)))
517
arg->err = au_wh_ino(sb, bend, h_ino, &ino);
519
arg->err = nhash_append_wh
520
(arg->whlist + bend, name, namelen, ino, d_type,
521
bend, au_ftest_fillvdir(arg->flags, SHWH));
532
static int au_handle_shwh(struct super_block *sb, struct aufs_vdir *vdir,
533
aufs_bindex_t bstart, aufs_bindex_t bend,
534
struct aufs_nhash *_whlist,
535
struct aufs_nhash *_delist)
537
#ifdef CONFIG_AUFS_SHWH
539
struct hlist_head *head;
540
struct aufs_wh *tpos;
541
struct hlist_node *pos, *n;
543
struct aufs_nhash *whlist, *delist;
544
struct aufs_destr *destr;
545
aufs_bindex_t bindex;
548
AuDebugOn(!au_flag_test_shwh(sb));
556
memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
557
p += AUFS_WH_PFX_LEN;
558
for (bindex = bstart; !err && bindex <= bend; bindex++) {
559
whlist = _whlist + bindex;
560
delist = _delist + bindex;
562
for (i = 0; i < AuSize_NHASH; i++) {
563
head = whlist->heads + i;
564
hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) {
565
destr = &tpos->wh_str;
566
memcpy(p, destr->name, destr->len);
567
err = append_de(vdir, o,
568
destr->len + AUFS_WH_PFX_LEN,
569
tpos->wh_ino, tpos->wh_type,
480
587
static int read_vdir(struct file *file, int may_read)
482
int err, do_read, dlgt;
589
int err, do_read, dlgt, shwh;
483
590
struct dentry *dentry;
484
591
struct inode *inode;
485
592
struct aufs_vdir *vdir, *allocated;
570
683
arg.bindex = bindex;
686
au_fclr_fillvdir(arg.flags, CALLED);
575
688
err = vfsub_readdir(hf, fillvdir, &arg, dlgt);
578
} while (!err && arg.called);
691
} while (!err && au_ftest_fillvdir(arg.flags, CALLED));
694
if (unlikely(!err && shwh))
695
err = au_handle_shwh(sb, vdir, bstart, bend, arg.whlist,
581
698
for (bindex = bstart; bindex <= bend; bindex++) {
582
699
free_dehlist(arg.delist + bindex);
583
700
nhash_fin(arg.whlist + bindex);