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

« back to all changes in this revision

Viewing changes to fs/aufs25/file.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
 * handling file/dir, and address_space operation
21
21
 *
22
 
 * $Id: file.c,v 1.7 2008/06/09 01:11:58 sfjro Exp $
 
22
 * $Id: file.c,v 1.11 2008/07/14 00:14:58 sfjro Exp $
23
23
 */
24
24
 
25
25
#include <linux/pagemap.h>
73
73
        struct inode *h_inode;
74
74
        struct super_block *sb;
75
75
        struct au_branch *br;
76
 
        int hinotify, err;
 
76
        int err;
77
77
 
78
78
        LKTRTrace("%.*s, b%d, flags 0%o, f %d\n",
79
79
                  AuDLNPair(dentry), bindex, flags, !!file);
80
 
        AuDebugOn(!dentry);
81
80
        h_dentry = au_h_dptr(dentry, bindex);
82
81
        AuDebugOn(!h_dentry);
83
82
        h_inode = h_dentry->d_inode;
84
 
        /* todo: a race can happen, return ENOENT */
85
 
#if 0
 
83
 
 
84
        /* a race condition can happen between open and unlink/rmdir */
86
85
        h_file = ERR_PTR(-ENOENT);
87
 
        if (unlikely(!h_inode))
 
86
        if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry))
 
87
                     || !h_inode))
88
88
                goto out;
89
 
#else
90
 
        AuDebugOn(!h_inode);
91
 
#endif
92
89
 
93
90
        sb = dentry->d_sb;
94
 
        hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY);
95
91
        br = au_sbr(sb, bindex);
96
92
        au_br_get(br);
97
93
        /* drop flags for writing */
121
117
                return h_file;
122
118
 
123
119
        au_br_put(br);
 
120
 
 
121
out:
124
122
        AuTraceErrPtr(h_file);
125
123
        return h_file;
126
124
}
128
126
static int do_coo(struct dentry *dentry, aufs_bindex_t bstart)
129
127
{
130
128
        int err;
131
 
        struct dentry *parent, *h_parent, *h_dentry, *gparent;
 
129
        struct dentry *parent;
132
130
        aufs_bindex_t bcpup;
133
 
        struct inode *h_dir, *h_inode, *dir;
 
131
        struct mutex *h_mtx;
134
132
        struct super_block *sb;
 
133
        struct au_pin pin;
135
134
 
136
135
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
137
136
        AuDebugOn(IS_ROOT(dentry));
144
143
        bcpup = err;
145
144
        if (err < 0) {
146
145
                err = 0; /* stop copyup, it is not an error */
147
 
                goto out;
 
146
                goto out_dgrade;
148
147
        }
149
148
        err = 0;
150
149
 
151
 
        h_parent = au_h_dptr(parent, bcpup);
152
 
        if (!h_parent) {
 
150
        if (!au_h_dptr(parent, bcpup)) {
153
151
                err = au_cpup_dirs(dentry, bcpup, NULL);
154
152
                if (unlikely(err))
155
 
                        goto out;
156
 
                h_parent = au_h_dptr(parent, bcpup);
 
153
                        goto out_dgrade;
157
154
        }
158
155
 
159
 
        h_dir = h_parent->d_inode;
160
 
        h_dentry = au_h_dptr(dentry, bstart);
161
 
        h_inode = h_dentry->d_inode;
162
 
        dir = parent->d_inode;
163
 
        /* todo: meaningless lock if CONFIG_AUFS_DEBUG is disabled. */
164
 
        gparent = NULL;
165
 
        if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY)
166
 
                     && !IS_ROOT(parent))) {
167
 
                gparent = dget_parent(parent);
168
 
                ii_read_lock_parent2(gparent->d_inode);
169
 
        }
170
 
        au_hdir_lock(h_dir, dir, bcpup);
171
 
        /* todo: test parent-gparent relationship? */
172
 
        mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
 
156
        di_downgrade_lock(parent, AuLock_IR);
 
157
        au_pin(&pin, dentry, bcpup, /*di_locked*/1,
 
158
               /*do_gp*/au_opt_test(au_mntflags(sb), UDBA_INOTIFY));
 
