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

« back to all changes in this revision

Viewing changes to fs/aufs25/super.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
/*
 
2
 * Copyright (C) 2005-2008 Junjiro Okajima
 
3
 *
 
4
 * This program, aufs is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
17
 */
 
18
 
 
19
/*
 
20
 * mount and super_block operations
 
21
 *
 
22
 * $Id: super.c,v 1.4 2008/05/04 23:53:02 sfjro Exp $
 
23
 */
 
24
 
 
25
#include <linux/module.h>
 
26
#include <linux/buffer_head.h>
 
27
#include <linux/seq_file.h>
 
28
#include <linux/smp_lock.h>
 
29
#include <linux/statfs.h>
 
30
 
 
31
#include "aufs.h"
 
32
 
 
33
/*
 
34
 * super_operations
 
35
 */
 
36
static struct inode *aufs_alloc_inode(struct super_block *sb)
 
37
{
 
38
        struct aufs_icntnr *c;
 
39
 
 
40
        AuTraceEnter();
 
41
 
 
42
        c = au_cache_alloc_icntnr();
 
43
        //if (LktrCond) {au_cache_free_icntnr(c); c = NULL;}
 
44
        if (c) {
 
45
                inode_init_once(&c->vfs_inode);
 
46
                c->vfs_inode.i_version = 1; //sigen(sb);
 
47
                c->iinfo.ii_hinode = NULL;
 
48
                return &c->vfs_inode;
 
49
        }
 
50
        return NULL;
 
51
}
 
52
 
 
53
static void aufs_destroy_inode(struct inode *inode)
 
54
{
 
55
        LKTRTrace("i%lu\n", inode->i_ino);
 
56
        au_iinfo_fin(inode);
 
57
        au_cache_free_icntnr(container_of(inode, struct aufs_icntnr,
 
58
                                          vfs_inode));
 
59
}
 
60
 
 
61
struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
 
62
{
 
63
        struct inode *inode;
 
64
        int err;
 
65
#if 0
 
66
        static struct backing_dev_info bdi = {
 
67
                .ra_pages       = 0,    /* No readahead */
 
68
                .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK
 
69
        };
 
70
#endif
 
71
 
 
72
        LKTRTrace("i%lu\n", ino);
 
73
 
 
74
        inode = iget_locked(sb, ino);
 
75
        if (unlikely(!inode)) {
 
76
                inode = ERR_PTR(-ENOMEM);
 
77
                goto out;
 
78
        }
 
79
        AuDebugOn(IS_ERR(inode));
 
80
        if (unlikely(!(inode->i_state & I_NEW)))
 
81
                goto out;
 
82
 
 
83
        err = au_iinfo_init(inode);
 
84
        //if (LktrCond) err = -1;
 
85
        if (!err) {
 
86
                inode->i_version++;
 
87
                inode->i_op = &aufs_iop;
 
88
                inode->i_fop = &aufs_file_fop;
 
89
                inode->i_mapping->a_ops = &aufs_aop;
 
90
                //inode->i_mapping->backing_dev_info = &bdi;
 
91
        } else {
 
92
                iget_failed(inode);
 
93
                inode = ERR_PTR(err);
 
94
        }
 
95
 
 
96
 out:
 
97
        /* never return NULL */
 
98
        AuDebugOn(!inode);
 
99
        AuTraceErrPtr(inode);
 
100
        return inode;
 
101
}
 
102
 
 
103
static int au_show_brs(struct seq_file *seq, struct super_block *sb)
 
104
{
 
105
        int err;
 
106
        aufs_bindex_t bindex, bend;
 
107
        struct dentry *root;
 
108
        struct path path;
 
109
 
 
110
        AuTraceEnter();
 
111
 
 
112
        err = 0;
 
113
        root = sb->s_root;
 
114
        bend = au_sbend(sb);
 
115
        for (bindex = 0; !err && bindex <= bend; bindex++) {
 
116
                path.mnt = au_sbr_mnt(sb, bindex);
 
117
                path.dentry = au_h_dptr(root, bindex);
 
118
                err = seq_path(seq, &path, au_esc_chars);
 
119
                if (err > 0)
 
120
                        err = seq_printf
 
121
                                (seq, "=%s",
 
122
                                 au_optstr_br_perm(au_sbr_perm(sb, bindex)));
 
123
                if (!err && bindex != bend)
 
124
                        err = seq_putc(seq, ':');
 
125
        }
 
126
 
 
127
        AuTraceErr(err);
 
128
        return err;
 
129
}
 
