~ubuntu-branches/ubuntu/raring/aufs/raring

« back to all changes in this revision

Viewing changes to fs/aufs/i_op.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-05-06 18:35:50 UTC
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20080506183550-7y7mrzkzkh2tjlfu
Tags: upstream-0+20080506
ImportĀ upstreamĀ versionĀ 0+20080506

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: i_op.c,v 1.58 2008/03/31 07:42:17 sfjro Exp $ */
 
19
/*
 
20
 * inode operations (except add/del/rename)
 
21
 *
 
22
 * $Id: i_op.c,v 1.60 2008/04/13 23:42:10 sfjro Exp $
 
23
 */
20
24
 
21
25
//#include <linux/fs.h>
22
26
//#include <linux/namei.h>
23
27
#include <linux/mm.h>
24
 
#include <linux/security.h>
25
28
#include "aufs.h"
26
29
 
27
 
#ifdef CONFIG_AUFS_DLGT
28
 
struct security_inode_permission_args {
29
 
        int *errp;
30
 
        struct inode *h_inode;
31
 
        int mask;
32
 
        struct nameidata *fake_nd;
33
 
};
34
 
 
35
 
static void call_security_inode_permission(void *args)
36
 
{
37
 
        struct security_inode_permission_args *a = args;
38
 
        LKTRTrace("fsuid %d\n", current->fsuid);
39
 
        *a->errp = security_inode_permission(a->h_inode, a->mask, a->fake_nd);
40
 
}
41
 
#endif /* CONFIG_AUFS_DLGT */
42
 
 
43
30
static int h_permission(struct inode *h_inode, int mask,
44
31
                        struct nameidata *fake_nd, int brperm, int dlgt)