159
        h_mtx = &au_h_dptr(dentry, bstart)->d_inode->i_mutex;
 
160
        mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
173
161
        AuDebugOn(au_h_dptr(dentry, bcpup));
174
162
        err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME);
175
163
        AuTraceErr(err);
176
 
        mutex_unlock(&h_inode->i_mutex);
177
 
        au_hdir_unlock(h_dir, dir, bcpup);
178
 
        if (unlikely(gparent)) {
179
 
                ii_read_unlock(gparent->d_inode);
180
 
                dput(gparent);
181
 
        }
 
164
        mutex_unlock(h_mtx);
 
165
        au_unpin(&pin);
 
166
        goto out;
182
167
 
 
168
 out_dgrade:
 
169
        di_downgrade_lock(parent, AuLock_IR);
183
170
 out:
184
 
        di_write_unlock(parent);
 
171
        di_read_unlock(parent, AuLock_IR);
185
172
        dput(parent);
186
173
        AuTraceErr(err);
187
174
        return err;
213
200
        if (unlikely(err))
214
201
                goto out;
215
202
 
216
 
        if (!coo) {
 
203
        if (!coo)
217
204
                di_read_lock_child(dentry, AuLock_IR);
218
 
                /* todo: remove this */
219
 
                bstart = au_dbstart(dentry);
220
 
        } else {
 
205
        else {
221
206
                di_write_lock_child(dentry);
222
207
                bstart = au_dbstart(dentry);
223
208
                if (au_test_ro(sb, bstart, dentry->d_inode)) {
226
211
                                di_write_unlock(dentry);
227
212
                                goto out_finfo;
228
213
                        }
229
 
                        /* todo: remove this */
230
 
                        bstart = au_dbstart(dentry);
231
214
                }
232
215
                di_downgrade_lock(dentry, AuLock_IR);
233
216
        }
330
313
/*
331
314
 * prepare the @file for writing.
332
315
 */
333
 
int au_ready_to_write(struct file *file, loff_t len)
 
316
int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
334
317
{
335
318
        int err;
336
 
        struct dentry *dentry, *parent, *h_dentry, *h_parent, *gparent;
337
 
        struct inode *h_inode, *h_dir, *inode, *dir;
 
319
        struct dentry *dentry, *parent, *h_dentry;
 
320
        struct inode *h_inode, *inode;
338
321
        struct super_block *sb;
339
322
        aufs_bindex_t bstart, bcpup;
340
323
 
348
331
 
349
332
        inode = dentry->d_inode;
350
333
        AuDebugOn(S_ISDIR(inode->i_mode));
351
 
        ii_read_lock_child(inode);
352
334
        LKTRTrace("rdonly %d, bstart %d\n",
353
335
                  au_test_ro(sb, bstart, inode), bstart);
 
336
 
354
337
        err = au_test_ro(sb, bstart, inode);
355
 
        ii_read_unlock(inode);
356
 
        if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE))
357
 
                return 0;
 
338
        if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) {
 
339
                au_pin(pin, dentry, bstart, /*di_locked*/0, /*dp_gp*/0);
 
340
                goto out;
 
341
        }
358
342
 
359
343
        /* need to cpup */
360
 
        di_write_lock_child(dentry);
361
344
        parent = dget_parent(dentry);
362
345
        di_write_lock_parent(parent);
363
346
        err = AuWbrCopyup(au_sbi(sb), dentry);
364
347
        bcpup = err;
365
348
        if (unlikely(err < 0))
366
 
                goto out_unlock;
 
349
                goto out_dgrade;
367
350
        err = 0;
368
351
 
369
 
        h_parent = au_h_dptr(parent, bcpup);
370
 
        if (!h_parent) {
 
352
        if (!au_h_dptr(parent, bcpup)) {
371
353
                err = au_cpup_dirs(dentry, bcpup, NULL);
372
354
                if (unlikely(err))
373
 
                        goto out_unlock;
374
 
                h_parent = au_h_dptr(parent, bcpup);
375
 
        }
376
 
 
377
 
        /* todo: meaningless lock if CONFIG_AUFS_DEBUG is disabled. */
378
 
        gparent = NULL;
379
 
        if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY)