130
 
 
131
static void au_show_wbr_create(struct seq_file *m, int v,
 
132
                               struct au_sbinfo *sbinfo)
 
133
{
 
134
        const char *pat;
 
135
 
 
136
        AuDebugOn(v == AuWbrCreate_Def);
 
137
 
 
138
        seq_printf(m, ",create=");
 
139
        pat = au_optstr_wbr_create(v);
 
140
        switch (v) {
 
141
        case AuWbrCreate_TDP:
 
142
        case AuWbrCreate_RR:
 
143
        case AuWbrCreate_MFS:
 
144
        case AuWbrCreate_PMFS:
 
145
                seq_printf(m, pat);
 
146
                break;
 
147
        case AuWbrCreate_MFSV:
 
148
                seq_printf(m, /*pat*/"mfs:%lu",
 
149
                           sbinfo->si_wbr_mfs.mfs_expire / HZ);
 
150
                break;
 
151
        case AuWbrCreate_PMFSV:
 
152
                seq_printf(m, /*pat*/"pmfs:%lu",
 
153
                           sbinfo->si_wbr_mfs.mfs_expire / HZ);
 
154
                break;
 
155
        case AuWbrCreate_MFSRR:
 
156
                seq_printf(m, /*pat*/"mfsrr:%Lu",
 
157
                           sbinfo->si_wbr_mfs.mfsrr_watermark);
 
158
                break;
 
159
        case AuWbrCreate_MFSRRV:
 
160
                seq_printf(m, /*pat*/"mfsrr:%Lu:%lu",
 
161
                           sbinfo->si_wbr_mfs.mfsrr_watermark,
 
162
                           sbinfo->si_wbr_mfs.mfs_expire / HZ);
 
163
                break;
 
164
        }
 
165
}
 
166
 
 
167
static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt)
 
