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

« back to all changes in this revision

Viewing changes to fs/aufs25/i_op.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-08-21 14:58:54 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20080821145854-a2qpyyfjwtbmarqj
Tags: upstream-0+20080719
ImportĀ upstreamĀ versionĀ 0+20080719

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
/*
20
20
 * inode operations (except add/del/rename)
21
21
 *
22
 
 * $Id: i_op.c,v 1.8 2008/06/09 01:10:26 sfjro Exp $
 
22
 * $Id: i_op.c,v 1.12 2008/07/14 00:15:45 sfjro Exp $
23
23
 */
24
24
 
25
25
#include <linux/fs_stack.h>
113
113
                si_read_unlock(sb);
114
114
                break;
115
115
        case 2:
116
 
                aufs_read_unlock(nd->path.dentry, AuLock_FLUSH | AuLock_IR);
 
116
                aufs_read_unlock(nd->path.dentry, AuLock_IR);
117
117
                break;
118
118
        default:
119
119
                BUG();
122
122
 
123
123
static int aufs_permission(struct inode *inode, int mask, struct nameidata *nd)
124
124
{
125
 
        int err, locked, dlgt;
 
125
        int err;
126
126
        aufs_bindex_t bindex, bend;
 
127
        unsigned char locked, dlgt;
127
128
        struct inode *h_inode;
128
129
        struct super_block *sb;
129
130
        unsigned int mnt_flags;
 
131
        /* todo: use nd directly instead of fake_nd */
130
132
        struct nameidata fake_nd, *p;
131
133
        const int write_mask = (mask & (MAY_WRITE | MAY_APPEND));
132
 
        const int nondir = !S_ISDIR(inode->i_mode);
 
134
        const unsigned char nondir = !S_ISDIR(inode->i_mode);
133
135
 
134
136
        LKTRTrace("ino %lu, mask 0x%x, nondir %d, write_mask %d, "
135
137
                  "nd %d{%d, %d}\n",
209
211
        int err, npositive;
210
212
        struct inode *inode, *h_inode;
211
213
        struct nameidata tmp_nd, *ndp;
 
214
        aufs_bindex_t bstart;
 
215
        struct mutex *mtx;
 
216
        struct super_block *sb;
212
217
 
213
218
        LKTRTrace("dir %lu, %.*s, nd{0x%x}\n",
214
219
                  dir->i_ino, AuDLNPair(dentry), nd ? nd->flags : 0);
215
220
        AuDebugOn(IS_ROOT(dentry));
216
221
        IMustLock(dir);
217
222
 
 
223
        sb = dir->i_sb;
 
224
        si_read_lock(sb, AuLock_FLUSH);
 
225
        err = au_alloc_dinfo(dentry);
 
226
        ret = ERR_PTR(err);
 
227
        if (unlikely(err))
 
228
                goto out;
 
229
 
218
230
        /* nd can be NULL */
 
231
        ndp = au_dup_nd(au_sbi(sb), &tmp_nd, nd);
219
232
        parent = dentry->d_parent; /* dir inode is locked */
220
 
        aufs_read_lock(parent, AuLock_FLUSH);
221
 
        err = au_alloc_dinfo(dentry);
222
 
        ret = ERR_PTR(err);
223
 
        if (unlikely(err))
224
 
                goto out;
225
 
 
226
 
        ndp = au_dup_nd(au_sbi(dir->i_sb), &tmp_nd, nd);
 
233
        di_read_lock_parent(parent, AuLock_IR);
227
234
        npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, ndp);
 
235
        di_read_unlock(parent, AuLock_IR);
228
236
        err = npositive;
229
237
        ret = ERR_PTR(err);
230
238
        if (unlikely(err < 0))
231
239
                goto out_unlock;
 
240
 
232
241
        inode = NULL;
233
242
        if (npositive) {
234
 
                /*
235
 
                 * stop 'race'-ing between hardlinks under different parents.
236
 
                 */
237
 
                h_inode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
 
243
                bstart = au_dbstart(dentry);
 
244
                h_inode = au_h_dptr(dentry, bstart)->d_inode;
238
245
                AuDebugOn(!h_inode);
239
 
                if (h_inode->i_nlink == 1 || S_ISDIR(h_inode->i_mode))
240
 
                        inode = au_new_inode(dentry);
241
 
                else {
242
 
                        /* todo: this lock is too large, try br_xino_nondir mutex */
243
 
                        static DEFINE_MUTEX(mtx);
244
 
                        mutex_lock(&mtx);
245
 
                        inode = au_new_inode(dentry);
246
 
                        mutex_unlock(&mtx);
247
 
                }
 
246
                if (!S_ISDIR(h_inode->i_mode)) {
 
247
                        /*
 
248
                         * stop 'race'-ing between hardlinks under different
 
249
                         * parents.
 
250
                         */
 
251
                        mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
 
252
                        mutex_lock(mtx);
 
253
                        inode = au_new_inode(dentry);
 
254
                        mutex_unlock(mtx);
 
255
                } else
 
256
                        inode = au_new_inode(dentry);
248
257
                ret = (void *)inode;
249
258
        }
250
259
        if (!IS_ERR(inode)) {
261
270
 out_unlock:
262
271
        di_write_unlock(dentry);
263
272
 out:
264
 
        aufs_read_unlock(parent, !AuLock_IR);
 
273
        si_read_unlock(sb);
265
274
        AuTraceErrPtr(ret);
266
275
        return ret;
267
276
}
383
392
 
384
393
/* ---------------------------------------------------------------------- */
385
394
 
386
 
static void au_hi_lock(struct inode *h_inode, int isdir, struct inode *inode,
387
 
                       aufs_bindex_t bindex)
388
 
{
389
 
        if (!isdir)
390
 
                mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
391
 
        else
392
 
                au_hdir2_lock(h_inode, inode, bindex);
393
 
}
394
 
 
395
 
static void au_hi_unlock(struct inode *h_inode, int isdir, struct inode *inode,
396
 
                         aufs_bindex_t bindex)
397
 
{
398
 
        if (!isdir)
399
 
                mutex_unlock(&h_inode->i_mutex);
400
 
        else
401
 
                au_hdir_unlock(h_inode, inode, bindex);
402
 
}
 
395
struct dentry *au_do_pinned_h_parent(struct au_pin1 *pin, aufs_bindex_t bindex)
 
396
{
 
397
        if (pin && pin->parent)
 
398
                return au_h_dptr(pin->parent, bindex);
 
399
        return NULL;
 
400
}
 
401
 
 
402
void au_do_unpin(struct au_pin1 *p, struct au_pin1 *gp)
 
403
{
 
404
        LKTRTrace("%p, %p\n", p, gp);
 
405
        AuDebugOn(!p);
 
406
 
 
407
        if (unlikely(!p->h_dir))
 
408
                return;
 
409
 
 
410
        LKTRTrace("p{%.*s, %d, %d, %d, %d}\n",
 
411
                  AuDLNPair(p->dentry), p->lsc_di, p->lsc_hi,
 
412
                  !!p->parent, !!p->h_dir);
 
413
 
 
414
        mutex_unlock(&p->h_dir->i_mutex);
 
415
        if (unlikely(gp))
 
416
                au_do_unpin(gp, NULL);
 
417
        if (!p->di_locked)
 
418
                di_read_unlock(p->parent, AuLock_IR);
 
419
        dput(p->parent);
 
420
        p->parent = NULL;
 
421
        p->h_dir = NULL;
 
422
}
 
423
 
 
424
void au_do_pin(struct au_pin1 *p, struct au_pin1 *gp, const aufs_bindex_t bindex,
 
425
               const int do_gp)
 
426
{
 
427
        struct dentry *h_dentry;
 
428
 
 
429
        LKTRTrace("%.*s, %d, b%d, %d\n",
 
430
                  AuDLNPair(p->dentry), !!gp, bindex, do_gp);
 
431
        AuDebugOn(do_gp && !gp);
 
432
 
 
433
        h_dentry = NULL;
 
434
        if (bindex <= au_dbend(p->dentry))
 
435
                h_dentry = au_h_dptr(p->dentry, bindex);
 
436
 
 
437
        while (!IS_ROOT(p->dentry)) {
 
438
                p->parent = dget_parent(p->dentry);
 
439
                if (!p->di_locked)
 
440
                        di_read_lock(p->parent, AuLock_IR, p->lsc_di);
 
441
                else
 
442
                        DiMustAnyLock(p->parent);
 
443
                AuDebugOn(!p->parent->d_inode);
 
444
                p->h_dir = au_h_iptr(p->parent->d_inode, bindex);
 
445
                AuDebugOn(!p->h_dir);
 
446
                if (unlikely(do_gp)) {
 
447
                        gp->dentry = p->parent;
 
448
                        au_do_pin(gp, NULL, bindex, 0);
 
449
                }
 
450
                mutex_lock_nested(&p->h_dir->i_mutex, p->lsc_hi);
 
451
                /* todo: call d_revalidate() here? */
 
452
                if (!h_dentry || !au_verify_parent(h_dentry, p->h_dir))
 
453
                        break;
 
454
 
 
455
#if 0
 
456
                AuWarn1("bypassed %.*s/%.*s?\n",
 
457
                        AuDLNPair(p->parent), AuDLNPair(p->dentry));
 
458
#endif
 
459
                AuDbgDentry(p->dentry);
 
460
                AuDbgDentry(h_dentry);
 
461
                AuDbgDentry(p->parent);
 
462
                AuDbgInode(p->h_dir);
 
463
                if (h_dentry)
 
464
                        AuDbgDentry(h_dentry->d_parent);
 
465
 
 
466
                au_do_unpin(p, gp);
 
467
                if (unlikely(do_gp))
 
468
                        gp->dentry = NULL;
 
469
 
 
470
                cond_resched();
 
471
                //yield();
 
472
        }
 
473
}
 
474
 
 
475
void au_pin_init(struct au_pin *args, struct dentry *dentry, int di_locked,
 
476
                 int lsc_di, int lsc_hi, int do_gp)
 
477
{
 
478
        struct au_pin1 *p;
 
479
 
 
480
        AuTraceEnter();
 
481
 
 
482
        memset(args, 0, sizeof(*args));
 
483
        p = args->pin + AuPin_PARENT;
 
484
        p->dentry = dentry;
 
485
        p->di_locked = di_locked;
 
486
        p->lsc_di = lsc_di;
 
487
        p->lsc_hi = lsc_hi;
 
488
        if (!do_gp)
 
489
                return;
 
490
 
 
491
        p = au_pin_gp(args);
 
492
        if (unlikely(p)) {
 
493
                p->lsc_di = lsc_di + 1; /* child first */
 
494
                p->lsc_hi = lsc_hi - 1; /* parent first */
 
495
        }
 
496
}
 
497
 
 
498
void au_pin(struct au_pin *args, struct dentry *dentry, aufs_bindex_t bindex,
 
499
            int di_locked, int do_gp)
 
500
{
 
501
        LKTRTrace("%.*s, b%d, di_locked %d, do_gp %d\n",
 
502
                  AuDLNPair(dentry), bindex, di_locked, do_gp);
 
503
 
 
504
        au_pin_init(args, dentry, di_locked, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
 
505
                    do_gp);
 
506
        au_do_pin(args->pin + AuPin_PARENT, au_pin_gp(args), bindex, do_gp);
 
507
}
 
508
 
 
509
/* ---------------------------------------------------------------------- */
403
510
 
404
511
struct au_icpup_args {
405
512
        aufs_bindex_t btgt;
406
 
        unsigned char isdir, did_cpup; /* flags */
407
 
        unsigned char hinotify;
408
 
        struct dentry *parent, *gparent, *h_dentry;
409
 
        struct inode *dir, *gdir, *h_inode, *h_dir;
 
513
        unsigned char isdir, hinotify; /* flags */
 
514
        struct dentry *h_dentry;
 
515
        struct inode *h_inode;
 
516
        struct au_pin pin;
 
517
        struct au_hin_ignore ign[2];
 
518
        struct vfsub_args vargs;
410
519
};
411
520
 
412
521
static int au_lock_and_icpup(struct dentry *dentry, loff_t sz,
413
 
                             struct au_icpup_args *rargs)
 
522
                             struct au_icpup_args *a)