380
 
                     && !IS_ROOT(parent))) {
381
 
                gparent = dget_parent(parent);
382
 
                ii_read_lock_parent2(gparent->d_inode);
383
 
        }
384
 
        h_dir = h_parent->d_inode;
385
 
        h_dentry = au_h_fptr(file, au_fbstart(file))->f_dentry;
 
355
                        goto out_dgrade;
 
356
        }
 
357
 
 
358
        di_downgrade_lock(parent, AuLock_IR);
 
359
        au_pin(pin, dentry, bcpup, /*di_locked*/1,
 
360
               /*dp_gp*/au_opt_test(au_mntflags(sb), UDBA_INOTIFY));
 
361
 
 
362
        AuDebugOn(au_fbstart(file) != bstart);
 
363
        h_dentry = au_h_fptr(file, bstart)->f_dentry;
386
364
        h_inode = h_dentry->d_inode;
387
 
        dir = parent->d_inode;
388
 
        au_hdir_lock(h_dir, dir, bcpup);
389
 
        /* todo: test parent-gparent relationship? */
390
365
        mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
391
366
        if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */
392
367
            /* || !h_inode->i_nlink */)
401
376
                AuTraceErr(err);
402
377
        }
403
378
        mutex_unlock(&h_inode->i_mutex);
404
 
        au_hdir_unlock(h_dir, dir, bcpup);
405
 
        if (unlikely(gparent)) {
406
 
                ii_read_unlock(gparent->d_inode);
407
 
                dput(gparent);
 
379
 
 
380
        if (!err) {
 
381
                au_unpin_gp(pin);
 
382
                au_pin_set_parent_lflag(pin, /*lflag*/0);
 
383
                goto out_dput; /* success */
408
384
        }
 
385
        au_unpin(pin);
 
386
        goto out_unlock;
409
387
 
 
388
 out_dgrade:
 
389
        di_downgrade_lock(parent, AuLock_IR);
410
390
 out_unlock:
411
 
        di_write_unlock(parent);
412
 
        di_write_unlock(dentry);
 
391
        di_read_unlock(parent, AuLock_IR);
 
392
 out_dput:
413
393
        dput(parent);
 
394
 out:
414
395
        AuTraceErr(err);
415
396
        return err;
416
 
 
417
397
}
418
398
 
419
399
/* ---------------------------------------------------------------------- */
427
407
        aufs_bindex_t bstart, new_bstart, old_bstart;
428
408
        struct super_block *sb;
429
409
        struct au_dinfo *dinfo;
 
410
        unsigned int mnt_flags;
430
411
 
431
412
        dentry = file->f_dentry;
432
413
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
436
417
        finfo = au_fi(file);
437
418
        inode = dentry->d_inode;
438
419
        sb = dentry->d_sb;
 
420
        mnt_flags = au_mntflags(sb);
439
421
 again:
440
422
        bstart = au_ibstart(inode);
441
423
        if (bstart == finfo->fi_bstart)
453
435
                        goto out_put;
454
436
                err = 0;
455
437
        }
456
 
        di_read_unlock(dentry, AuLock_IR);
457
 
        di_write_lock_child(dentry);
458
438
        /* someone else might change our inode while we were sleeping */
459
439
        /* todo: test more? */