168
{
 
169
        int err, n;
 
170
        struct super_block *sb;
 
171
        struct au_sbinfo *sbinfo;
 
172
        struct dentry *root;
 
173
        struct file *xino;
 
174
        unsigned int mnt_flags, v;
 
175
        struct path path;
 
176
 
 
177
        //au_debug_on();
 
178
        AuTraceEnter();
 
179
 
 
180
        sb = mnt->mnt_sb;
 
181
        root = sb->s_root;
 
182
        aufs_read_lock(root, !AuLock_IR);
 
183
        sbinfo = au_sbi(sb);
 
184
        mnt_flags = au_mntflags(sb);
 
185
        if (au_opt_test(mnt_flags, XINO)) {
 
186
                err = seq_puts(m, ",xino=");
 
187
                if (unlikely(err))
 
188
                        goto out;
 
189
                xino = sbinfo->si_xib;
 
190
                path.mnt = xino->f_vfsmnt;
 
191
                path.dentry = xino->f_dentry;
 
192
                err = seq_path(m, &path, au_esc_chars);
 
193
                if (unlikely(err <= 0))
 
194
                        goto out;
 
195
                err = 0;
 
196
 
 
197
#define Deleted "\\040(deleted)"
 
198
                m->count -= sizeof(Deleted) - 1;
 
199
                AuDebugOn(memcmp(m->buf + m->count, Deleted,
 
200
                                 sizeof(Deleted) - 1));
 
201
#undef Deleted
 
202
        } else
 
203
                err = seq_puts(m, ",noxino");
 
204
 
 
205
#define AuBool(name, str) do { \
 
206
        v = au_opt_test(mnt_flags, name); \
 
207
        if (!err && v != au_opt_test(AuOpt_Def, name)) \
 
208
                err = seq_printf(m, ",%s" #str, v ? "" : "no"); \
 
209
} while (0)
 
210
 
 
211
#define AuStr(name, str) do { \
 
212
        v = mnt_flags & AuOptMask_##name; \
 
213
        if (!err && v != (AuOpt_Def & AuOptMask_##name)) \
 
214
                err = seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
 
215
} while (0)
 
216
 
 
217
#ifdef CONFIG_AUFS_COMPAT
 
218
#define AuStr_BrOpt     "dirs="
 
219
#else
 
220
#define AuStr_BrOpt     "br:"
 
221
#endif
 
222
 
 
223
        AuBool(TRUNC_XINO, trunc_xino);
 
224
        AuBool(DIRPERM1, dirperm1);
 
225
        AuBool(SHWH, shwh);
 
226
        AuBool(PLINK, plink);
 
227
        AuStr(UDBA, udba);
 
228
 
 
229
        v = sbinfo->si_wbr_create;
 
230
        if (v != AuWbrCreate_Def)
 
231
                au_show_wbr_create(m, v, sbinfo);
 
232
 
 
233
        v = sbinfo->si_wbr_copyup;
 
234
        if (v != AuWbrCopyup_Def)
 
235
                err = seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
 
236
 
 
237
        v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
 
238
        if (!err && v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
 
239
                err = seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
 
240
        AuBool(REFROF, refrof);
 
241
        AuBool(DLGT, dlgt);
 
242
        AuBool(WARN_PERM, warn_perm);
 
243
        AuBool(VERBOSE, verbose);
 
244
 
 
245
        n = sbinfo->si_dirwh;
 
246
        if (!err && n != AUFS_DIRWH_DEF)
 
247
                err = seq_printf(m, ",dirwh=%d", n);
 
248
        n = sbinfo->si_rdcache / HZ;
 
249
        if (!err && n != AUFS_RDCACHE_DEF)
 
250
                err = seq_printf(m, ",rdcache=%d", n);
 
251
 
 
252
        AuStr(COO, coo);
 
253
 
 
254
        if (!err && !sysaufs_brs) {
 
255
                err = seq_puts(m, "," AuStr_BrOpt);
 
256
                if (!err)
 
257
                        err = au_show_brs(m, sb);
 
258
        }
 
259
 
 
260
        /* seq_file will re-call me in case of too long string */
 
261
        err = 0;
 
262
 
 
263
 out:
 
264
        aufs_read_unlock(root, !AuLock_IR);
 
265
        AuTraceErr(err);
 
266
        if (err)
 
267
                err = -E2BIG;
 
268
        AuTraceErr(err);
 
269
        //au_debug_off();
 
270
        return err;
 
271
 
 
272
#undef AuBool
 
273
#undef AuStr
 
274
#undef AuStr_BrOpt
 
275
}
 
276
 
 
277
static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
 
278
{
 
279
        int err;
 
280
 
 
281
        AuTraceEnter();
 
282
 
 
283
        aufs_read_lock(dentry->d_sb->s_root, 0);
 
284
        err = vfsub_statfs(au_h_dptr(dentry->d_sb->s_root, 0), buf,
 
285
                           !!au_opt_test_dlgt(au_mntflags(dentry->d_sb)));
 
286
        //if (LktrCond) err = -1;
 
287
        aufs_read_unlock(dentry->d_sb->s_root, 0);
 
288
        if (!err) {
 
289
                buf->f_type = AUFS_SUPER_MAGIC;
 
290
                buf->f_namelen -= AUFS_WH_PFX_LEN;
 
291
                //todo: support uuid?
 
292
                memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
 
293
        }
 
294
        /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
 
295
 
 
296
        AuTraceErr(err);
 
297
        return err;
 
298
}
 
299
 
 
300
static void au_fsync_br(struct super_block *sb)
 
301
{
 
302
#ifdef CONFIG_AUFS_FSYNC_SUPER_PATCH
 
303
        aufs_bindex_t bend, bindex;
 
304
        int brperm;
 
305
        struct super_block *h_sb;
 
306
 
 
307
        AuTraceEnter();
 
308
 
 
309
        si_write_lock(sb);
 
310
        bend = au_sbend(sb);
 
311
        for (bindex = 0; bindex < bend; bindex++) {
 
312
                brperm = au_sbr_perm(sb, bindex);
 
313
                if (brperm == AuBr_RR || brperm == AuBr_RRWH)
 
314
                        continue;
 
315
                h_sb = au_sbr_sb(sb, bindex);
 
316
                if (bdev_read_only(h_sb->s_bdev))
 
317
                        continue;
 
318
 
 
319
                lockdep_off();
 
320
                down_write(&h_sb->s_umount);
 
321
                shrink_dcache_sb(h_sb);
 
322
                fsync_super(h_sb);
 
323
                up_write(&h_sb->s_umount);
 
324
                lockdep_on();
 
325
        }
 
326
        si_write_unlock(sb);
 
327
#endif
 
328
}
 
329
 
 
330
static void aufs_umount_begin(struct vfsmount *mnt, int flags)
 
331
{
 
332
        struct super_block *sb = mnt->mnt_sb;
 
333
        struct au_sbinfo *sbinfo;
 
334
 
 
335
        AuTraceEnter();
 
336
 
 
337
        sbinfo = au_sbi(sb);
 
338
        if (unlikely(!sbinfo))
 
339
                return;
 
340
 
 
341
        au_fsync_br(sb);
 
342
 
 
343
        si_write_lock(sb);
 
344
        if (au_opt_test(au_mntflags(sb), PLINK))
 
345
                au_plink_put(sb);
 
346
#if 0 // remove
 
347
        if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY)))
 
