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

« back to all changes in this revision

Viewing changes to fs/aufs/f_op.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: f_op.c,v 1.49 2008/03/24 02:15:34 sfjro Exp $ */
 
19
/*
 
20
 * file and vm operations
 
21
 *
 
22
 * $Id: f_op.c,v 1.51 2008/04/13 23:40:32 sfjro Exp $
 
23
 */
20
24
 
21
25
#include <linux/fsnotify.h>
22
26
#include <linux/pagemap.h>
47
51
        di_read_lock_child(dentry, AuLock_IW);
48
52
 
49
53
        err = 0;
50
 
        bend = fbend(file);
51
 
        for (bindex = fbstart(file); !err && bindex <= bend; bindex++) {
 
54
        bend = au_fbend(file);
 
55
        for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
52
56
                struct file *h_file;
53
57
                h_file = au_h_fptr_i(file, bindex);
54
58
                if (h_file && h_file->f_op && h_file->f_op->flush) {
76
80
        int err;
77
81
        aufs_bindex_t bindex;
78
82
        struct super_block *sb;
79
 
        struct file *hidden_file;
 
83
        struct file *h_file;
80
84
        struct dentry *dentry;
81
85
        struct inode *inode;
82
 
        struct aufs_finfo *finfo;
 
86
        struct au_finfo *finfo;
83
87
 
84
88
        dentry = file->f_dentry;
85
89
        LKTRTrace("%.*s, flags 0%o\n", AuDLNPair(dentry), flags);
88
92
        AuDebugOn(!inode || S_ISDIR(inode->i_mode));
89
93
 
90
94
        err = 0;
91
 
        finfo = ftofi(file);
 
95
        finfo = au_fi(file);
92
96
        finfo->fi_h_vm_ops = NULL;
93
97
        sb = dentry->d_sb;
94
 
        bindex = dbstart(dentry);
 
98
        bindex = au_dbstart(dentry);
95
99
        AuDebugOn(!au_h_dptr(dentry)->d_inode);
96
100
        /* O_TRUNC is processed already */
97
101
        BUG_ON(au_test_ro(sb, bindex, inode) && (flags & O_TRUNC));
98
102
 
99
 
        hidden_file = au_h_open(dentry, bindex, flags, file);
100
 
        //if (LktrCond) {fput(hidden_file); br_put(stobr(dentry->d_sb, bindex));
101
 
        //hidden_file = ERR_PTR(-1);}
102
 
        if (!IS_ERR(hidden_file)) {
103
 
                set_fbstart(file, bindex);
104
 
                set_fbend(file, bindex);
105
 
                set_h_fptr(file, bindex, hidden_file);
 
103
        h_file = au_h_open(dentry, bindex, flags, file);
 
104
        //if (LktrCond) {fput(h_file); au_br_put(au_sbr(dentry->d_sb, bindex));
 
105
        //h_file = ERR_PTR(-1);}
 
106
        if (!IS_ERR(h_file)) {
 
107
                au_set_fbstart(file, bindex);
 
108
                au_set_fbend(file, bindex);
 
109
                au_set_h_fptr(file, bindex, h_file);
106
110
                au_update_figen(file);
107
 
                //file->f_ra = hidden_file->f_ra; //??
 
111
                //file->f_ra = h_file->f_ra; //??
108
112
                //AuDbgFile(file);
109
113
                return 0; /* success */
110
114
        }
111
 
        err = PTR_ERR(hidden_file);
 
115
        err = PTR_ERR(h_file);
112
116
        AuTraceErr(err);
113
117
        return err;
114
118
}
157
161
        /* support LSM and notify */
158
162
        hidden_file = au_h_fptr(file);
159
163
        h_inode = hidden_file->f_dentry->d_inode;
160
 
        err = vfsub_read_u(hidden_file, buf, count, ppos, au_need_dlgt(sb));
 
164
        err = vfsub_read_u(hidden_file, buf, count, ppos,
 
165
                           au_opt_test_dlgt(au_mntflags(sb)));
161
166
        //file->f_ra = hidden_file->f_ra; //??
162
167
        dentry->d_inode->i_atime = hidden_file->f_dentry->d_inode->i_atime;
163
168
 
175
180
        struct dentry *dentry, *parent;
176
181
        struct inode *inode, *dir;
177
182
        struct super_block *sb;
 
183
        unsigned int mnt_flags;
178
184
        struct file *h_file;
179
185
        char __user *buf = (char __user *)__buf;
180
 
        struct aufs_hin_ignore ign;
 
186
        struct au_hin_ignore ign;
181
187
        struct vfsub_args vargs;
182
188
 
183
189
        dentry = file->f_dentry;
199
205
                goto out_unlock;
200
206
 
201
207
        /* support LSM and notify */
202
 
        vfsub_args_init(&vargs, &ign, au_need_dlgt(sb), 0);
 
208
        mnt_flags = au_mntflags(sb);
 
209
        vfsub_args_init(&vargs, &ign, au_opt_test_dlgt(mnt_flags), 0);
203
210
        h_file = au_h_fptr(file);
204
 
        if (!au_flag_test_udba_inotify(sb))
 
211
        if (!au_opt_test(mnt_flags, UDBA_INOTIFY))
205
212
                err = vfsub_write_u(h_file, buf, count, ppos, &vargs);
206
213
        else {
207
214
                parent = dget_parent(dentry);
208
215
                dir = parent->d_inode;
209
216
                ii_read_lock_parent(dir);
210
 
                vfsub_ign_hinode(&vargs, IN_MODIFY, itohi(dir, fbstart(file)));
 
217
                vfsub_ign_hinode(&vargs, IN_MODIFY,
 
218
                                 au_hi(dir, au_fbstart(file)));
211
219
                err = vfsub_write_u(h_file, buf, count, ppos, &vargs);
212
220
                ii_read_unlock(dir);
213
221
                dput(parent);
266
274
                file->f_mapping = h_file->f_mapping;
267
275
                smp_mb(); /* unnecessary? */
268
276
        }
269
 
        err = vfsub_splice_to(h_file, ppos, pipe, len, flags, au_need_dlgt(sb));
 
277
        err = vfsub_splice_to(h_file, ppos, pipe, len, flags,
 
278
                              au_opt_test_dlgt(au_mntflags(sb)));
270
279
        //file->f_ra = h_file->f_ra; //??
271
280
        dentry->d_inode->i_atime = h_file->f_dentry->d_inode->i_atime;
272
281
        fi_read_unlock(file);
287
296
        struct super_block *sb;
288
297
        struct file *h_file;
289
298
        struct inode *h_inode;
290
 
        struct aufs_hin_ignore ign;
 
299
        struct au_hin_ignore ign;
291
300
        struct vfsub_args vargs;
 
301
        unsigned int mnt_flags;
292
302
 
293
303
        dentry = file->f_dentry;
294
304
        LKTRTrace("%.*s, len %lu, pos %Ld\n",
309
319
                goto out_unlock;
310
320
 
311
321
        /* support LSM and notify */
312
 
        vfsub_args_init(&vargs, &ign, au_need_dlgt(sb), 0);
 
322
        mnt_flags = au_mntflags(sb);
 
323
        vfsub_args_init(&vargs, &ign, au_opt_test_dlgt(mnt_flags), 0);
313
324
        h_file = au_h_fptr(file);
314
325
        h_inode = h_file->f_dentry->d_inode;
315
326
        /* current do_splice_from() doesn't fire up the inotify event */
316
 
        if (1 || !au_flag_test_udba_inotify(sb))
 
327
        if (1 || !au_opt_test(mnt_flags, UDBA_INOTIFY))
317
328
                err = vfsub_splice_from(pipe, h_file, ppos, len, flags, &vargs);
318
329
        else {
319
330
                //struct dentry *parent = dget_parent(dentry);
320
331
                //vfsub_ign_hinode(&vargs, IN_MODIFY,
321
 
                //itohi(parent->d_inode, fbstart(file));
 
332
                //au_hi(parent->d_inode, au_fbstart(file));
322
333
                err = vfsub_splice_from(pipe, h_file, ppos, len, flags, &vargs);
323
334
                //dput(parent);
324
335
        }
338
349
 
339
350
/* ---------------------------------------------------------------------- */
340
351
 
341
 
//todo: robr.c and norobr.c?
342
 
#ifdef CONFIG_AUFS_ROBR
343
 
struct lvma {
344
 
        struct list_head list;
345
 
        struct vm_area_struct *vma;
346
 
};
347
 
 
348
 
static struct file *safe_file(struct vm_area_struct *vma)
349
 
{
350
 
        struct file *file = vma->vm_file;
351
 
        struct super_block *sb = file->f_dentry->d_sb;
352
 
        struct lvma *lvma, *entry;
353
 
        struct aufs_sbinfo *sbinfo;
354
 
        int found, warn;
355
 
 
356
 
        AuTraceEnter();
357
 
        AuDebugOn(!au_test_aufs(sb));
358
 
 
359
 
        warn = 0;
360
 
        found = 0;
361
 
        sbinfo = stosi(sb);
362
 
        spin_lock(&sbinfo->si_lvma_lock);
363
 
        list_for_each_entry(entry, &sbinfo->si_lvma, list) {
364
 
                found = (entry->vma == vma);
365
 
                if (unlikely(found))
366
 
                        break;
367
 
        }
368
 
        if (!found) {
369
 
                lvma = kmalloc(sizeof(*lvma), GFP_ATOMIC);
370
 
                if (lvma) {
371
 
                        lvma->vma = vma;
372
 
                        list_add(&lvma->list, &sbinfo->si_lvma);
373
 
                } else {
374
 
                        warn = 1;
375
 
                        file = NULL;
376
 
                }
377
 
        } else
378
 
                file = NULL;
379
 
        spin_unlock(&sbinfo->si_lvma_lock);
380
 
 
381
 
        if (unlikely(warn))
382
 
                AuWarn1("no memory for lvma\n");
383
 
        return file;
384
 
}
385
 
 
386
 
static void reset_file(struct vm_area_struct *vma, struct file *file)
387
 
{
388
 
        struct super_block *sb = file->f_dentry->d_sb;
389
 
        struct lvma *entry, *found;
390
 
        struct aufs_sbinfo *sbinfo;
391
 
 
392
 
        AuTraceEnter();
393
 
        AuDebugOn(!au_test_aufs(sb));
394
 
 
395
 
        vma->vm_file = file;
396
 
 
397
 
        found = NULL;
398
 
        sbinfo = stosi(sb);
399
 
        spin_lock(&sbinfo->si_lvma_lock);
400
 
        list_for_each_entry(entry, &sbinfo->si_lvma, list)
401
 
                if (entry->vma == vma) {
402
 
                        found = entry;
403
 
                        break;
404
 
                }
405
 
        AuDebugOn(!found);
406
 
        list_del(&found->list);
407
 
        spin_unlock(&sbinfo->si_lvma_lock);
408
 
        kfree(found);
409
 
}
410
 
 
411
 
#else
412
 
 
413
 
static struct file *safe_file(struct vm_area_struct *vma)
414
 
{
415
 
        struct file *file;
416
 
 
417
 
        file = vma->vm_file;
418
 
        if (file->private_data && au_test_aufs(file->f_dentry->d_sb))
419
 
                return file;
420
 
        return NULL;
421
 
}
422
 
 
423
 
static void reset_file(struct vm_area_struct *vma, struct file *file)
424
 
{
425
 
        vma->vm_file = file;
426
 
        smp_mb(); /* flush vm_file */
427
 
}
428
 
#endif /* CONFIG_AUFS_ROBR */
429
 
 
430
352
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
431
353
static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
432
354
{
435
357
        struct file *file, *h_file;
436
358
        struct inode *inode;
437
359
        static DECLARE_WAIT_QUEUE_HEAD(wq);
438
 
        struct aufs_finfo *finfo;
 
360
        struct au_finfo *finfo;
439
361
        //struct page *page;
440
362
 
441
363
        AuTraceEnter();
442
364
        AuDebugOn(!vma || !vma->vm_file);
443
 
        wait_event(wq, (file = safe_file(vma)));
 
365
        wait_event(wq, (file = au_robr_safe_file(vma)));
444
366
        AuDebugOn(!au_test_aufs(file->f_dentry->d_sb));
445
367
        dentry = file->f_dentry;
446
368
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
448
370
        AuDebugOn(!S_ISREG(inode->i_mode));
449
371
 
450
372
        /* do not revalidate, nor lock */
451
 
        finfo = ftofi(file);
 
373
        finfo = au_fi(file);
452
374
        h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
453
375
        AuDebugOn(!h_file || !au_test_mmapped(file));
454
376
        vma->vm_file = h_file;
455
377
        //smp_mb();
456
378
        err = finfo->fi_h_vm_ops->fault(vma, vmf);
457
379
        //file->f_ra = h_file->f_ra; //??
458
 
        reset_file(vma, file);
 
380
        au_robr_reset_file(vma, file);
459
381
#if 0 //def CONFIG_SMP
460
382
        //wake_up_nr(&wq, online_cpu - 1);
461
383
        wake_up_all(&wq);
487
409
        struct file *file, *h_file;
488
410
        struct inode *inode;
489
411
        static DECLARE_WAIT_QUEUE_HEAD(wq);
490
 
        struct aufs_finfo *finfo;
 
412
        struct au_finfo *finfo;
491
413
 
492
414
        AuTraceEnter();
493
415
        AuDebugOn(!vma || !vma->vm_file);
494
 
        wait_event(wq, (file = safe_file(vma)));
 
416
        wait_event(wq, (file = au_robr_safe_file(vma)));
495
417
        AuDebugOn(!au_test_aufs(file->f_dentry->d_sb));
496
418
        dentry = file->f_dentry;
497
419
        LKTRTrace("%.*s, addr %lx\n", AuDLNPair(dentry), addr);
499
421
        AuDebugOn(!S_ISREG(inode->i_mode));
500
422
 
501
423
        /* do not revalidate, nor lock */
502
 
        finfo = ftofi(file);
 
424
        finfo = au_fi(file);
503
425
        h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
504
426
        AuDebugOn(!h_file || !au_test_mmapped(file));
505
427
        vma->vm_file = h_file;
506
428
        //smp_mb();
507
429
        page = finfo->fi_h_vm_ops->nopage(vma, addr, type);
508
430
        //file->f_ra = h_file->f_ra; //??
509
 
        reset_file(vma, file);
 
431
        au_robr_reset_file(vma, file);
510
432
#if 0 //def CONFIG_SMP
511
433
        //wake_up_nr(&wq, online_cpu - 1);
512
434
        wake_up_all(&wq);
530
452
                         int nonblock)
531
453
{
532
454
        AuUnsupport();
533
 
        return ftofi(vma->vm_file)->fi_h_vm_ops->populate
 
455
        return au_fi(vma->vm_file)->fi_h_vm_ops->populate
534
456
                (vma, addr, len, prot, pgoff, nonblock);
535
457
}
536
458
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) */
632
554
                err = generic_file_mmap(file, vma); /* instead of h_file */
633
555
                if (unlikely(err))
634
556
                        goto out_unlock;
635
 
                ftofi(file)->fi_h_vm_ops = vma->vm_ops;
 
557
                au_fi(file)->fi_h_vm_ops = vma->vm_ops;
636
558
        } else {
637
559
                vm_ops = NULL;
638
560
                if (!mmapped) {
647
569
                        goto out_unlock;
648
570
                vma->vm_ops = &aufs_vm_ops;
649
571
                if (!mmapped)
650
 
                        ftofi(file)->fi_h_vm_ops = vm_ops;
 
572
                        au_fi(file)->fi_h_vm_ops = vm_ops;
651
573
        }
652
574
 
653
575
        file_accessed(h_file);