~ubuntu-branches/ubuntu/quantal/aufs/quantal

« back to all changes in this revision

Viewing changes to fs/aufs/vdir.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-04-01 18:26:37 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080401182637-ujuqq47eiggw4y5w
Tags: 0+20080401-1
* New upstream snapshot
  - Remove bashisms in script (Closes: #471288)
* debian/conf.mk, linux-patch-aufs.kpatches.sysfs_get_dentry:
  - Remove support for this patch, no longer used
* debian/conf.mk:
  - Add hacks for arm to armel (Closes: #473767)
* debian/control:
  - Add Dm-Upload-Allowed
* debian/copyright:
  - Use http://wiki.debian.org/Proposals/CopyrightFormat
* debian/linux-patch-aufs.kpatches.{splice,put_filp}:
  - Add support for Kernel 2.6.24 (and 2.6.25)
* debian/patches:
  - 01_vserver_apparmor: Update patch
  - 06_rt: Add patch for realtime kernel
  - 07_splice_hack: Add hack to support splice operations (Closes: #473430)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2005, 2006, 2007 Junjiro Okajima
 
2
 * Copyright (C) 2005, 2006, 2007, 2008 Junjiro Okajima
3
3
 *
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
17
17
 */
18
18
 
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 $ */
20
20
 
21
21
#include "aufs.h"
22
22
 
176
176
}
177
177
 
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,
 
180
                    unsigned char shwh)
180
181
{
181
182
        int err;
182
183
        struct aufs_destr *str;
190
191
                goto out;
191
192
        err = 0;
192
193
        wh->wh_bindex = bindex;
 
194
        if (unlikely(shwh))
 
195
                au_shwh_init_wh(wh, ino, d_type);
193
196
        str = &wh->wh_str;
194
197
        str->len = namelen;
195
198
        memcpy(str->name, name, namelen);
399
402
 
400
403
/* ---------------------------------------------------------------------- */
401
404
 
 
405
static int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
 
406
                  ino_t *ino)
 
407
{
 
408
        int err;
 
409
        struct xino_entry xinoe;
 
410
        static DEFINE_MUTEX(mtx);
 
411
 
 
412
        /* a race condition for hardlinks */
 
413
        mutex_lock(&mtx);
 
414
        err = xino_read(sb, bindex, h_ino, &xinoe);
 
415
        if (unlikely(err))
 
416
                goto out;
 
417
 
 
418
        if (!xinoe.ino) {
 
419
                //struct inode *h_inode;
 
420
                err = -EIO;
 
421
                xinoe.ino = xino_new_ino(sb);
 
422
                if (unlikely(!xinoe.ino))
 
423
                        goto out;
 
424
#if 0 // rfu
 
425
                //xinoe.h_gen = AuXino_INVALID_HGEN;
 
426
                h_inode = ilookup(sbr_sb(sb, bindex), h_ino);
 
427
                if (h_inode) {
 
428
                        if (!is_bad_inode(h_inode)) {
 
429
                                xinoe.h_gen = h_inode->i_generation;
 
430
                                WARN_ON(xinoe.h_gen == AuXino_INVALID_HGEN);
 
431
                        }
 
432
                        iput(h_inode);
 
433
                }
 
434
#endif
 
435
                err = xino_write(sb, bindex, h_ino, &xinoe);
 
436
                if (unlikely(err))
 
437
                        goto out;
 
438
        }
 
439
 
 
440
        *ino = xinoe.ino;
 
441
 
 
442
 out:
 
443
        mutex_unlock(&mtx);
 
444
        AuTraceErr(err);
 
445
        return err;
 
446
}
 
447
 
 
448
static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
 
449
                     ino_t *ino)
 
450
{
 
451
        int err;
 
452
 
 
453
        err = 0;
 
454
#ifdef CONFIG_AUFS_SHWH
 
455
        err = au_ino(sb, bindex, h_ino, ino);
 
456
#endif
 
457
        return err;
 
458
}
 
459
 
 
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; }
 
465
 
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;
 
472
        unsigned int            flags;
408
473
        int                     err;
409
 
        int                     called;
410
474
};
411
475
 
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;
 
483
        ino_t ino;
420
484
 
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;
426
490
        arg->err = 0;
427
 
        arg->called++;
 
491
        au_fset_fillvdir(arg->flags, CALLED);
428
492
        //smp_mb();
429
493
        if (namelen <= AUFS_WH_PFX_LEN
430
494
            || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
434
498
                                                   namelen))
435
499
                                goto out; /* already exists or whiteouted */
436
500
 
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))
442
 
                                arg->err = -EIO;
443
 
#if 0 // rfu
444
 
                        //xinoe.h_gen = AuXino_INVALID_HGEN;
445
 
                        h_inode = ilookup(sbr_sb(sb, bend), h_ino);