348
                shrink_dcache_sb(sb);
 
349
#endif
 
350
        sbinfo->si_mntcache = NULL;
 
351
#if 0
 
352
        if (sbinfo->si_wbr_create_ops->fin)
 
353
                sbinfo->si_wbr_create_ops->fin(sb);
 
354
#endif
 
355
        si_write_unlock(sb);
 
356
}
 
357
 
 
358
/* final actions when unmounting a file system */
 
359
static void aufs_put_super(struct super_block *sb)
 
360
{
 
361
        struct au_sbinfo *sbinfo;
 
362
 
 
363
        AuTraceEnter();
 
364
 
 
365
        sbinfo = au_sbi(sb);
 
366
        if (unlikely(!sbinfo))
 
367
                return;
 
368
        kobject_put(&sbinfo->si_kobj);
 
369
}
 
370
 
 
371
/* ---------------------------------------------------------------------- */
 
372
 
 
373
/*
 
374
 * refresh dentry and inode at remount time.
 
375
 */
 
376
static int do_refresh(struct dentry *dentry, mode_t type,
 
377
                      unsigned int dir_flags)
 
378
{
 
379
        int err;
 
380
        struct dentry *parent;
 
381
        struct inode *inode;
 
382
 
 
383
        LKTRTrace("%.*s, 0%o\n", AuDLNPair(dentry), type);
 
384
        inode = dentry->d_inode;
 
385
        AuDebugOn(!inode);
 
386
 
 
387
        di_write_lock_child(dentry);
 
388
        parent = dget_parent(dentry);
 
389
        di_read_lock_parent(parent, AuLock_IR);
 
390
        /* returns a number of positive dentries */
 
391
        err = au_refresh_hdentry(dentry, type);
 
392
        //err = -1;
 
393
        if (err >= 0) {
 
394
                err = au_refresh_hinode(inode, dentry);
 
395
                //err = -1;
 
396
                if (!err && type == S_IFDIR)
 
397
                        au_reset_hinotify(inode, dir_flags);
 
398
        }
 
399
        if (unlikely(err))
 
400
                AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry));
 
401
        di_read_unlock(parent, AuLock_IR);
 
402
        dput(parent);
 
403
        di_write_unlock(dentry);
 
404
 
 
405
        AuTraceErr(err);
 
406
        return err;
 
407
}
 
408
 
 
409
static int test_dir(struct dentry *dentry, void *arg)
 
410
{
 
411
        return S_ISDIR(dentry->d_inode->i_mode);
 
412
}
 
413
 
 
414
//todo: merge with refresh_nondir()
 
415
static int refresh_dir(struct dentry *root, au_gen_t sgen)
 
416
{
 
417
        int err, i, j, ndentry, e;
 
418
        const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1);
 
419
        struct au_dcsub_pages dpages;
 
420
        struct au_dpage *dpage;
 
421
        struct dentry **dentries;
 
422
        struct inode *inode;
 
423
 
 
424
        LKTRTrace("sgen %d\n", sgen);
 
425
        SiMustWriteLock(root->d_sb);
 
426
        AuDebugOn(au_digen(root) != sgen || !kernel_locked());
 
427
 
 
428
        err = 0;
 
429
        list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list)
 
430
                if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sgen) {
 
431
                        ii_write_lock_child(inode);
 
432
                        e = au_refresh_hinode_self(inode);
 
433
                        //e = -1;
 
434
                        ii_write_unlock(inode);
 
435
                        if (unlikely(e)) {
 
436
                                LKTRTrace("e %d, i%lu\n", e, inode->i_ino);
 
437
                                if (!err)
 
438
                                        err = e;
 
439
                                /* go on even if err */
 
440
                        }
 
441
                }
 
442
 
 
443
        e = au_dpages_init(&dpages, GFP_TEMPORARY);
 
444
        if (unlikely(e)) {
 
445
                if (!err)
 
446
                        err = e;
 
447
                goto out;
 
448
        }
 
449
        e = au_dcsub_pages(&dpages, root, test_dir, NULL);
 
450
        if (unlikely(e)) {
 
451
                if (!err)
 
452
                        err = e;
 
453
                goto out_dpages;
 
454
        }
 