414
523
{
415
524
        int err;
416
525
        aufs_bindex_t bstart;
 
526
        unsigned char did_cpup;
417
527
        struct super_block *sb;
418
528
        struct dentry *hi_wh;
419
529
        struct inode *inode;
428
538
        bstart = au_dbstart(dentry);
429
539
        sb = dentry->d_sb;
430
540
        inode = dentry->d_inode;
431
 
        rargs->isdir = S_ISDIR(inode->i_mode);
432
 
        if (rargs->isdir)
 
541
        a->isdir = !!S_ISDIR(inode->i_mode);
 
542
        if (unlikely(a->isdir))
433
543
                au_fset_wrdir(wr_dir_args.flags, ISDIR);
 
544
#if 0 /* todo: fix this */
 
545
        if (unlikely(bstart != au_ibstart(inode))) {
 
546
                AuDebugOn(!au_plink_test(sb, inode));
 
547
                wr_dir_args.force_btgt = au_ibstart(inode);
 
548
        }
 
549
#endif
434
550
        err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
435
551
        if (unlikely(err < 0))
436
552
                goto out_dentry;
437
 
        rargs->btgt = err;
438
 
        rargs->did_cpup = (err != bstart);
 
553
        a->btgt = err;
 
554
        did_cpup = (err != bstart);
439
555
        err = 0;
440
556
 
441
557
        /* crazy udba locks */
442
 
        rargs->hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY);