45
32
{
59
46
 
60
47
        /* skip hidden fs test in the case of write to ro branch */
61
48
        submask = mask & ~MAY_APPEND;
62
 
        if (unlikely((write_mask && !br_writable(brperm))
 
49
        if (unlikely((write_mask && !au_br_writable(brperm))
63
50
                     || !h_inode->i_op
64
51
                     || !h_inode->i_op->permission)) {
65
52
                //LKTRLabel(generic_permission);
71
58
        }
72
59
 
73
60
#if 1
74
 
        if (!err) {
75
 
#ifndef CONFIG_AUFS_DLGT
76
 
                err = security_inode_permission(h_inode, mask, fake_nd);
77
 
#else
78
 
                if (!dlgt)
79
 
                        err = security_inode_permission(h_inode, mask,
80
 
                                                        fake_nd);
81
 
                else {
82
 
                        int wkq_err;
83
 
                        struct security_inode_permission_args args = {
84
 
                                .errp           = &err,
85
 
                                .h_inode        = h_inode,
86
 
                                .mask           = mask,
87
 
                                .fake_nd        = fake_nd
88
 
                        };
89
 
                        wkq_err = au_wkq_wait(call_security_inode_permission,
90
 
                                              &args, /*dlgt*/1);
91
 
                        if (unlikely(wkq_err))
92
 
                                err = wkq_err;
93
 
                }
94
 
#endif /* CONFIG_AUFS_DLGT */
95
 
        }
 
61
        if (!err)
 
62
                err = au_security_inode_permission(h_inode, mask, fake_nd,
 
63
                                                   dlgt);
96
64
#endif
97
65
 
98
66
 out:
176
144
        aufs_bindex_t bindex, bend;
177
145
        struct inode *h_inode;
178
146
        struct super_block *sb;
 
147
        unsigned int mnt_flags;
179
148
        struct nameidata fake_nd, *p;
180
149
        const int write_mask = (mask & (MAY_WRITE | MAY_APPEND));
181
150
        const int nondir = !S_ISDIR(inode->i_mode);
187
156
 
188
157
        sb = inode->i_sb;
189
158
        locked = silly_lock(inode, nd);
190
 
        dlgt = au_need_dlgt(sb);
 
159
        mnt_flags = au_mntflags(sb);
 
160
        dlgt = !!au_opt_test_dlgt(mnt_flags);
191
161
 
192
162
        if (nd)
193
163
                fake_nd = *nd;
194
 
        if (/* unlikely */(nondir || write_mask || au_need_dirperm1(sb))) {
 
164
        if (/* unlikely */(nondir || write_mask
 
165
                           || au_opt_test_dirperm1(mnt_flags))) {
195
166
                h_inode = au_h_iptr(inode);
196
167
                AuDebugOn(!h_inode
197
168
                          || ((h_inode->i_mode & S_IFMT)
198
169
                              != (inode->i_mode & S_IFMT)));
199
170
                err = 0;
200
 
                bindex = ibstart(inode);
 
171
                bindex = au_ibstart(inode);
201
172
                p = au_fake_dm(&fake_nd, nd, sb, bindex);
202
173
                /* actual test will be delegated to LSM */
203
174
                if (IS_ERR(p))
205
176
                else {
206
177
                        LKTRTrace("b%d\n", bindex);
207
178
                        err = h_permission(h_inode, mask, p,
208
 
                                           sbr_perm(sb, bindex), dlgt);
 
179
                                           au_sbr_perm(sb, bindex), dlgt);
209
180
                        au_fake_dm_release(p);
210
181
                }
211
182
                if (write_mask && !err) {
212
183
                        /* test whether the upper writable branch exists */
213
184
                        err = -EROFS;
214
185
                        for (; bindex >= 0; bindex--)
215
 
                                if (!br_rdonly(stobr(sb, bindex))) {
 
186
                                if (!au_br_rdonly(au_sbr(sb, bindex))) {
216
187
                                        err = 0;
217
188
                                        break;
218
189
                                }
222
193
 
223
194
        /* non-write to dir */
224
195
        err = 0;
225
 
        bend = ibend(inode);
226
 
        for (bindex = ibstart(inode); !err && bindex <= bend; bindex++) {
 
196
        bend = au_ibend(inode);
 
197
        for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
227
198
                h_inode = au_h_iptr_i(inode, bindex);
228
199
                if (!h_inode)
229
200
                        continue;
236
207
                else {
237
208
                        LKTRTrace("b%d\n", bindex);
238
209
                        err = h_permission(h_inode, mask, p,
239
 
                                           sbr_perm(sb, bindex), dlgt);
 
210
                                           au_sbr_perm(sb, bindex), dlgt);
240
211
                        au_fake_dm_release(p);
241
212
                }
242
213
        }
272
243
        if (unlikely(err))
273
244
                goto out;
274
245
 
275
 
        ndp = au_dup_nd(stosi(dir->i_sb), &tmp_nd, nd);
276
 
        npositive = au_lkup_dentry(dentry, dbstart(parent), /*type*/0, ndp);
 
246
        ndp = au_dup_nd(au_sbi(dir->i_sb), &tmp_nd, nd);
 
247
        npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, ndp);
277
248
        err = npositive;
278
249
        //err = -1;
279
250
        ret = ERR_PTR(err);
337
308
        struct super_block *sb;
338
309
        struct dentry *parent, *src_parent = NULL, *h_parent;
339
310
        struct inode *dir, *src_dir = NULL;
340
 
        struct aufs_sbinfo *sbinfo;
 
311
        struct au_sbinfo *sbinfo;
341
312
        const int add_entry = au_ftest_wrdir(args->flags, ADD_ENTRY);
342
313
        const int lock_srcdir = au_ftest_wrdir(args->flags, LOCK_SRCDIR);
343
314
 
346
317
        //AuDbgDentry(dentry);
347
318
 
348
319
        sb = dentry->d_sb;
349
 
        sbinfo = stosi(sb);
 
320
        sbinfo = au_sbi(sb);
350
321
        parent = dget_parent(dentry);
351
 
        bstart = dbstart(dentry);
 
322
        bstart = au_dbstart(dentry);
352
323
        bcpup = bstart;
353
324
        if (args->force_btgt < 0) {
354
325
                if (src_dentry) {
355
 
                        src_bstart = dbstart(src_dentry);
 
326
                        src_bstart = au_dbstart(src_dentry);
356
327
                        if (src_bstart < bstart)
357
328
                                bcpup = src_bstart;
358
329
                } else if (add_entry) {
418
389
                err = au_lkup_neg(dentry, bcpup);
419
390
                //err = -1;
420
391
                vfsub_i_unlock(h_parent->d_inode);
421
 
                if (bstart < bcpup && dbstart(dentry) < 0) {
422
 
                        set_dbstart(dentry, 0);
 
392
                if (bstart < bcpup && au_dbstart(dentry) < 0) {
 
393
                        au_set_dbstart(dentry, 0);
423
394
                        au_update_dbrange(dentry, /*do_put_zero*/0);
424
395
                }
425
396
        }
447
418
        if (!isdir)
448
419
                vfsub_i_lock_nested(h_inode, AuLsc_I_CHILD);
449
420
        else
450
 
                hdir2_lock(h_inode, inode, bindex);
 
421
                au_hdir2_lock(h_inode, inode, bindex);
451
422
}
452
423
 
453
424
static void au_hi_unlock(struct inode *h_inode, int isdir, struct inode *inode,
456
427
        if (!isdir)
457
428
                vfsub_i_unlock(h_inode);
458
429
        else
459
 
                hdir_unlock(h_inode, inode, bindex);
 
430
                au_hdir_unlock(h_inode, inode, bindex);
460
431
}
461
432
 
462
433
struct au_icpup_args {
463
434
        aufs_bindex_t btgt;
464
435
        unsigned char isdir, did_cpup; /* flags */
465
 
        unsigned int udba;
 
436
        unsigned char hinotify;
466
437
        struct dentry *parent, *gparent, *h_dentry;
467
438
        struct inode *dir, *gdir, *h_inode, *h_dir;
468
439
};
483
454
        LKTRTrace("%.*s, %lld\n", AuDLNPair(dentry), sz);
484
455
 
485
456
        di_write_lock_child(dentry);
486
 
        bstart = dbstart(dentry);
 
457
        bstart = au_dbstart(dentry);
487
458
        sb = dentry->d_sb;
488
459
        inode = dentry->d_inode;
489
460
        rargs->isdir = S_ISDIR(inode->i_mode);
498
469
        err = 0;
499
470
 
500
471
        /* crazy udba locks */
501
 
        rargs->udba = au_flag_test_udba_inotify(sb);
 
472
        rargs->hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY);
502
473
        if (unlikely(!IS_ROOT(dentry))) {
503
474
                rargs->parent = dget_parent(dentry);
504
475
                rargs->dir = rargs->parent->d_inode;
513
484
                goto out; /* success */
514
485
        }
515
486
 
516
 
        if (unlikely(rargs->udba
 
487
        if (unlikely(rargs->hinotify
517
488
                     && rargs->parent
518
489
                     && !IS_ROOT(rargs->parent))) {
519
490
                rargs->gparent = dget_parent(rargs->parent);
523
494
 
524
495
        hi_wh = NULL;
525
496
        rargs->h_dir = au_h_iptr_i(rargs->dir, rargs->btgt);
526
 
        hdir_lock(rargs->h_dir, rargs->dir, rargs->btgt);
 
497
        au_hdir_lock(rargs->h_dir, rargs->dir, rargs->btgt);
527
498
        au_hi_lock(rargs->h_inode, rargs->isdir, inode, bstart);
528
499
        if (!d_unhashed(dentry)) {
529
500
                err = au_sio_cpup_simple(dentry, rargs->btgt, sz, AuCpup_DTIME);
552
523
        AuDebugOn(!rargs->h_inode);
553
524
        if (!err)
554
525
                au_hi_lock(rargs->h_inode, rargs->isdir, inode, rargs->btgt);
555
 
        hdir_unlock(rargs->h_dir, rargs->dir, rargs->btgt);
 
526
        au_hdir_unlock(rargs->h_dir, rargs->dir, rargs->btgt);
556
527
        if (!err)
557
528
                goto out; /* success */
558
529
 
582
553
        struct dentry *dentry;
583
554
        struct au_icpup_args rargs;
584
555
 
585
 
        LKTRTrace("i%lu, 0x%x, %lld, %lld\n",
586
 
                  inode->i_ino, mode, offset, len);
 
556
        LKTRTrace("i%lu, 0x%x, %lld, %lld\n", inode->i_ino, mode, offset, len);
587
557
 
588
558
        sb = inode->i_sb;
589
559
        si_read_lock(sb, AuLock_FLUSH);
636
606
{
637
607
        int err;
638
608
        struct inode *inode;
639
 
        struct aufs_hin_ignore ign;
 
609
        struct au_hin_ignore ign;
640
610
        struct vfsub_args vargs;
641
611
        struct super_block *sb;
642
612
        __u32 events;
668
638
        if (unlikely(err < 0))
669
639
                goto out;
670
640
 
671
 
#if 0
672
 
        di_write_lock_child(dentry);
673
 
        bstart = dbstart(dentry);
674
 
        if (S_ISDIR(dentry->d_inode->i_mode))
675
 
                au_fset_wrdir(wr_dir_args.flags, ISDIR);
676
 
        err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
677
 
        bcpup = err;
678
 
        //err = -1;
679
 
        if (unlikely(err < 0))
680
 
                goto out;
681
 
 
682
 
        /* crazy udba locks */
683
 
        udba = au_flag_test_udba_inotify(sb);
684
 
        parent = NULL;
685
 
        dir = NULL;
686
 
        if (!IS_ROOT(dentry)) {
687
 
                parent = dget_parent(dentry);
688
 
                dir = parent->d_inode;
689
 
                di_read_lock_parent(parent, AuLock_IR);
690
 
        }
691
 
        //todo: meaningless lock if CONFIG_AUFS_DEBUG is disabled.
692
 
        gparent = NULL;
693
 
        gdir = NULL;
694
 
        if (unlikely(udba && parent && !IS_ROOT(parent))) {
695
 
                gparent = dget_parent(parent);
696
 
                gdir = gparent->d_inode;
697
 
                ii_read_lock_parent2(gdir);
698
 
        }
699
 
 
700
 
        h_dentry = au_h_dptr(dentry);
701
 
        h_inode = h_dentry->d_inode;
702
 
        AuDebugOn(!h_inode);
703
 
 
704
 
#define HiLock(bindex) \
705
 
        do { \
706
 
                if (!au_ftest_wrdir(wr_dir_args.flags, ISDIR)) \
707
 
                        vfsub_i_lock_nested(h_inode, AuLsc_I_CHILD); \
708
 
                else \
709
 
                        hdir2_lock(h_inode, inode, bindex); \
710
 
        } while (0)
711
 
#define HiUnlock(bindex) \
712
 
        do { \
713
 
                if (!au_ftest_wrdir(wr_dir_args.flags, ISDIR)) \
714
 
                        vfsub_i_unlock(h_inode); \
715
 
                else \
716
 
                        hdir_unlock(h_inode, inode, bindex); \
717
 
        } while (0)
718
 
 
719
 
        if (bstart != bcpup) {
720
 
                loff_t size = -1;
721
 
 
722
 
                /* do not drop ATTR_SIZE here, to call vmtruncate() */
723
 
                if ((ia->ia_valid & ATTR_SIZE)
724
 
                    && ia->ia_size < i_size_read(inode))
725
 
                        size = ia->ia_size;
726
 
                hi_wh = NULL;
727
 
                h_dir = au_h_iptr_i(dir, bcpup);
728
 
                hdir_lock(h_dir, dir, bcpup);
729
 
                HiLock(bstart);
730
 
                if (!d_unhashed(dentry))
731
 
                        err = au_sio_cpup_simple(dentry, bcpup, size,
732
 
                                                 AuCpup_DTIME);
733
 
                else {
734
 
                        hi_wh = au_hi_wh(inode, bcpup);
735
 
                        if (!hi_wh) {
736
 
                                err = au_sio_cpup_wh(dentry, bcpup, size,
737
 
                                                     /*file*/NULL);
738
 
                                if (!err)
739
 
                                        hi_wh = au_hi_wh(inode, bcpup);
740
 
                        }
741
 
#if 0
742
 
                        revalidate hi_wh
743
 
#endif
744
 
                }
745
 
 
746
 
                //err = -1;
747
 
                HiUnlock(bstart);
748
 
                hdir_unlock(h_dir, dir, bcpup);
749
 
                if (unlikely(err))
750
 
                        goto out_unlock;
751
 
 
752
 
                if (!hi_wh)
753
 
                        h_dentry = au_h_dptr(dentry);
754
 
                else
755
 
                        h_dentry = hi_wh; /* do not dget here */
756
 
                h_inode = h_dentry->d_inode;
757
 
                AuDebugOn(!h_inode);
758
 
                ia->ia_valid &= ~ATTR_FILE;
759
 
        }
760
 
#endif
761
 
 
762
641
        if ((ia->ia_valid & ATTR_SIZE)
763
642
            && ia->ia_size < i_size_read(inode)) {
764
643
                err = vmtruncate(inode, ia->ia_size);
772
651
#endif
773
652
 
774
653
        events = 0;
775
 
        vfsub_args_init(&vargs, &ign, au_need_dlgt(sb), 0);
776
 
        if (unlikely(rargs.udba && rargs.dir)) {
 
654
        vfsub_args_init(&vargs, &ign, au_opt_test_dlgt(au_mntflags(sb)), 0);
 
655
        if (unlikely(rargs.hinotify && rargs.dir)) {
777
656
                events = vfsub_events_notify_change(ia);
778
657
                if (events)
779
658
                        vfsub_ign_hinode(&vargs, events,
780
 
                                         itohi(rargs.dir, rargs.btgt));
 
659
                                         au_hi(rargs.dir, rargs.btgt));
781
660
        }
782
661
        err = vfsub_notify_change(rargs.h_dentry, ia, &vargs);
783
662
        //err = -1;
806
685
        return err;
807
686
}
808
687
 
809
 
/* currently, for fuse only */
810
 
#ifdef CONFIG_AUFS_WORKAROUND_FUSE
811
 
static int aufs_getattr(struct vfsmount *mnt, struct dentry *dentry,
812
 
                        struct kstat *st)
813
 
{
814
 
        int err;
815
 
        struct inode *inode, *h_inode;
816
 
        struct dentry *h_dentry;
817
 
 
818
 
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
819
 
 
820
 
        err = 0;
821
 
        aufs_read_lock(dentry, AuLock_IR);
822
 
        inode = dentry->d_inode;
823
 
        h_inode = au_h_iptr(inode);
824
 
        if (unlikely(au_test_fuse(h_inode->i_sb))) {
825
 
                h_dentry = d_find_alias(h_inode);
826
 
                /* simply gave up updating fuse inode */
827
 
                if (h_dentry) {
828
 
                        /*ignore*/
829
 
                        if (!au_update_fuse_h_inode(NULL, h_dentry))
830
 
                                au_cpup_attr_all(inode);
831
 
                        dput(h_dentry);
832
 
                }
833
 
        }
834
 
        generic_fillattr(inode, st);
835
 
 
836
 
        aufs_read_unlock(dentry, AuLock_IR);
837
 
        return err;
838
 
}
839
 
#endif /* CONFIG_AUFS_WORKAROUND_FUSE */
840
 
 
841
688
/* ---------------------------------------------------------------------- */
842
689
 
843
690
static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
855
702
 
856
703
        sb = dentry->d_sb;
857
704
        if (!au_test_ro(sb, bindex, dentry->d_inode)) {
858
 
                touch_atime(sbr_mnt(sb, bindex), h_dentry);
 
705
                touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
859
706
                au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/
860
707
                dentry->d_inode->i_atime = h_dentry->d_inode->i_atime;
861
708
        }
869
716
        LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), bufsiz);
870
717
 
871
718
        aufs_read_lock(dentry, AuLock_IR);
872
 
        err = h_readlink(dentry, dbstart(dentry), buf, bufsiz);
 
719
        err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
873
720
        //err = -1;
874
721
        aufs_read_unlock(dentry, AuLock_IR);
875
722
        AuTraceErr(err);
893
740
        aufs_read_lock(dentry, AuLock_IR);
894
741
        old_fs = get_fs();
895
742
        set_fs(KERNEL_DS);
896
 
        err = h_readlink(dentry, dbstart(dentry), (char __user *)buf, PATH_MAX);
 
743
        err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf,
 
744
                         PATH_MAX);
897
745
        //err = -1;
898
746
        set_fs(old_fs);
899
747
        aufs_read_unlock(dentry, AuLock_IR);