455
 
 
456
        for (i = 0; !e && i < dpages.ndpage; i++) {
 
457
                dpage = dpages.dpages + i;
 
458
                dentries = dpage->dentries;
 
459
                ndentry = dpage->ndentry;
 
460
                for (j = 0; !e && j < ndentry; j++) {
 
461
                        struct dentry *d;
 
462
                        d = dentries[j];
 
463
#ifdef CONFIG_AUFS_DEBUG
 
464
                        {
 
465
                                struct dentry *parent;
 
466
                                parent = dget_parent(d);
 
467
                                AuDebugOn(!S_ISDIR(d->d_inode->i_mode)
 
468
                                          || IS_ROOT(d)
 
469
                                          || au_digen(parent) != sgen);
 
470
                                dput(parent);
 
471
                        }
 
472
#endif
 
473
                        if (au_digen(d) != sgen) {
 
474
                                e = do_refresh(d, S_IFDIR, flags);
 
475
                                //e = -1;
 
476
                                if (unlikely(e && !err))
 
477
                                        err = e;
 
478
                                /* break on err */
 
479
                        }
 
480
                }
 
481
        }
 
482
 
 
483
 out_dpages:
 
484
        au_dpages_free(&dpages);
 
485
 out:
 
486
        AuTraceErr(err);
 
487
        return err;
 
488
}
 
489
 
 
490
static int test_nondir(struct dentry *dentry, void *arg)
 
491
{
 
492
        return !S_ISDIR(dentry->d_inode->i_mode);
 
493
}
 
494
 
 
495
static int refresh_nondir(struct dentry *root, au_gen_t sgen, int do_dentry)
 
496
{
 
497
        int err, i, j, ndentry, e;
 
498
        struct au_dcsub_pages dpages;
 
499
        struct au_dpage *dpage;
 
500
        struct dentry **dentries;
 
501
        struct inode *inode;
 
502
 
 
503
        LKTRTrace("sgen %d\n", sgen);
 
504
        SiMustWriteLock(root->d_sb);
 
505
        AuDebugOn(au_digen(root) != sgen || !kernel_locked());
 
506
 
 
507
        err = 0;
 
508
        list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list)
 
509
                if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sgen) {
 
510
                        ii_write_lock_child(inode);
 
511
                        e = au_refresh_hinode_self(inode);
 
512
                        //e = -1;
 
513
                        ii_write_unlock(inode);
 
514
                        if (unlikely(e)) {
 
515
                                LKTRTrace("e %d, i%lu\n", e, inode->i_ino);
 
516
                                if (!err)
 
517
                                        err = e;
 
518
                                /* go on even if err */
 
519
                        }
 
520
                }
 
521
 
 
522
        if (!do_dentry)
 
523
                goto out;
 
524
 
 
525
        e = au_dpages_init(&dpages, GFP_TEMPORARY);
 
526
        if (unlikely(e)) {
 
527
                if (!err)
 
528
                        err = e;
 
529
                goto out;
 
530
        }
 
531
        e = au_dcsub_pages(&dpages, root, test_nondir, NULL);
 
532
        if (unlikely(e)) {
 
533
                if (!err)
 
534
                        err = e;
 
535
                goto out_dpages;
 
536
        }
 
537
 
 
538
        for (i = 0; i < dpages.ndpage; i++) {
 
539
                dpage = dpages.dpages + i;
 
540
                dentries = dpage->dentries;
 
541
                ndentry = dpage->ndentry;
 
542
                for (j = 0; j < ndentry; j++) {
 
543
                        struct dentry *d;
 
544
                        d = dentries[j];
 
545
#ifdef CONFIG_AUFS_DEBUG
 
546
                        {
 
547
                                struct dentry *parent;
 
548
                                parent = dget_parent(d);
 
549
                                AuDebugOn(S_ISDIR(d->d_inode->i_mode)
 
550
                                          || au_digen(parent) != sgen);
 
551
                                dput(parent);
 
552
                        }
 
553
#endif
 
554
                        inode = d->d_inode;
 
555
                        if (inode && au_digen(d) != sgen) {
 
556
                                e = do_refresh(d, inode->i_mode & S_IFMT, 0);
 
557
                                //e = -1;
 
558
                                if (unlikely(e && !err))
 
559
                                        err = e;
 
560
                                /* go on even err */
 
561
                        }
 
562
                }
 
563
        }
 
564
 
 
565
 out_dpages:
 
566
        au_dpages_free(&dpages);
 
567
 out:
 
568
        AuTraceErr(err);
 
569
        return err;
 
570
}
 
571
 
 
572
/* stop extra interpretation of errno in mount(8), and strange error messages */
 
573
static int cvt_err(int err)
 