446
 
                        if (h_inode) {
447
 
                                if (!is_bad_inode(h_inode)) {
448
 
                                        xinoe.h_gen = h_inode->i_generation;
449
 
                                        WARN_ON(xinoe.h_gen
450
 
                                                == AuXino_INVALID_HGEN);
451
 
                                }
452
 
                                iput(h_inode);
453
 
                        }
454
 
#endif
455
 
                        arg->err = xino_write(sb, bend, h_ino, &xinoe);
456
 
                }
 
501
                ino = 1; /* why does gcc warns? */
 
502
                arg->err = au_ino(sb, bend, h_ino, &ino);
457
503
                if (!arg->err)
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);
461
507
        } else {
462
508
                name += AUFS_WH_PFX_LEN;
465
511
                        if (nhash_test_known_wh(arg->whlist + bend, name,
466
512
                                                namelen))
467
513
                                goto out; /* already whiteouted */
468
 
                arg->err = nhash_append_wh(arg->whlist + bend, name, namelen,
469
 
                                           bend);
 
514
 
 
515
                ino = 1; /* dummy */
 
516
                if (unlikely(au_ftest_fillvdir(arg->flags, SHWH)))
 
517
                        arg->err = au_wh_ino(sb, bend, h_ino, &ino);
 
518
                if (!arg->err)
 
519
                        arg->err = nhash_append_wh
 
520
                                (arg->whlist + bend, name, namelen, ino, d_type,
 
521
                                 bend, au_ftest_fillvdir(arg->flags, SHWH));
470
522
        }
471
523
 
472
524
 out:
477
529
        return arg->err;
478
530
}
479
531
 
 
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)
 
536
{
 
537
#ifdef CONFIG_AUFS_SHWH
 
538
        int err, i;
 
539
        struct hlist_head *head;
 
540
        struct aufs_wh *tpos;
 
541
        struct hlist_node *pos, *n;
 
542
        char *p, *o;
 
543
        struct aufs_nhash *whlist, *delist;
 
544
        struct aufs_destr *destr;
 
545
        aufs_bindex_t bindex;
 
546
 
 
547
        AuTraceEnter();
 
548
        AuDebugOn(!au_flag_test_shwh(sb));
 
549
 
 
550
        err = -ENOMEM;
 
551
        o = p = __getname();
 
552
        if (unlikely(!p))
 
553
                goto out;
 
554
 
 
555
        err = 0;
 
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;
 
561
 
 
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,
 
570
                                                delist);
 
571
                                if (unlikely(err))
 
572
                                        break;
 
573
                        }
 
574
                }
 
575
        }
 
576
 
 
577
        __putname(o);
 
578
 
 
579
 out:
 
580
        AuTraceErr(err);
 
581
        return err;
 
582
#else
 
583
        return 0;
 
584
#endif
 
585
}
 
586
 
480
587
static int read_vdir(struct file *file, int may_read)
481
588
{
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;
554
661
        dlgt = au_need_dlgt(sb);
555
662
        arg.file = file;
556
663
        arg.vdir = vdir;
 
664
        arg.flags = 0;
 
665
        shwh = 0;
 
666
        if (unlikely(au_flag_test_shwh(sb))) {
 
667
                shwh = 1;
 
668
                au_fset_fillvdir(arg.flags, SHWH);
 
669
        }
557
670
        bstart = fbstart(file);
558
671
        for (bindex = bstart; !err && bindex <= bend; bindex++) {
559
672
                struct file *hf;
570
683
                arg.bindex = bindex;
571
684
                do {
572
685
                        arg.err = 0;
573
 
                        arg.called = 0;
 
686
                        au_fclr_fillvdir(arg.flags, CALLED);
574
687
                        //smp_mb();
575
688
                        err = vfsub_readdir(hf, fillvdir, &arg, dlgt);
576
689
                        if (err >= 0)
577
690
                                err = arg.err;
578
 
                } while (!err && arg.called);
 
691
                } while (!err && au_ftest_fillvdir(arg.flags, CALLED));
579
692
        }
580
693
 
 
694
        if (unlikely(!err && shwh))
 
695
                err = au_handle_shwh(sb, vdir, bstart, bend, arg.whlist,
 
696
                                     arg.delist);
 
697
 
581
698
        for (bindex = bstart; bindex <= bend; bindex++) {
582
699
                free_dehlist(arg.delist + bindex);
583
700
                nhash_fin(arg.whlist + bindex);
594
711
                vdir->vd_last.p.deblk = vdir->vd_deblk[0];
595
712
                if (allocated)
596
713
                        set_ivdir(inode, allocated);
 
714
                //AuDbgVdir(vdir);
597
715
        } else if (allocated)
598
716
                au_vdir_free(allocated);
599
 
        //AuDbgVdir(vdir); goto out;
600
717
 
601
718
 out:
602
719
        AuTraceErr(err);