460
440
        if (bstart != au_ibstart(inode)) {
461
 
                di_downgrade_lock(dentry, AuLock_IR);
462
441
                err = 0;
463
442
                dput(parent);
464
443
                goto again;
467
446
        bstart = new_bstart;
468
447
 
469
448
        hi_wh = au_hi_wh(inode, bstart);
470
 
        if (au_opt_test(au_mntflags(sb), PLINK)
 
449
        if (au_opt_test(mnt_flags, PLINK)
471
450
            && au_plink_test(sb, inode)
472
451
            && !d_unhashed(dentry)) {
473
452
                err = au_test_and_cpup_dirs(dentry, bstart, NULL);
474
453
 
475
454
                /* always superio. */
476
 
#if 1 /* reserved for future use */
 
455
#if 1
477
456
                h_dir = au_h_dptr(parent, bstart)->d_inode;
478
 
                au_hdir_lock(h_dir, dir, bstart);
 
457
                mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
479
458
                err = au_sio_cpup_simple(dentry, bstart, -1, AuCpup_DTIME);
480
 
                au_hdir_unlock(h_dir, dir, bstart);
481
 
#else
 
459
                mutex_unlock(&h_dir->i_mutex);
 
460
#else /* reserved for future use */
482
461
                if (!au_test_wkq(current)) {
483
462
                        int wkq_err;
484
463
                        struct cpup_pseudo_link_args args = {
506
485
                *need_reopen = 0;
507
486
        }
508
487
        di_read_unlock(parent, AuLock_IR);
509
 
        di_downgrade_lock(dentry, AuLock_IR);
510
488
 
511
489
 out_put:
512
490
        dput(parent);
531
509
        dentry = file->f_dentry;
532
510
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
533
511
        FiMustWriteLock(file);
534
 
        DiMustReadLock(dentry);
 
512
        DiMustAnyLock(dentry);
535
513
        inode = dentry->d_inode;
536
 
        IiMustReadLock(inode);
 
514
        IiMustAnyLock(inode);
537
515
 
538
516
        err = -ENOMEM;
539
517
        sb = dentry->d_sb;
540
518
        finfo = au_fi(file);
541
519
        new_sz = sizeof(*finfo->fi_hfile) * (au_sbend(sb) + 1);
542
520
        p = au_kzrealloc(finfo->fi_hfile, sizeof(*p) * (finfo->fi_bend + 1),
543
 
                         new_sz, GFP_KERNEL);
 
521
                         new_sz, GFP_NOFS);
544
522
        if (unlikely(!p))
545
523
                goto out;
546
524
        finfo->fi_hfile = p;
636
614
}
637
615
 
638
616
/* common function to regular file and dir */
639
 
int au_reval_and_lock_finfo(struct file *file, int (*reopen)(struct file *file),
640
 
                            int wlock, int locked)
 
617
int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
 
618
                          int wlock, int locked)
641
619
{
642
620
        int err, pseudo_link;
643
621
        struct dentry *dentry;
654
632
        sgen = au_sigen(sb);
655
633
        fi_write_lock(file);
656
634
        fgen = au_figen(file);
657
 
        di_read_lock_child(dentry, AuLock_IR);
 
635
        di_write_lock_child(dentry);
658
636
        bstart = au_dbstart(dentry);
659
637
        pseudo_link = (bstart != au_ibstart(dentry->d_inode));
660
 
        di_read_unlock(dentry, AuLock_IR);
661
638
        if (sgen == fgen && !pseudo_link && au_fbstart(file) == bstart) {
662
 
                if (!wlock)
 
639
                if (!wlock) {
 
640
                        di_downgrade_lock(dentry, AuLock_IR);
663
641
                        fi_downgrade_lock(file);
 
642
                }
664
643
                goto out; /* success */
665
644
        }
666
645
 
672
651
                 * to revalidate. but si_rwsem in DEBUG_RWSEM will cause a
673
652
                 * deadlock. removed the code.
674
653
                 */
675
 
                di_write_lock_child(dentry);
676
654
                err = au_reval_dpath(dentry, sgen);
677
 
                di_write_unlock(dentry);
678
655
                if (unlikely(err < 0))
679
656
                        goto out;
680
657
                AuDebugOn(au_digen(dentry) != sgen
681
658
                          || au_iigen(dentry->d_inode) != sgen);
682
659
        }
683
660
 
684
 
        di_read_lock_child(dentry, AuLock_IR);
685
661
        err = refresh_file(file, reopen
686
662
                           /* , au_opt_test(au_mnt_flags(sb), REFROF) */);
687
 
        di_read_unlock(dentry, AuLock_IR);
688
663
        if (!err) {
689
 
                if (!wlock)
 
664
                if (!wlock) {
 
665
                        di_downgrade_lock(dentry, AuLock_IR);
690
666
                        fi_downgrade_lock(file);
691
 
        } else
 
667
                }
 
668
        } else {
 
669
                di_write_unlock(dentry);
692
670
                fi_write_unlock(file);
 
671
        }
693
672
 
694
673
 out:
695
674
        AuTraceErr(err);