574
{
 
575
        AuTraceErr(err);
 
576
 
 
577
        switch (err) {
 
578
        case -ENOENT:
 
579
        case -ENOTDIR:
 
580
        case -EEXIST:
 
581
        case -EIO:
 
582
                err = -EINVAL;
 
583
        }
 
584
        return err;
 
585
}
 
586
 
 
587
/* protected by s_umount */
 
588
static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
 
589
{
 
590
        int err;
 
591
        struct dentry *root;
 
592
        struct inode *inode;
 
593
        struct au_opts opts;
 
594
        unsigned int dlgt;
 
595
        struct au_sbinfo *sbinfo;
 
596
 
 
597
        //au_debug_on();
 
598
        LKTRTrace("flags 0x%x, data %s, len %lu\n",
 
599
                  *flags, data ? data : "NULL",
 
600
                  (unsigned long)(data ? strlen(data) : 0));
 
601
 
 
602
        au_fsync_br(sb);
 
603
        err = 0;
 
604
        if (!data || !*data)
 
605
                goto out; /* success */
 
606
 
 
607
        err = -ENOMEM;
 
608
        memset(&opts, 0, sizeof(opts));
 
609
        opts.opt = (void *)__get_free_page(GFP_TEMPORARY);
 
610
        //if (LktrCond) {free_page((unsigned long)opts.opt); opts.opt = NULL;}
 
611
        if (unlikely(!opts.opt))
 
612
                goto out;
 
613
        opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
 
614
        opts.flags = AuOpts_REMOUNT;
 
615
 
 
616
        /* parse it before aufs lock */
 
617
        err = au_opts_parse(sb, *flags, data, &opts);
 
618
        //if (LktrCond) {au_free_opts(&opts); err = -1;}
 
619
        if (unlikely(err))
 
620
                goto out_opts;
 
621
 
 
622
        sbinfo = au_sbi(sb);
 
623
        root = sb->s_root;
 
624
        inode = root->d_inode;
 
625
        mutex_lock(&inode->i_mutex);
 
626
        aufs_write_lock(root);
 
627
 
 
628
        //DbgSleep(3);
 
629
 
 
630
        /* au_do_opts() may return an error */
 
631
        err = au_opts_remount(sb, &opts);
 
632
        //if (LktrCond) err = -1;
 
633
        au_opts_free(&opts);
 
634
 
 
635
        if (au_ftest_opts(opts.flags, REFRESH_DIR)
 
636
            || au_ftest_opts(opts.flags, REFRESH_NONDIR)) {
 
637
                int rerr;
 
638
                au_gen_t sigen;
 
639
 
 
640
                dlgt = !!au_opt_test_dlgt(sbinfo->si_mntflags);
 
641
                au_opt_clr(sbinfo->si_mntflags, DLGT);
 
642
                au_sigen_inc(sb);
 
643
                au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1));
 
644
                sigen = au_sigen(sb);
 
645
                au_fclr_si(sbinfo, FAILED_REFRESH_DIRS);
 
646
 
 
647
                DiMustNoWaiters(root);
 
648
                IiMustNoWaiters(root->d_inode);
 
649
                di_write_unlock(root);
 
650
 
 
651
                rerr = refresh_dir(root, sigen);
 
652
                if (unlikely(rerr)) {
 
653
                        au_fset_si(sbinfo, FAILED_REFRESH_DIRS);
 
654
                        AuWarn("Refreshing directories failed, ignores (%d)\n",
 
655
                               rerr);
 
656
                }
 
657
 
 
658
                if (unlikely(au_ftest_opts(opts.flags, REFRESH_NONDIR))) {
 
659
                        //au_debug_on();
 
660
                        rerr = refresh_nondir(root, sigen, !rerr);
 
661
                        if (unlikely(rerr))
 
662
                                AuWarn("Refreshing non-directories failed,"
 
663
                                       " ignores (%d)\n", rerr);
 
664
                        //au_debug_off();
 
665
                }
 
666
 
 
667
                /* aufs_write_lock() calls ..._child() */
 
668
                di_write_lock_child(root);
 
669
 
 
670
                au_cpup_attr_all(inode);
 
671
                if (unlikely(dlgt))
 
672
                        au_opt_set(sbinfo->si_mntflags, DLGT);
 
673
        }
 
674
 
 
675
        aufs_write_unlock(root);
 
676
        mutex_unlock(&inode->i_mutex);
 
677
 
 
678
 out_opts:
 
679
        free_page((unsigned long)opts.opt);
 