443
 
        if (unlikely(!IS_ROOT(dentry))) {
444
 
                rargs->parent = dget_parent(dentry);
445
 
                rargs->dir = rargs->parent->d_inode;
446
 
                di_read_lock_parent(rargs->parent, AuLock_IR);
447
 
        }
448
 
        rargs->h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
449
 
        rargs->h_inode = rargs->h_dentry->d_inode;
450
 
        AuDebugOn(!rargs->h_inode);
451
 
 
452
 
        if (!rargs->did_cpup) {
453
 
                au_hi_lock(rargs->h_inode, rargs->isdir, inode, rargs->btgt);
454
 
                /* todo: revalidate the lower dentry? */
 
558
        a->hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY);
 
559
        au_pin(&a->pin, dentry, a->btgt, /*di_locked*/0, /*dp_gp*/a->hinotify);
 
560
        a->h_dentry = au_h_dptr(dentry, bstart);
 
561
        a->h_inode = a->h_dentry->d_inode;
 
562
        AuDebugOn(!a->h_inode);
 
563
        mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
 
564
        if (!did_cpup) {
 
565
                au_unpin_gp(&a->pin);
455
566
                goto out; /* success */
456
567
        }
457
568
 
458
 
        if (unlikely(rargs->hinotify
459
 
                     && rargs->parent
460
 
                     && !IS_ROOT(rargs->parent))) {
461
 
                rargs->gparent = dget_parent(rargs->parent);
462
 
                rargs->gdir = rargs->gparent->d_inode;
463
 
                ii_read_lock_parent2(rargs->gdir);
464
 
        }
