~ubuntu-branches/ubuntu/vivid/aufs/vivid

« 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-05-06 18:35:50 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080506183550-0b6c974kkgc46oeh
Tags: 0+20080506-1
* New upstream release, supports Kernel 2.6.25 (Closes: #479717)
* Fix building with older Kernels (Closes: #475042)
* Update the patches 01, 04 and 07 to also patch fs/aufs25

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2005, 2006, 2007, 2008 Junjiro Okajima
 
2
 * Copyright (C) 2005-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.35 2008/03/31 07:43:41 sfjro Exp $ */
 
19
/*
 
20
 * virtual or vertical directory
 
21
 *
 
22
 * $Id: vdir.c,v 1.37 2008/04/13 23:45:56 sfjro Exp $
 
23
 */
20
24
 
21
25
#include "aufs.h"
22
26
 
24
28
{
25
29
        int sz;
26
30
 
27
 
        sz = sizeof(struct aufs_de) + namelen;
 
31
        sz = sizeof(struct au_vdir_de) + namelen;
28
32
        if (sizeof(ino_t) == sizeof(long)) {
29
33
                const int mask = sizeof(ino_t) - 1;
30
34
                if (sz & mask) {
46
50
        return sz;
47
51
}
48
52
 
49
 
static int set_deblk_end(union aufs_deblk_p *p, union aufs_deblk_p *deblk_end)
 
53
static int set_deblk_end(union au_vdir_deblk_p *p,
 
54
                         union au_vdir_deblk_p *deblk_end)
50
55
{
51
56
        if (calc_size(0) <= deblk_end->p - p->p) {
52
57
                p->de->de_str.len = 0;
57
62
}
58
63
 
59
64
/* returns true or false */
60
 
static int is_deblk_end(union aufs_deblk_p *p, union aufs_deblk_p *deblk_end)
 
65
static int is_deblk_end(union au_vdir_deblk_p *p,
 
66
                        union au_vdir_deblk_p *deblk_end)
61
67
{
62
68
        if (calc_size(0) <= deblk_end->p - p->p)
63
69
                return !p->de->de_str.len;
64
70
        return 1;
65
71
}
66
72
 
67
 
static aufs_deblk_t *last_deblk(struct aufs_vdir *vdir)
 
73
static au_vdir_deblk_t *last_deblk(struct au_vdir *vdir)
68
74
{
69
75
        return vdir->vd_deblk[vdir->vd_nblk - 1];
70
76
}
71
77
 
72
 
void nhash_init(struct aufs_nhash *nhash)
 
78
void nhash_init(struct au_nhash *nhash)
73
79
{
74
80
        int i;
75
81
        for (i = 0; i < AuSize_NHASH; i++)
76
82
                INIT_HLIST_HEAD(nhash->heads + i);
77
83
}
78
84
 
79
 
struct aufs_nhash *nhash_new(gfp_t gfp)
 
85
struct au_nhash *nhash_new(gfp_t gfp)
80
86
{
81
 
        struct aufs_nhash *nhash;
 
87
        struct au_nhash *nhash;
82
88
 
83
89
        nhash = kmalloc(sizeof(*nhash), gfp);
84
90
        if (nhash) {
88
94
        return ERR_PTR(-ENOMEM);
89
95
}
90
96
 
91
 
void nhash_del(struct aufs_nhash *nhash)
 
97
void nhash_del(struct au_nhash *nhash)
92
98
{
93
99
        nhash_fin(nhash);
94
100
        kfree(nhash);
95
101
}
96
102
 
97
 
void nhash_move(struct aufs_nhash *dst, struct aufs_nhash *src)
 
103
void nhash_move(struct au_nhash *dst, struct au_nhash *src)
98
104
{
99
105
        int i;
100
106
 
116
122
 
117
123
/* ---------------------------------------------------------------------- */
118
124
 
119
 
void nhash_fin(struct aufs_nhash *whlist)
 
125
void nhash_fin(struct au_nhash *whlist)
120
126
{
121
127
        int i;
122
128
        struct hlist_head *head;
123
 
        struct aufs_wh *tpos;
 
129
        struct au_vdir_wh *tpos;
124
130
        struct hlist_node *pos, *n;
125
131
 
126
132
        AuTraceEnter();
134
140
        }
135
141
}
136
142
 
137
 
int nhash_test_longer_wh(struct aufs_nhash *whlist, aufs_bindex_t btgt,
138
 
                         int limit)
 
143
int nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, int limit)
139
144
{
140
145
        int n, i;
141
146
        struct hlist_head *head;
142
 
        struct aufs_wh *tpos;
 
147
        struct au_vdir_wh *tpos;
143
148
        struct hlist_node *pos;
144
149
 
145
150
        LKTRTrace("limit %d\n", limit);
156
161
}
157
162
 
158
163
/* returns found(true) or not */
159
 
int nhash_test_known_wh(struct aufs_nhash *whlist, char *name, int namelen)
 
164
int nhash_test_known_wh(struct au_nhash *whlist, char *name, int namelen)
160
165
{
161
166
        struct hlist_head *head;
162
 
        struct aufs_wh *tpos;
 
167
        struct au_vdir_wh *tpos;
163
168
        struct hlist_node *pos;
164
 
        struct aufs_destr *str;
 
169
        struct au_vdir_destr *str;
165
170
 
166
171
        LKTRTrace("%.*s\n", namelen, name);
167
172
 
175
180
        return 0;
176
181
}
177
182
 
178
 
int nhash_append_wh(struct aufs_nhash *whlist, char *name, int namelen,
 
183
int nhash_append_wh(struct au_nhash *whlist, char *name, int namelen,
179
184
                    ino_t ino, unsigned int d_type, aufs_bindex_t bindex,
180
185
                    unsigned char shwh)
181
186
{
182
187
        int err;
183
 
        struct aufs_destr *str;
184
 
        struct aufs_wh *wh;
 
188
        struct au_vdir_destr *str;
 
189
        struct au_vdir_wh *wh;
185
190
 
186
191
        LKTRTrace("%.*s\n", namelen, name);
187
192
 
207
212
 
208
213
/* ---------------------------------------------------------------------- */
209
214
 
210
 
void au_vdir_free(struct aufs_vdir *vdir)
 
215
void au_vdir_free(struct au_vdir *vdir)
211
216
{
212
 
        aufs_deblk_t **deblk;
 
217
        au_vdir_deblk_t **deblk;
213
218
 
214
219
        AuTraceEnter();
215
220
 
222
227
        au_cache_free_vdir(vdir);
223
228
}
224
229
 
225
 
static int append_deblk(struct aufs_vdir *vdir)
 
230
static int append_deblk(struct au_vdir *vdir)
226
231
{
227
232
        int err, sz, i;
228
 
        aufs_deblk_t **o;
229
 
        union aufs_deblk_p p, deblk_end;
 
233
        au_vdir_deblk_t **o;
 
234
        union au_vdir_deblk_p p, deblk_end;
230
235
 
231
236
        AuTraceEnter();
232
237
 
252
257
        return err;
253
258
}
254
259
 
255
 
static struct aufs_vdir *alloc_vdir(void)
 
260
static struct au_vdir *alloc_vdir(void)
256
261
{
257
 
        struct aufs_vdir *vdir;
 
262
        struct au_vdir *vdir;
258
263
        int err;
259
264
 
260
265
        AuTraceEnter();
284
289
        return vdir;
285
290
}
286
291
 
287
 
static int reinit_vdir(struct aufs_vdir *vdir)
 
292
static int reinit_vdir(struct au_vdir *vdir)
288
293
{
289
294
        int err;
290
 
        union aufs_deblk_p p, deblk_end;
 
295
        union au_vdir_deblk_p p, deblk_end;
291
296
 
292
297
        AuTraceEnter();
293
298
 
311
316
 
312
317
/* ---------------------------------------------------------------------- */
313
318
 
314
 
static void free_dehlist(struct aufs_nhash *dehlist)
 
319
static void free_dehlist(struct au_nhash *dehlist)
315
320
{
316
321
        int i;
317
322
        struct hlist_head *head;
318
 
        struct aufs_dehstr *tpos;
 
323
        struct au_vdir_dehstr *tpos;
319
324
        struct hlist_node *pos, *n;
320
325
 
321
326
        AuTraceEnter();
330
335
}
331
336
 
332
337
/* returns found(true) or not */
333
 
static int test_known(struct aufs_nhash *delist, char *name, int namelen)
 
338
static int test_known(struct au_nhash *delist, char *name, int namelen)
334
339
{
335
340
        struct hlist_head *head;
336
 
        struct aufs_dehstr *tpos;
 
341
        struct au_vdir_dehstr *tpos;
337
342
        struct hlist_node *pos;
338
 
        struct aufs_destr *str;
 
343
        struct au_vdir_destr *str;
339
344
 
340
345
        LKTRTrace("%.*s\n", namelen, name);
341
346
 
350
355
 
351
356
}
352
357
 
353
 
static int append_de(struct aufs_vdir *vdir, char *name, int namelen, ino_t ino,
354
 
                     unsigned int d_type, struct aufs_nhash *delist)
 
358
static int append_de(struct au_vdir *vdir, char *name, int namelen, ino_t ino,
 
359
                     unsigned int d_type, struct au_nhash *delist)
355
360
{
356
361
        int err, sz;
357
 
        union aufs_deblk_p p, *room, deblk_end;
358
 
        struct aufs_dehstr *dehstr;
 
362
        union au_vdir_deblk_p p, *room, deblk_end;
 
363
        struct au_vdir_dehstr *dehstr;
359
364
 
360
365
        LKTRTrace("%.*s %d, i%lu, dt%u\n", namelen, name, namelen, ino, d_type);
361
366
 
406
411
                  ino_t *ino)
407
412
{
408
413
        int err;
409
 
        struct xino_entry xinoe;
 
414
        struct au_xino_entry xinoe;
410
415
        static DEFINE_MUTEX(mtx);
411
416
 
412
417
        /* a race condition for hardlinks */
413
418
        mutex_lock(&mtx);
414
 
        err = xino_read(sb, bindex, h_ino, &xinoe);
 
419
        err = au_xino_read(sb, bindex, h_ino, &xinoe);
415
420
        if (unlikely(err))
416
421
                goto out;
417
422
 
418
423
        if (!xinoe.ino) {
419
424
                //struct inode *h_inode;
420
425
                err = -EIO;
421
 
                xinoe.ino = xino_new_ino(sb);
 
426
                xinoe.ino = au_xino_new_ino(sb);
422
427
                if (unlikely(!xinoe.ino))
423
428
                        goto out;
424
429
#if 0 // rfu
425
430
                //xinoe.h_gen = AuXino_INVALID_HGEN;
426
 
                h_inode = ilookup(sbr_sb(sb, bindex), h_ino);
 
431
                h_inode = ilookup(au_sbr_sb(sb, bindex), h_ino);
427
432
                if (h_inode) {
428
433
                        if (!is_bad_inode(h_inode)) {
429
434
                                xinoe.h_gen = h_inode->i_generation;
432
437
                        iput(h_inode);
433
438
                }
434
439
#endif
435
 
                err = xino_write(sb, bindex, h_ino, &xinoe);
 
440
                err = au_xino_write(sb, bindex, h_ino, &xinoe);
436
441
                if (unlikely(err))
437
442
                        goto out;
438
443
        }
445
450
        return err;
446
451
}
447
452
 
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
453
#ifdef CONFIG_AUFS_SHWH
455
 
        err = au_ino(sb, bindex, h_ino, ino);
 
454
static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
 
455
                     ino_t *ino)
 
456
{
 
457
        return au_ino(sb, bindex, h_ino, ino);
 
458
}
 
459
#else
 
460
static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
 
461
                     ino_t *ino)
 
462
{
 
463
        return 0;
 
464
}
456
465
#endif
457
 
        return err;
458
 
}
459
466
 
460
467
#define AuFillVdir_CALLED       1
461
468
#define AuFillVdir_SHWH         (1 << 1)
465
472
 
466
473
struct fillvdir_arg {
467
474
        struct file             *file;
468
 
        struct aufs_vdir        *vdir;
469
 
        struct aufs_nhash       *delist;
470
 
        struct aufs_nhash       *whlist;
 
475
        struct au_vdir  *vdir;
 
476
        struct au_nhash *delist;
 
477
        struct au_nhash *whlist;
471
478
        aufs_bindex_t           bindex;
472
479
        unsigned int            flags;
473
480
        int                     err;
501
508
                ino = 1; /* why does gcc warns? */
502
509
                arg->err = au_ino(sb, bend, h_ino, &ino);
503
510
                if (!arg->err)
504
 
                        arg->err = append_de
505
 
                                (arg->vdir, name, namelen, ino, d_type,
506
 
                                 arg->delist + bend);
 
511
                        arg->err = append_de(arg->vdir, name, namelen, ino,
 
512
                                             d_type, arg->delist + bend);
507
513
        } else {
508
514
                name += AUFS_WH_PFX_LEN;
509
515
                namelen -= AUFS_WH_PFX_LEN;
529
535
        return arg->err;
530
536
}
531
537
 
532
 
static int au_handle_shwh(struct super_block *sb, struct aufs_vdir *vdir,
 
538
static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
533
539
                          aufs_bindex_t bstart, aufs_bindex_t bend,
534
 
                          struct aufs_nhash *_whlist,
535
 
                          struct aufs_nhash *_delist)
 
540
                          struct au_nhash *_whlist, struct au_nhash *_delist)
536
541
{
537
542
#ifdef CONFIG_AUFS_SHWH
538
543
        int err, i;
539
544
        struct hlist_head *head;
540
 
        struct aufs_wh *tpos;
 
545
        struct au_vdir_wh *tpos;
541
546
        struct hlist_node *pos, *n;
542
547
        char *p, *o;
543
 
        struct aufs_nhash *whlist, *delist;
544
 
        struct aufs_destr *destr;
 
548
        struct au_nhash *whlist, *delist;
 
549
        struct au_vdir_destr *destr;
545
550
        aufs_bindex_t bindex;
546
551
 
547
552
        AuTraceEnter();
548
 
        AuDebugOn(!au_flag_test_shwh(sb));
 
553
        AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
549
554
 
550
555
        err = -ENOMEM;
551
556
        o = p = __getname();
589
594
        int err, do_read, dlgt, shwh;
590
595
        struct dentry *dentry;
591
596
        struct inode *inode;
592
 
        struct aufs_vdir *vdir, *allocated;
 
597
        struct au_vdir *vdir, *allocated;
593
598
        unsigned long expire;
594
599
        struct fillvdir_arg arg;
595
600
        aufs_bindex_t bindex, bend, bstart;
596
601
        struct super_block *sb;
 
602
        unsigned int mnt_flags;
597
603
 
598
604
        dentry = file->f_dentry;
599
605
        LKTRTrace("%.*s, may %d\n", AuDLNPair(dentry), may_read);
607
613
        allocated = NULL;
608
614
        do_read = 0;
609
615
        sb = inode->i_sb;
610
 
        expire = stosi(sb)->si_rdcache;
611
 
        vdir = ivdir(inode);
 
616
        expire = au_sbi(sb)->si_rdcache;
 
617
        vdir = au_ivdir(inode);
612
618
#if 0 // debug
613
619
        AuDbg("vdir %p, fvdir %p, i_ver %lu, vd_ver %lu, jiffy %lu,"
614
620
              " vd_jiffy %lu, expire %lu\n",
615
 
              vdir, fvdir_cache(file), inode->i_version,
 
621
              vdir, au_fvdir_cache(file), inode->i_version,
616
622
              vdir ? vdir->vd_version : 0LU, jiffies,
617
623
              vdir ? vdir->vd_jiffy + expire : 0LU, expire);
618
624
#endif
619
625
        if (!vdir) {
620
 
                AuDebugOn(fvdir_cache(file));
 
626
                AuDebugOn(au_fvdir_cache(file));
621
627
                do_read = 1;
622
628
                vdir = alloc_vdir();
623
629
                err = PTR_ERR(vdir);
645
651
                return 0; /* success */
646
652
 
647
653
        err = -ENOMEM;
648
 
        bend = fbend(file);
 
654
        bend = au_fbend(file);
649
655
        arg.delist = kmalloc(sizeof(*arg.delist) * (bend + 1), GFP_TEMPORARY);
650
656
        if (unlikely(!arg.delist))
651
657
                goto out_vdir;
658
664
                nhash_init(arg.whlist + bindex);
659
665
        }
660
666
 
661
 
        dlgt = au_need_dlgt(sb);
 
667
        mnt_flags = au_mntflags(sb);
 
668
        dlgt = !!au_opt_test_dlgt(mnt_flags);
662
669
        arg.file = file;
663
670
        arg.vdir = vdir;
664
671
        arg.flags = 0;
665
672
        shwh = 0;
666
 
        if (unlikely(au_flag_test_shwh(sb))) {
 
673
        if (unlikely(au_opt_test(mnt_flags, SHWH))) {
667
674
                shwh = 1;
668
675
                au_fset_fillvdir(arg.flags, SHWH);
669
676
        }
670
 
        bstart = fbstart(file);
 
677
        bstart = au_fbstart(file);
671
678
        for (bindex = bstart; !err && bindex <= bend; bindex++) {
672
679
                struct file *hf;
673
680
                loff_t offset;
710
717
                vdir->vd_last.i = 0;
711
718
                vdir->vd_last.p.deblk = vdir->vd_deblk[0];
712
719
                if (allocated)
713
 
                        set_ivdir(inode, allocated);
 
720
                        au_set_ivdir(inode, allocated);
714
721
                //AuDbgVdir(vdir);
715
722
        } else if (allocated)
716
723
                au_vdir_free(allocated);
720
727
        return err;
721
728
}
722
729
 
723
 
static int copy_vdir(struct aufs_vdir *tgt, struct aufs_vdir *src)
 
730
static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
724
731
{
725
732
        int err, i, rerr, n;
726
733
 
730
737
 
731
738
        err = -ENOMEM;
732
739
        if (tgt->vd_nblk < src->vd_nblk) {
733
 
                aufs_deblk_t **p;
 
740
                au_vdir_deblk_t **p;
734
741
                p = au_kzrealloc(tgt->vd_deblk, sizeof(*p) * tgt->vd_nblk,
735
742
                                 sizeof(*p) * src->vd_nblk, GFP_KERNEL);
736
743
                if (unlikely(!p))
770
777
        int err;
771
778
        struct dentry *dentry;
772
779
        struct inode *inode;
773
 
        struct aufs_vdir *vdir_cache, *allocated;
 
780
        struct au_vdir *vdir_cache, *allocated;
774
781
 
775
782
        dentry = file->f_dentry;
776
783
        LKTRTrace("%.*s, pos %Ld\n", AuDLNPair(dentry), file->f_pos);
782
789
        err = read_vdir(file, !file->f_pos);
783
790
        if (unlikely(err))
784
791
                goto out;
785
 
        //AuDbgVdir(ivdir(inode)); goto out;
 
792
        //AuDbgVdir(au_ivdir(inode)); goto out;
786
793
 
787
794
        allocated = NULL;
788
 
        vdir_cache = fvdir_cache(file);
 
795
        vdir_cache = au_fvdir_cache(file);
789
796
        if (!vdir_cache) {
790
797
                vdir_cache = alloc_vdir();
791
798
                err = PTR_ERR(vdir_cache);
800
807
                return 0; /* success */
801
808
        //err = 0; AuDbgVdir(vdir_cache); goto out;
802
809
 
803
 
        err = copy_vdir(vdir_cache, ivdir(inode));
 
810
        err = copy_vdir(vdir_cache, au_ivdir(inode));
804
811
        if (!err) {
805
812
                file->f_version = inode->i_version;
806
813
                if (allocated)
807
 
                        set_fvdir_cache(file, allocated);
 
814
                        au_set_fvdir_cache(file, allocated);
808
815
        } else if (allocated)
809
816
                au_vdir_free(allocated);
810
817
 
815
822
        return err;
816
823
}
817
824
 
818
 
static loff_t calc_offset(struct aufs_vdir *vdir)
 
825
static loff_t calc_offset(struct au_vdir *vdir)
819
826
{
820
827
        loff_t offset;
821
 
        union aufs_deblk_p p;
 
828
        union au_vdir_deblk_p p;
822
829
 
823
830
        p.deblk = vdir->vd_deblk[vdir->vd_last.i];
824
831
        offset = vdir->vd_last.p.p - p.p;
831
838
{
832
839
        int valid, i, n;
833
840
        struct dentry *dentry;
834
 
        struct aufs_vdir *vdir_cache;
 
841
        struct au_vdir *vdir_cache;
835
842
        loff_t offset;
836
 
        union aufs_deblk_p p, deblk_end;
 
843
        union au_vdir_deblk_p p, deblk_end;
837
844
 
838
845
        dentry = file->f_dentry;
839
846
        LKTRTrace("%.*s, pos %Ld\n", AuDLNPair(dentry), file->f_pos);
840
 
        vdir_cache = fvdir_cache(file);
 
847
        vdir_cache = au_fvdir_cache(file);
841
848
        AuDebugOn(!vdir_cache);
842
849
        //AuDbgVdir(vdir_cache);
843
850
 
888
895
{
889
896
        int err, l;
890
897
        struct dentry *dentry;
891
 
        struct aufs_vdir *vdir_cache;
892
 
        struct aufs_de *de;
893
 
        union aufs_deblk_p deblk_end;
 
898
        struct au_vdir *vdir_cache;
 
899
        struct au_vdir_de *de;
 
900
        union au_vdir_deblk_p deblk_end;
894
901
 
895
902
        dentry = file->f_dentry;
896
903
        LKTRTrace("%.*s, pos %Ld\n", AuDLNPair(dentry), file->f_pos);
897
 
        vdir_cache = fvdir_cache(file);
 
904
        vdir_cache = au_fvdir_cache(file);
898
905
        AuDebugOn(!vdir_cache);
899
906
        //AuDbgVdir(vdir_cache);
900
907