680
 out:
 
681
        err = cvt_err(err);
 
682
        AuTraceErr(err);
 
683
        //au_debug_off();
 
684
        return err;
 
685
}
 
686
 
 
687
static struct super_operations aufs_sop = {
 
688
        .alloc_inode    = aufs_alloc_inode,
 
689
        .destroy_inode  = aufs_destroy_inode,
 
690
        //.dirty_inode  = aufs_dirty_inode,
 
691
        //.write_inode  = aufs_write_inode,
 
692
        //void (*put_inode) (struct inode *);
 
693
        .drop_inode     = generic_delete_inode,
 
694
        //.delete_inode = aufs_delete_inode,
 
695
        //.clear_inode  = aufs_clear_inode,
 
696
 
 
697
        .show_options   = aufs_show_options,
 
698
        .statfs         = aufs_statfs,
 
699
 
 
700
        .put_super      = aufs_put_super,
 
701
        //void (*write_super) (struct super_block *);
 
702
        //int (*sync_fs)(struct super_block *sb, int wait);
 
703
        //void (*write_super_lockfs) (struct super_block *);
 
704
        //void (*unlockfs) (struct super_block *);
 
705
        .remount_fs     = aufs_remount_fs,
 
706
        /* depends upon umount flags. also use put_super() (< 2.6.18) */
 
707
        .umount_begin   = aufs_umount_begin
 
708
};
 
709
 
 
710
/* ---------------------------------------------------------------------- */
 
711
 
 
712
static int alloc_root(struct super_block *sb)
 
713
{
 
714
        int err;
 
715
        struct inode *inode;
 
716
        struct dentry *root;
 
717
 
 
718
        AuTraceEnter();
 
719
 
 
720
        err = -ENOMEM;
 
721
        inode = au_iget_locked(sb, AUFS_ROOT_INO);
 
722
        //if (LktrCond) {iput(inode); inode = NULL;}
 
723
        err = PTR_ERR(inode);
 
724
        if (IS_ERR(inode))
 
725
                goto out;
 
726
        unlock_new_inode(inode);
 
727
        inode->i_mode = S_IFDIR;
 
728
        root = d_alloc_root(inode);
 
729
        //if (LktrCond) {igrab(inode); dput(root); root = NULL;}
 
730
        if (unlikely(!root))
 
731
                goto out_iput;
 
732
        err = PTR_ERR(root);
 
733
        if (IS_ERR(root))
 
734
                goto out_iput;
 
735
 
 
736
        err = au_alloc_dinfo(root);
 
737
        //if (LktrCond){au_rw_write_unlock(&au_di(root)->di_rwsem);err=-1;}
 
738
        if (!err) {
 
739
                sb->s_root = root;
 
740
                return 0; /* success */
 
741
        }
 
742
        dput(root);
 
743
        goto out; /* do not iput */
 
744
 
 
745
 out_iput:
 
746
        iget_failed(inode);
 
747
        iput(inode);
 
748
 out:
 
749
        AuTraceErr(err);
 
750
        return err;
 
751
 
 
752
}
 
753
 
 
754
static int aufs_fill_super(struct super_block *sb, void *raw_data, int silent)
 