465
 
 
466
569
        hi_wh = NULL;
467
 
        rargs->h_dir = au_h_iptr(rargs->dir, rargs->btgt);
468
 
        au_hdir_lock(rargs->h_dir, rargs->dir, rargs->btgt);
469
 
        /* todo: revalidate the lower dentry? */
470
 
        au_hi_lock(rargs->h_inode, rargs->isdir, inode, bstart);
471
570
        if (!d_unhashed(dentry)) {
472
 
                err = au_sio_cpup_simple(dentry, rargs->btgt, sz, AuCpup_DTIME);
 
571
                err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME);
473
572
                if (!err)
474
 
                        rargs->h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
 
573
                        a->h_dentry = au_h_dptr(dentry, a->btgt);
475
574
        } else {
476
 
                hi_wh = au_hi_wh(inode, rargs->btgt);
 
575
                hi_wh = au_hi_wh(inode, a->btgt);
477
576
                if (!hi_wh) {
478
 
                        err = au_sio_cpup_wh(dentry, rargs->btgt, sz,
 
577
                        err = au_sio_cpup_wh(dentry, a->btgt, sz,
479
578
                                             /*file*/NULL);
480
579
                        if (!err)
481
 
                                hi_wh = au_hi_wh(inode, rargs->btgt);
 
580
                                hi_wh = au_hi_wh(inode, a->btgt);
482
581
                        /* todo: revalidate hi_wh? */
483
582
                }
484
583
                if (!hi_wh)
485
 
                        rargs->h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
 
584
                        a->h_dentry = au_h_dptr(dentry, a->btgt);
486
585
                else
487
 
                        rargs->h_dentry = hi_wh; /* do not dget here */
 
586
                        a->h_dentry = hi_wh; /* do not dget here */
488
587
        }
489
588
 
490
 
        au_hi_unlock(rargs->h_inode, rargs->isdir, inode, bstart);
491
 
        rargs->h_inode = rargs->h_dentry->d_inode;
492
 
        AuDebugOn(!rargs->h_inode);
493
 
        if (!err)
494
 
                au_hi_lock(rargs->h_inode, rargs->isdir, inode, rargs->btgt);
495
 
        au_hdir_unlock(rargs->h_dir, rargs->dir, rargs->btgt);
496
 
        if (!err)
 
589
        mutex_unlock(&a->h_inode->i_mutex);
 
590
        a->h_inode = a->h_dentry->d_inode;
 
591
        AuDebugOn(!a->h_inode);
 
592
        if (!err) {
 
593
                mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
 
594
                au_unpin_gp(&a->pin);
497
595
                goto out; /* success */
 
596
        }
498
597
 
499
 
        au_hi_unlock(rargs->h_inode, rargs->isdir, inode, rargs->btgt);
500
 
        if (unlikely(rargs->gdir)) {
501
 
                ii_read_unlock(rargs->gdir);
502
 
                dput(rargs->gparent);
503
 
        }
504
 
        if (unlikely(rargs->dir)) {
505
 
                di_read_unlock(rargs->parent, AuLock_IR);
506
 
                dput(rargs->parent);
507
 
        }
 
598
        au_unpin(&a->pin);
508
599
 
509
600
 out_dentry:
510
601
        di_write_unlock(dentry);
517
608
{
518
609
        int err;
519
610
        struct inode *inode;
520
 
        struct au_hin_ignore ign;
521
 
        struct vfsub_args vargs;
522
611
        struct super_block *sb;
523
612
        __u32 events;
524
613
        struct file *file;
525
614
        loff_t sz;
526
 
        struct au_icpup_args rargs;
 
615
        struct au_icpup_args *a;
527
616
 
528
617
        LKTRTrace("%.*s, ia_valid 0x%x\n", AuDLNPair(dentry), ia->ia_valid);
529
618
        inode = dentry->d_inode;
530
619
        IMustLock(inode);
531
620
 
532
 
        sb = dentry->d_sb;
533
 
        si_read_lock(sb, AuLock_FLUSH);
 
621
        err = -ENOMEM;
 
622
        a = kzalloc(sizeof(*a), GFP_NOFS);
 
623
        if (unlikely(!a))
 
624
                goto out;
534
625
 
535
626
        file = NULL;
 
627
        sb = dentry->d_sb;
 
628
        si_read_lock(sb, AuLock_FLUSH);
 
629
        vfsub_args_init(&a->vargs, a->ign, au_test_dlgt(au_mntflags(sb)), 0);
 
630
 
536
631
        if (ia->ia_valid & ATTR_FILE) {
537
632
                /* currently ftruncate(2) only */
538
633
                file = ia->ia_file;
544
639
        if ((ia->ia_valid & ATTR_SIZE)
545
640
            && ia->ia_size < i_size_read(inode))
546
641
                sz = ia->ia_size;
547
 
        memset(&rargs, 0, sizeof(rargs));
548
 
        err = au_lock_and_icpup(dentry, sz, &rargs);
 
642
        err = au_lock_and_icpup(dentry, sz, a);
549
643
        if (unlikely(err < 0))
550
 
                goto out;
 
644
                goto out_si;
551
645
 
552
646
        if ((ia->ia_valid & ATTR_SIZE)
553
647
            && ia->ia_size < i_size_read(inode)) {
560
654
                ia->ia_valid &= ~ATTR_MODE;
561
655
 
562
656
        events = 0;
563
 
        vfsub_args_init(&vargs, &ign, au_test_dlgt(au_mntflags(sb)), 0);
564
 
        if (unlikely(rargs.hinotify && rargs.dir)) {
 
657
        if (unlikely(a->hinotify)) {
565
658
                events = vfsub_events_notify_change(ia);
566
 
                if (events)
567
 
                        vfsub_ign_hinode(&vargs, events,
568
 
                                         au_hi(rargs.dir, rargs.btgt));
 
659
                if (events) {
 
660
                        if (unlikely(a->isdir))
 
661
                                vfsub_ign_hinode(&a->vargs, events,
 
662
                                                 au_hi(inode, a->btgt));
 
663
                        vfsub_ign_hinode(&a->vargs, events,
 
664
                                         au_pinned_hdir(&a->pin, a->btgt));
 
665
                }
569
666
        }
570
 
        err = vfsub_notify_change(rargs.h_dentry, ia, &vargs);
 
667
        err = vfsub_notify_change(a->h_dentry, ia, &a->vargs);
571
668
        if (!err)
572
669
                au_cpup_attr_changeable(inode);
573
670
 
574
671
 out_unlock:
575
 
        au_hi_unlock(rargs.h_inode, rargs.isdir, inode, rargs.btgt);
576
 
        if (unlikely(rargs.gdir)) {
577
 
                ii_read_unlock(rargs.gdir);
578
 
                dput(rargs.gparent);
579
 
        }
580
 
        if (unlikely(rargs.dir)) {
581
 
                di_read_unlock(rargs.parent, AuLock_IR);
582
 
                dput(rargs.parent);
583
 
        }
 
672
        mutex_unlock(&a->h_inode->i_mutex);
 
673
        au_unpin(&a->pin);
584
674
        di_write_unlock(dentry);
585
 
 out:
 
675
 out_si:
586
676
        if (file) {
587
677
                ia->ia_file = file;
588
678
                /* ia->ia_valid |= ATTR_FILE; */
589
679
                fi_write_unlock(file);
590
680
        }
591
681
        si_read_unlock(sb);
 
682
        kfree(a);
 
683
 out:
592
684
        AuTraceErr(err);
593
685
        return err;
594
686
}