755
{
 
756
        int err;
 
757
        struct dentry *root;
 
758
        struct inode *inode;
 
759
        struct au_opts opts;
 
760
        char *arg = raw_data;
 
761
 
 
762
        //au_debug_on();
 
763
        if (unlikely(!arg || !*arg)) {
 
764
                err = -EINVAL;
 
765
                AuErr("no arg\n");
 
766
                goto out;
 
767
        }
 
768
        LKTRTrace("%s, silent %d\n", arg, silent);
 
769
 
 
770
        err = -ENOMEM;
 
771
        memset(&opts, 0, sizeof(opts));
 
772
        opts.opt = (void *)__get_free_page(GFP_TEMPORARY);
 
773
        //if (LktrCond) {free_page((unsigned long)opts.opt); opts.opt = NULL;}
 
774
        if (unlikely(!opts.opt))
 
775
                goto out;
 
776
        opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
 
777
 
 
778
        err = au_si_alloc(sb);
 
779
        //if (LktrCond) {si_write_unlock(sb);free_sbinfo(sb);err=-1;}
 
780
        if (unlikely(err))
 
781
                goto out_opts;
 
782
        SiMustWriteLock(sb);
 
783
        /* all timestamps always follow the ones on the branch */
 
784
        sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
 
785
        sb->s_op = &aufs_sop;
 
786
        sb->s_magic = AUFS_SUPER_MAGIC;
 
787
        au_init_export_op(sb);
 
788
 
 
789
        err = alloc_root(sb);
 
790
        //if (LktrCond) {au_rw_write_unlock(&au_di(sb->s_root)->di_rwsem);
 
791
        //dput(sb->s_root);sb->s_root=NULL;err=-1;}
 
792
        if (unlikely(err)) {
 
793
                AuDebugOn(sb->s_root);
 
794
                si_write_unlock(sb);
 
795
                goto out_info;
 
796
        }
 
797
        root = sb->s_root;
 
798
        DiMustWriteLock(root);
 
799
        inode = root->d_inode;
 
800
        inode->i_nlink = 2;
 
801
 
 
802
        /*
 
803
         * actually we can parse options regardless aufs lock here.
 
804
         * but at remount time, parsing must be done before aufs lock.
 
805
         * so we follow the same rule.
 
806
         */
 
807
        ii_write_lock_parent(inode);
 
808
        aufs_write_unlock(root);
 
809
        err = au_opts_parse(sb, sb->s_flags, arg, &opts);
 
810
        //if (LktrCond) {au_opts_free(&opts); err = -1;}
 
811
        if (unlikely(err))
 
812
                goto out_root;
 
813
 
 
814
        /* lock vfs_inode first, then aufs. */
 
815
        mutex_lock(&inode->i_mutex);
 
816
        inode->i_op = &aufs_dir_iop;
 
817
        inode->i_fop = &aufs_dir_fop;
 
818
        aufs_write_lock(root);
 
819
 
 
820
        sb->s_maxbytes = 0;
 
821
        err = au_opts_mount(sb, &opts);
 
822
        //if (LktrCond) err = -1;
 
823
        au_opts_free(&opts);
 
824
        if (unlikely(err))
 
825
                goto out_unlock;
 
826
        AuDebugOn(!sb->s_maxbytes);
 
827
 
 
828
        //AuDbgDentry(root);
 
829
        aufs_write_unlock(root);
 
830
        mutex_unlock(&inode->i_mutex);
 
831
        //AuDbgSb(sb);
 
832
        goto out_opts; /* success */
 
833
 
 
834
 out_unlock:
 
835
        aufs_write_unlock(root);
 
836
        mutex_unlock(&inode->i_mutex);
 
837
 out_root:
 
838
        dput(root);
 
839
        sb->s_root = NULL;
 
840
 out_info:
 
841
        au_fset_si(au_sbi(sb), FAILED_INIT);
 
842
        kobject_put(&au_sbi(sb)->si_kobj);
 
843
        sb->s_fs_info = NULL;
 
844
 out_opts:
 
845
        free_page((unsigned long)opts.opt);
 
846
 out:
 
847
        AuTraceErr(err);
 
848
        err = cvt_err(err);
 
849
        AuTraceErr(err);
 
850
        //au_debug_off();
 
851
        return err;
 
852
}
 
853
 
 
854
/* ---------------------------------------------------------------------- */
 
855
 
 
856
static int aufs_get_sb(struct file_system_type *fs_type, int flags,
 
857
                       const char *dev_name, void *raw_data,
 
858
                       struct vfsmount *mnt)
 
859
{
 
860
        int err;
 
861
 
 
862
        /* all timestamps always follow the ones on the branch */
 
863
        /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
 
864
        err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt);
 
865
        if (!err) {
 
866
                struct super_block *sb = mnt->mnt_sb;
 
867
                struct au_sbinfo *sbinfo = au_sbi(sb);
 
868
 
 
869
                /* no get/put */
 
870
                sbinfo->si_mntcache = mnt;
 
871
                sbinfo->si_sb = sb;
 
872
 
 
873
                au_sbilist_lock();
 
874
                au_sbilist_add(sbinfo);
 
875
                si_write_lock(sb);
 
876
                sysaufs_brs_add(sb, 0);
 
877
                si_write_unlock(sb);
 
878
                au_sbilist_unlock();
 
879
        }
 
880
        return err;
 
881
}
 
882
 
 
883
struct file_system_type aufs_fs_type = {
 
884
        .name           = AUFS_FSTYPE,
 
885
        .fs_flags       = FS_REVAL_DOT, /* for UDBA and NFS branch */
 
886
        .get_sb         = aufs_get_sb,
 
887
        .kill_sb        = generic_shutdown_super,
 
888
        //.kill_sb      = kill_anon_super,
 
889
        /* no need to __module_get() and module_put(). */
 
890
        .owner          = THIS_MODULE,
 
891
};