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

« back to all changes in this revision

Viewing changes to fs/aufs25/dentry.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
/*
 
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
 * lookup and dentry operations
 
21
 *
 
22
 * $Id: dentry.c,v 1.4 2008/05/04 23:51:55 sfjro Exp $
 
23
 */
 
24
 
 
25
//#include <linux/fs.h>
 
26
//#include <linux/namei.h>
 
27
#include "aufs.h"
 
28
 
 
29
/* ---------------------------------------------------------------------- */
 
30
 
 
31
/*
 
32
 * au_lkup_one() is a generic abstract entry function which calls
 
33
 * lookup_one_len() or __lookup_hash() finally. it is some condisions that makes
 
34
 * lookup complicated, which are nfs branch, open-intent and dlgt mode.
 
35
 */
 
36
 
 
37
#if defined(CONFIG_AUFS_BR_NFS) || defined(CONFIG_AUFS_DLGT)
 
38
/* cf. lookup_one_len() in linux/fs/namei.c */
 
39
struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len,
 
40
                           struct au_ndx *ndx)
 
41
{
 
42
        struct dentry *dentry;
 
43
 
 
44
        LKTRTrace("%.*s/%.*s, ndx{%d, 0x%x}\n",
 
45
                  AuDLNPair(parent), len, name, !!ndx->nfsmnt, ndx->flags);
 
46
 
 
47
        ndx->nd_file = NULL;
 
48
        if (!ndx->nfsmnt)
 
49
                dentry = au_lkup_one_dlgt(name, parent, len, ndx->flags);
 
50
        else
 
51
                dentry = au_lkup_hash(name, parent, len, ndx);
 
52
 
 
53
        AuTraceErrPtr(dentry);
 
54
        return dentry;
 
55
}
 
56
#endif /* CONFIG_AUFS_BR_NFS || CONFIG_AUFS_DLGT */
 
57
 
 
58
struct au_lkup_one_args {
 
59
        struct dentry **errp;
 
60
        const char *name;
 
61
        struct dentry *parent;
 
62
        int len;
 
63
        struct au_ndx *ndx;
 
64
};
 
65
 
 
66
static void au_call_lkup_one(void *args)
 
67
{
 
68
        struct au_lkup_one_args *a = args;
 
69
        *a->errp = au_lkup_one(a->name, a->parent, a->len, a->ndx);
 
70
}
 
71
 
 
72
#define AuLkup_ALLOW_NEG        1
 
73
#define AuLkup_DLGT             (1 << 1)
 
74
#define AuLkup_DIRPERM1         (1 << 2)
 
75
#define au_ftest_lkup(flags, name)      ((flags) & AuLkup_##name)
 
76
#define au_fset_lkup(flags, name)       { (flags) |= AuLkup_##name; }
 
77
#define au_fclr_lkup(flags, name)       { (flags) &= ~AuLkup_##name; }
 
78
#ifndef CONFIG_AUFS_DLGT
 
79
#undef AuLkup_DLGT
 
80
#define AuLkup_DLGT     0
 
81
#undef AuLkup_DIRPERM1
 
82
#define AuLkup_DIRPERM1 0
 
83
#endif
 
84
 
 
85
struct au_do_lookup_args {
 
86
        unsigned int            flags;
 
87
        mode_t                  type;
 
88
        struct nameidata        *nd;
 
89
};
 
90
 
 
91
/*
 
92
 * returns positive/negative dentry, NULL or an error.
 
93
 * NULL means whiteout-ed or not-found.
 
94
 */
 
95
static noinline_for_stack
 
96
struct dentry *au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
 
97
                            aufs_bindex_t bindex, struct qstr *wh_name,
 
98
                            struct au_do_lookup_args *args)
 
99
{
 
100
        struct dentry *h_dentry;
 
101
        int wh_found, wh_able, opq, err;
 
102
        struct inode *h_dir, *h_inode, *inode;
 
103
        struct qstr *name;
 
104
        struct super_block *sb;
 
105
        unsigned int nd_flags;
 
106
        struct au_ndx ndx = {
 
107
                .flags  = 0,
 
108
                .nd     = args->nd
 
109
        };
 
110
        const int allow_neg = au_ftest_lkup(args->flags, ALLOW_NEG);
 
111
 
 
112
        LKTRTrace("%.*s/%.*s, b%d, {flags 0x%x, type 0%o, nd %d}\n",
 
113
                  AuDLNPair(h_parent), AuDLNPair(dentry), bindex,
 
114
                  args->flags, args->type, !!args->nd);
 
115
        AuDebugOn(IS_ROOT(dentry));
 
116
        h_dir = h_parent->d_inode;
 
117
 
 
118
        nd_flags = 0;
 
119
        wh_found = 0;
 
120
        sb = dentry->d_sb;
 
121
        ndx.nfsmnt = au_nfsmnt(sb, bindex);
 
122
        if (unlikely(au_ftest_lkup(args->flags, DLGT)))
 
123
                au_fset_ndx(ndx.flags, DLGT);
 
124
        if (unlikely(au_ftest_lkup(args->flags, DIRPERM1)))
 
125
                au_fset_ndx(ndx.flags, DIRPERM1);
 
126
        LKTRTrace("nfsmnt %p\n", ndx.nfsmnt);
 
127
        ndx.br = au_sbr(sb, bindex);
 
128
        wh_able = au_br_whable(ndx.br->br_perm);
 
129
        name = &dentry->d_name;
 
130
        if (unlikely(wh_able))
 
131
                wh_found = au_test_robr_wh(name, h_parent, wh_name,
 
132
                                           /*try_sio*/0, &ndx);
 
133
        //if (LktrCond) wh_found = -1;
 
134
        h_dentry = ERR_PTR(wh_found);
 
135
        if (!wh_found)
 
136
                goto real_lookup;
 
137
        if (unlikely(wh_found < 0))
 
138
                goto out;
 
139
 
 
140
        /* We found a whiteout */
 
141
        //au_set_dbend(dentry, bindex);
 
142
        au_set_dbwh(dentry, bindex);
 
143
        if (!allow_neg)
 
144
                return NULL; /* success */
 
145
        if (unlikely(ndx.nd
 
146
                     && au_test_nfs(h_parent->d_sb)
 
147
                     && (ndx.nd->flags & LOOKUP_CREATE))) {
 
148
                nd_flags = ndx.nd->flags;
 
149
                ndx.nd->flags &= ~(LOOKUP_OPEN | LOOKUP_CREATE);
 
150
        }
 
151
 
 
152
 real_lookup:
 
153
        /* do not superio. */
 
154
        h_dentry = au_lkup_one(name->name, h_parent, name->len, &ndx);
 
155
        //if (LktrCond) {dput(h_dentry); h_dentry = ERR_PTR(-1);}
 
156
        if (IS_ERR(h_dentry))
 
157
                goto out;
 
158
        AuDebugOn(d_unhashed(h_dentry));
 
159
        h_inode = h_dentry->d_inode;
 
160
        if (!h_inode) {
 
161
                if (!allow_neg)
 
162
                        goto out_neg;
 
163
        } else if (wh_found
 
164
                   || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
 
165
                goto out_neg;
 
166
 
 
167
        if (au_dbend(dentry) <= bindex)
 
168
                au_set_dbend(dentry, bindex);
 
169
        if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
 
170
                au_set_dbstart(dentry, bindex);
 
171
        au_set_h_dptr(dentry, bindex, h_dentry);
 
172
 
 
173
        err = au_br_nfs_h_intent(ndx.nd_file, dentry, bindex, args->nd);
 
174
        if (unlikely(err)) {
 
175
                h_dentry = ERR_PTR(err);
 
176
                goto out;
 
177
        }
 
178
 
 
179
        inode = dentry->d_inode;
 
180
        if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
 
181
            || (inode && !S_ISDIR(inode->i_mode)))
 
182
                goto out; /* success */
 
183
 
 
184
        mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
 
185
        opq = au_diropq_test(h_dentry, &ndx);
 
186
        //if (LktrCond) opq = -1;
 
187
        mutex_unlock(&h_inode->i_mutex);
 
188
        if (opq > 0)
 
189
                au_set_dbdiropq(dentry, bindex);
 
190
        else if (unlikely(opq < 0)) {
 
191
                au_set_h_dptr(dentry, bindex, NULL);
 
192
                h_dentry = ERR_PTR(opq);
 
193
        }
 
194
        goto out;
 
195
 
 
196
 out_neg:
 
197
        dput(h_dentry);
 
198
        h_dentry = NULL;
 
199
 out:
 
200
        if (unlikely(nd_flags))
 
201
                ndx.nd->flags |= (nd_flags & (LOOKUP_OPEN | LOOKUP_CREATE));
 
202
        AuTraceErrPtr(h_dentry);
 
203
        return h_dentry;
 
204
}
 
205
 
 
206
/*
 
207
 * returns the number of hidden positive dentries,
 
208
 * otherwise an error.
 
209
 * can be called at unlinking with @type is zero.
 
210
 */
 
211
int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
 
212
                   struct nameidata *nd)
 
213
{
 
214
        int npositive, err, isdir;
 
215
        struct dentry *parent;
 
216
        aufs_bindex_t bindex, btail, bdiropq;
 
217
        const struct qstr *name = &dentry->d_name;
 
218
        struct qstr whname;
 
219
        struct super_block *sb;
 
220
        unsigned int mnt_flags;
 
221
        struct inode *inode;
 
222
        struct au_do_lookup_args args = {
 
223
                .type   = type,
 
224
                .nd     = nd
 
225
        };
 
226
 
 
227
        LKTRTrace("%.*s, b%d, type 0%o\n", AuLNPair(name), bstart, type);
 
228
        AuDebugOn(bstart < 0 || IS_ROOT(dentry));
 
229
 
 
230
        /* dir may not be locked */
 
231
        parent = dget_parent(dentry);
 
232
 
 
233
        err = au_test_robr_shwh(dentry->d_sb, name);
 
234
        if (unlikely(err))
 
235
                goto out;
 
236
 
 
237
        err = au_wh_name_alloc(name->name, name->len, &whname);
 
238
        //if (LktrCond) {au_wh_name_free(&whname); err = -1;}
 
239
        if (unlikely(err))
 
240
                goto out;
 
241
 
 
242
        sb = dentry->d_sb;
 
243
        mnt_flags = au_mntflags(sb);
 
244
        inode = dentry->d_inode;
 
245
        isdir = (inode && S_ISDIR(inode->i_mode));
 
246
        args.flags = 0;
 
247
        if (unlikely(au_opt_test_dlgt(mnt_flags)))
 
248
                au_fset_lkup(args.flags, DLGT);
 
249
        if (unlikely(au_opt_test_dirperm1(mnt_flags)))
 
250
                au_fset_lkup(args.flags, DIRPERM1);
 
251
        if (!type)
 
252
                au_fset_lkup(args.flags, ALLOW_NEG);
 
253
        npositive = 0;
 
254
        btail = au_dbtaildir(parent);
 
255
        for (bindex = bstart; bindex <= btail; bindex++) {
 
256
                struct dentry *h_parent, *h_dentry;
 
257
                struct inode *h_inode, *h_dir;
 
258
 
 
259
                h_dentry = au_h_dptr(dentry, bindex);
 
260
                if (h_dentry) {
 
261
                        if (h_dentry->d_inode)
 
262
                                npositive++;
 
263
                        if (type != S_IFDIR)
 
264
                                break;
 
265
                        continue;
 
266
                }
 
267
                h_parent = au_h_dptr(parent, bindex);
 
268
                if (!h_parent)
 
269
                        continue;
 
270
                h_dir = h_parent->d_inode;
 
271
                if (!h_dir || !S_ISDIR(h_dir->i_mode))
 
272
                        continue;
 
273
 
 
274
                mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
 
275
                h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
 
276
                                        &args);
 
277
                // do not dput for testing
 
278
                //if (LktrCond) {h_dentry = ERR_PTR(-1);}
 
279
                mutex_unlock(&h_dir->i_mutex);
 
280
                err = PTR_ERR(h_dentry);
 
281
                if (IS_ERR(h_dentry))
 
282
                        goto out_wh;
 
283
                au_fclr_lkup(args.flags, ALLOW_NEG);
 
284
 
 
285
                if (au_dbwh(dentry) >= 0)
 
286
                        break;
 
287
                if (!h_dentry)
 
288
                        continue;
 
289
                h_inode = h_dentry->d_inode;
 
290
                if (!h_inode)
 
291
                        continue;
 
292
                npositive++;
 
293
                if (!args.type)
 
294
                        args.type = h_inode->i_mode & S_IFMT;
 
295
                if (args.type != S_IFDIR)
 
296
                        break;
 
297
                else if (isdir) {
 
298
                        /* the type of lowers may be different */
 
299
                        bdiropq = au_dbdiropq(dentry);
 
300
                        if (bdiropq >= 0 && bdiropq <= bindex)
 
301
                                break;
 
302
                }
 
303
        }
 
304
 
 
305
        if (npositive) {
 
306
                LKTRLabel(positive);
 
307
                au_update_dbstart(dentry);
 
308
        }
 
309
        err = npositive;
 
310
 
 
311
 out_wh:
 
312
        au_wh_name_free(&whname);
 
313
 out:
 
314
        dput(parent);
 
315
        AuTraceErr(err);
 
316
        return err;
 
317
}
 
318
 
 
319
struct dentry *au_sio_lkup_one(const char *name, struct dentry *parent, int len,
 
320
                               struct au_ndx *ndx)
 
321
{
 
322
        struct dentry *dentry;
 
323
        int wkq_err;
 
324
 
 
325
        LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name);
 
326
 
 
327
        if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC,
 
328
                                au_ftest_ndx(ndx->flags, DLGT)))
 
329
                dentry = au_lkup_one(name, parent, len, ndx);
 
330
        else {
 
331
                // ugly
 
332
                unsigned int flags = ndx->flags;
 
333
                struct au_lkup_one_args args = {
 
334
                        .errp   = &dentry,
 
335
                        .name   = name,
 
336
                        .parent = parent,
 
337
                        .len    = len,
 
338
                        .ndx    = ndx
 
339
                };
 
340
 
 
341
                au_fclr_ndx(ndx->flags, DLGT);
 
342
                au_fclr_ndx(ndx->flags, DIRPERM1);
 
343
                wkq_err = au_wkq_wait(au_call_lkup_one, &args, /*dlgt*/0);
 
344
                if (unlikely(wkq_err))
 
345
                        dentry = ERR_PTR(wkq_err);
 
346
                ndx->flags = flags;
 
347
        }
 
348
 
 
349
        AuTraceErrPtr(dentry);
 
350
        return dentry;
 
351
}
 
352
 
 
353
/*
 
354
 * lookup @dentry on @bindex which should be negative.
 
355
 */
 
356
int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex)
 
357
{
 
358
        int err;
 
359
        struct dentry *parent, *h_parent, *h_dentry;
 
360
        struct inode *h_dir;
 
361
        struct au_ndx ndx = {
 
362
                .flags  = 0,
 
363
                .nd     = NULL,
 
364
                //.br   = NULL
 
365
        };
 
366
        struct super_block *sb;
 
367
        unsigned int mnt_flags;
 
368
 
 
369
        LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bindex);
 
370
        /* dir may not be locked */
 
371
        parent = dget_parent(dentry);
 
372
        AuDebugOn(!parent || !parent->d_inode
 
373
                  || !S_ISDIR(parent->d_inode->i_mode));
 
374
        h_parent = au_h_dptr(parent, bindex);
 
375
        AuDebugOn(!h_parent);
 
376
        h_dir = h_parent->d_inode;
 
377
        AuDebugOn(!h_dir || !S_ISDIR(h_dir->i_mode));
 
378
 
 
379
        sb = dentry->d_sb;
 
380
        mnt_flags = au_mntflags(sb);
 
381
        ndx.nfsmnt = au_nfsmnt(sb, bindex);
 
382
        if (unlikely(au_opt_test_dlgt(mnt_flags)))
 
383
                au_fset_ndx(ndx.flags, DLGT);
 
384
        if (unlikely(au_opt_test_dirperm1(mnt_flags)))
 
385
                au_fset_ndx(ndx.flags, DIRPERM1);
 
386
        h_dentry = au_sio_lkup_one(dentry->d_name.name, h_parent,
 
387
                                   dentry->d_name.len, &ndx);
 
388
        //if (LktrCond) {dput(h_dentry); h_dentry = ERR_PTR(-1);}
 
389
        err = PTR_ERR(h_dentry);
 
390
        if (IS_ERR(h_dentry))
 
391
                goto out;
 
392
        if (unlikely(h_dentry->d_inode)) {
 
393
                err = -EIO;
 
394
                AuIOErr("b%d %.*s should be negative.\n",
 
395
                        bindex, AuDLNPair(h_dentry));
 
396
                dput(h_dentry);
 
397
                goto out;
 
398
        }
 
399
 
 
400
        if (bindex < au_dbstart(dentry))
 
401
                au_set_dbstart(dentry, bindex);
 
402
        if (au_dbend(dentry) < bindex)
 
403
                au_set_dbend(dentry, bindex);
 
404
        au_set_h_dptr(dentry, bindex, h_dentry);
 
405
        err = 0;
 
406
 
 
407
 out:
 
408
        dput(parent);
 
409
        AuTraceErr(err);
 
410
        return err;
 
411
}
 
412
 
 
413
/*
 
414
 * returns the number of found hidden positive dentries,
 
415
 * otherwise an error.
 
416
 */
 
417
int au_refresh_hdentry(struct dentry *dentry, mode_t type)
 
418
{
 
419
        int npositive, new_sz;
 
420
        struct au_dinfo *dinfo;
 
421
        struct super_block *sb;
 
422
        struct dentry *parent;
 
423
        aufs_bindex_t bindex, parent_bend, parent_bstart, bwh, bdiropq, bend;
 
424
        struct au_hdentry *p;
 
425
        au_gen_t sgen;
 
426
 
 
427
        LKTRTrace("%.*s, type 0%o\n", AuDLNPair(dentry), type);
 
428
        DiMustWriteLock(dentry);
 
429
        sb = dentry->d_sb;
 
430
        AuDebugOn(IS_ROOT(dentry));
 
431
        sgen = au_sigen(sb);
 
432
        parent = dget_parent(dentry);
 
433
        AuDebugOn(au_digen(parent) != sgen
 
434
                  || au_iigen(parent->d_inode) != sgen);
 
435
 
 
436
        npositive = -ENOMEM;
 
437
        new_sz = sizeof(*dinfo->di_hdentry) * (au_sbend(sb) + 1);
 
438
        dinfo = au_di(dentry);
 
439
        p = au_kzrealloc(dinfo->di_hdentry, sizeof(*p) * (dinfo->di_bend + 1),
 
440
                         new_sz, GFP_KERNEL);
 
441
        //p = NULL;
 
442
        if (unlikely(!p))
 
443
                goto out;
 
444
        dinfo->di_hdentry = p;
 
445
 
 
446
        bend = dinfo->di_bend;
 
447
        bwh = dinfo->di_bwh;
 
448
        bdiropq = dinfo->di_bdiropq;
 
449
        p += dinfo->di_bstart;
 
450
        for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
 
451
                struct dentry *hd, *hdp;
 
452
                struct au_hdentry tmp, *q;
 
453
                aufs_bindex_t new_bindex;
 
454
 
 
455
                hd = p->hd_dentry;
 
456
                if (!hd)
 
457
                        continue;
 
458
                hdp = dget_parent(hd);
 
459
                if (hdp == au_h_dptr(parent, bindex)) {
 
460
                        dput(hdp);
 
461
                        continue;
 
462
                }
 
463
 
 
464
                new_bindex = au_find_dbindex(parent, hdp);
 
465
                dput(hdp);
 
466
                AuDebugOn(new_bindex == bindex);
 
467
                if (dinfo->di_bwh == bindex)
 
468
                        bwh = new_bindex;
 
469
                if (dinfo->di_bdiropq == bindex)
 
470
                        bdiropq = new_bindex;
 
471
                if (new_bindex < 0) { // test here
 
472
                        au_hdput(p, /*do_free*/0);
 
473
                        p->hd_dentry = NULL;
 
474
                        continue;
 
475
                }
 
476
                /* swap two hidden dentries, and loop again */
 
477
                q = dinfo->di_hdentry + new_bindex;
 
478
                tmp = *q;
 
479
                *q = *p;
 
480
                *p = tmp;
 
481
                if (tmp.hd_dentry) {
 
482
                        bindex--;
 
483
                        p--;
 
484
                }
 
485
        }
 
486
 
 
487
        // test here
 
488
        dinfo->di_bwh = -1;
 
489
        if (unlikely(bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh)))
 
490
                dinfo->di_bwh = bwh;
 
491
        dinfo->di_bdiropq = -1;
 
492
        if (unlikely(bdiropq >= 0 && bdiropq <= au_sbend(sb)
 
493
                     && au_sbr_whable(sb, bdiropq)))
 
494
                dinfo->di_bdiropq = bdiropq;
 
495
        parent_bend = au_dbend(parent);
 
496
        p = dinfo->di_hdentry;
 
497
        for (bindex = 0; bindex <= parent_bend; bindex++, p++)
 
498
                if (p->hd_dentry) {
 
499
                        dinfo->di_bstart = bindex;
 
500
                        break;
 
501
                }
 
502
        p = dinfo->di_hdentry + parent_bend;
 
503
        //for (bindex = parent_bend; bindex > dinfo->di_bstart; bindex--, p--)
 
504
        for (bindex = parent_bend; bindex >= 0; bindex--, p--)
 
505
                if (p->hd_dentry) {
 
506
                        dinfo->di_bend = bindex;
 
507
                        break;
 
508
                }
 
509
 
 
510
        npositive = 0;
 
511
        parent_bstart = au_dbstart(parent);
 
512
        if (type != S_IFDIR && dinfo->di_bstart == parent_bstart)
 
513
                goto out_dgen; /* success */
 
514
 
 
515
        npositive = au_lkup_dentry(dentry, parent_bstart, type, /*nd*/NULL);
 
516
        //if (LktrCond) npositive = -1;
 
517
        if (npositive < 0)
 
518
                goto out;
 
519
        if (unlikely(dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart))
 
520
                d_drop(dentry);
 
521
 
 
522
 out_dgen:
 
523
        au_update_digen(dentry);
 
524
 out:
 
525
        dput(parent);
 
526
        AuTraceErr(npositive);
 
527
        return npositive;
 
528
}
 
529
 
 
530
#ifdef CONFIG_AUFS_FAKE_DM
 
531
 
 
532
static int au_lock_nd(struct dentry *dentry, struct nameidata *nd)
 
533
{
 
534
        return 0;
 
535
}
 
536
 
 
537
static void au_unlock_nd(int locked, struct nameidata *nd)
 
538
{
 
539
        /* empty */
 
540
}
 
541
 
 
542
#else
 
543
 
 
544
static int au_lock_nd(struct dentry *dentry, struct nameidata *nd)
 
545
{
 
546
        int locked = 0;
 
547
        if (nd && dentry != nd->path.dentry) {
 
548
                di_read_lock_parent(nd->path.dentry, 0);
 
549
                locked = 1;
 
550
        }
 
551
        return locked;
 
552
}
 
553
 
 
554
static void au_unlock_nd(int locked, struct nameidata *nd)
 
555
{
 
556
        if (locked)
 
557
                di_read_unlock(nd->path.dentry, 0);
 
558
}
 
559
 
 
560
#endif /* CONFIG_AUFS_FAKE_DM */
 
561
 
 
562
//#define TestingFuse
 
563
static noinline_for_stack int
 
564
au_do_h_d_reval(struct dentry *dentry, aufs_bindex_t bindex,
 
565
                struct nameidata *nd, struct dentry *h_dentry)
 
566
{
 
567
        int err, valid, e;
 
568
        int (*reval)(struct dentry *, struct nameidata *);
 
569
        struct super_block *sb;
 
570
        struct nameidata fake_nd, *p;
 
571
 
 
572
        LKTRTrace("%.*s, b%d, nd %d\n", AuDLNPair(dentry), bindex, !!nd);
 
573
 
 
574
        err = 0;
 
575
        reval = NULL;
 
576
        if (h_dentry->d_op)
 
577
                reval = h_dentry->d_op->d_revalidate;
 
578
        if (!reval)
 
579
                goto out;
 
580
 
 
581
        sb = dentry->d_sb;
 
582
        if (nd) {
 
583
                memcpy(&fake_nd, nd, sizeof(*nd));
 
584
                err = au_fake_intent(&fake_nd, au_sbr_perm(sb, bindex));
 
585
                if (unlikely(err)) {
 
586
                        err = -EINVAL;
 
587
                        goto out;
 
588
                }
 
589
        }
 
590
        p = au_fake_dm(&fake_nd, nd, sb, bindex);
 
591
        AuDebugOn(IS_ERR(p));
 
592
        AuDebugOn(nd && p != &fake_nd);
 
593
        LKTRTrace("b%d\n", bindex);
 
594
 
 
595
        /* it may return tri-state */
 
596
        valid = reval(h_dentry, p);
 
597
        if (unlikely(valid < 0))
 
598
                err = valid;
 
599
        else if (!valid)
 
600
                err = -EINVAL;
 
601
        else
 
602
                AuDebugOn(err);
 
603
 
 
604
        if (p) {
 
605
                AuDebugOn(!nd);
 
606
                e = au_hin_after_reval(p, dentry, bindex, nd->intent.open.file);
 
607
#ifndef TestingFuse
 
608
                au_update_fuse_h_inode(p->path.mnt, h_dentry); /*ignore*/
 
609
#endif
 
610
                if (unlikely(e && !err))
 
611
                        err = e;
 
612
        }
 
613
#ifndef TestingFuse
 
614
        else
 
615
                au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/
 
616
#endif
 
617
        au_fake_dm_release(p);
 
618
 
 
619
 out:
 
620
        AuTraceErr(err);
 
621
        return err;
 
622
}
 
623
 
 
624
static noinline_for_stack int
 
625
h_d_revalidate(struct dentry *dentry, struct inode *inode,
 
626
               struct nameidata *nd, int do_udba)
 
627
{
 
628
        int err, plus, locked, unhashed, is_root, h_plus;
 
629
        aufs_bindex_t bindex, btail, bstart, ibs, ibe;
 
630
        struct super_block *sb;
 
631
        struct inode *first, *h_inode, *h_cached_inode;
 
632
        umode_t mode, h_mode;
 
633
        struct dentry *h_dentry;
 
634
        struct qstr *name;
 
635
 
 
636
        LKTRTrace("%.*s, nd %d\n", AuDLNPair(dentry), !!nd);
 
637
        AuDebugOn(inode && au_digen(dentry) != au_iigen(inode));
 
638
 
 
639
        err = 0;
 
640
        sb = dentry->d_sb;
 
641
        plus = 0;
 
642
        mode = 0;
 
643
        first = NULL;
 
644
        ibs = -1;
 
645
        ibe = -1;
 
646
        unhashed = d_unhashed(dentry);
 
647
        is_root = IS_ROOT(dentry);
 
648
        name = &dentry->d_name;
 
649
 
 
650
        /*
 
651
         * Theoretically, REVAL test should be unnecessary in case of INOTIFY.
 
652
         * But inotify doesn't fire some necessary events,
 
653
         *      IN_ATTRIB for atime/nlink/pageio
 
654
         *      IN_DELETE for NFS dentry
 
655
         * Let's do REVAL test too.
 
656
         */
 
657
        if (do_udba && inode) {
 
658
                mode = (inode->i_mode & S_IFMT);
 
659
                plus = (inode->i_nlink > 0);
 
660
                first = au_h_iptr(inode, au_ibstart(inode));
 
661
                ibs = au_ibstart(inode);
 
662
                ibe = au_ibend(inode);
 
663
        }
 
664
 
 
665
        bstart = au_dbstart(dentry);
 
666
        btail = bstart;
 
667
        if (inode && S_ISDIR(inode->i_mode))
 
668
                btail = au_dbtaildir(dentry);
 
669
        locked = au_lock_nd(dentry, nd);
 
670
        for (bindex = bstart; bindex <= btail; bindex++) {
 
671
                h_dentry = au_h_dptr(dentry, bindex);
 
672
                if (!h_dentry)
 
673
                        continue;
 
674
 
 
675
                LKTRTrace("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
 
676
#ifdef TestingFuse
 
677
                /* force re-lookup for fuse, in order to update attributes */
 
678
                if (unlikely(au_test_fuse(h_dentry->d_sb)))
 
679
                        goto err;
 
680
#endif
 
681
 
 
682
                if (unlikely(do_udba
 
683
                             && !is_root
 
684
                             && (unhashed != d_unhashed(h_dentry)
 
685
//#if 1
 
686
                                 || name->len != h_dentry->d_name.len
 
687
                                 || memcmp(name->name, h_dentry->d_name.name,
 
688
                                           name->len)
 
689
//#endif
 
690
                                     ))) {
 
691
                        LKTRTrace("unhash 0x%x 0x%x, %.*s %.*s\n",
 
692
                                  unhashed, d_unhashed(h_dentry),
 
693
                                  AuDLNPair(dentry), AuDLNPair(h_dentry));
 
694
                        goto err;
 
695
                }
 
696
 
 
697
                err = au_do_h_d_reval(dentry, bindex, nd, h_dentry);
 
698
                if (unlikely(err))
 
699
                        /* do not goto err, to keep the errno */
 
700
                        break;
 
701
 
 
702
                if (unlikely(!do_udba))
 
703
                        continue;
 
704
 
 
705
                /* UDBA tests */
 
706
                h_inode = h_dentry->d_inode;
 
707
                if (unlikely(!!inode != !!h_inode)) {
 
708
                        //AuDbg("here\n");
 
709
                        goto err;
 
710
                }
 
711
 
 
712
                h_plus = plus;
 
713
                h_mode = mode;
 
714
                h_cached_inode = h_inode;
 
715
                if (h_inode) {
 
716
                        h_mode = (h_inode->i_mode & S_IFMT);
 
717
                        h_plus = (h_inode->i_nlink > 0);
 
718
                        //AuDbgInode(inode);
 
719
                        //AuDbgInode(h_inode);
 
720
                }
 
721
                if (inode && ibs <= bindex && bindex <= ibe)
 
722
                        h_cached_inode = au_h_iptr(inode, bindex);
 
723
 
 
724
                LKTRTrace("{%d, 0%o, %d}, h{%d, 0%o, %d}\n",
 
725
                          plus, mode, !!h_cached_inode,
 
726
                          h_plus, h_mode, !!h_inode);
 
727
                if (unlikely(plus != h_plus
 
728
                             || mode != h_mode
 
729
                             || h_cached_inode != h_inode))
 
730
                        goto err;
 
731
                continue;
 
732
 
 
733
        err:
 
734
                err = -EINVAL;
 
735
                break;
 
736
        }
 
737
        au_unlock_nd(locked, nd);
 
738
 
 
739
        /*
 
740
         * judging by timestamps is meaningless since some filesystem uses
 
741
         * CURRENT_TIME_SEC instead of CURRENT_TIME.
 
742
         */
 
743
        /*
 
744
         * NFS may stop IN_DELETE because of DCACHE_NFSFS_RENAMED.
 
745
         */
 
746
 
 
747
#if 0 // debug
 
748
        if (!err)
 
749
                au_update_from_fuse(inode);
 
750
        if (unlikely(!err && udba && first))
 
751
                au_cpup_attr_all(inode);
 
752
#endif
 
753
 
 
754
        AuTraceErr(err);
 
755
        return err;
 
756
}
 
757
 
 
758
static noinline_for_stack int
 
759
simple_reval_dpath(struct dentry *dentry, au_gen_t sgen)
 
760
{
 
761
        int err;
 
762
        mode_t type;
 
763
        struct dentry *parent;
 
764
        struct inode *inode;
 
765
 
 
766
        LKTRTrace("%.*s, sgen %d\n", AuDLNPair(dentry), sgen);
 
767
        SiMustAnyLock(dentry->d_sb);
 
768
        DiMustWriteLock(dentry);
 
769
        inode = dentry->d_inode;
 
770
        AuDebugOn(!inode);
 
771
 
 
772
        if (au_digen(dentry) == sgen && au_iigen(inode) == sgen)
 
773
                return 0;
 
774
 
 
775
        parent = dget_parent(dentry);
 
776
        di_read_lock_parent(parent, AuLock_IR);
 
777
        AuDebugOn(au_digen(parent) != sgen
 
778
                  || au_iigen(parent->d_inode) != sgen);
 
779
#ifdef CONFIG_AUFS_DEBUG
 
780
        {
 
781
                int i, j;
 
782
                struct au_dcsub_pages dpages;
 
783
                struct au_dpage *dpage;
 
784
                struct dentry **dentries;
 
785
 
 
786
                err = au_dpages_init(&dpages, GFP_TEMPORARY);
 
787
                AuDebugOn(err);
 
788
                err = au_dcsub_pages_rev(&dpages, parent, /*do_include*/1, NULL,
 
789
                                         NULL);
 
790
                AuDebugOn(err);
 
791
                for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
 
792
                        dpage = dpages.dpages + i;
 
793
                        dentries = dpage->dentries;
 
794
                        for (j = dpage->ndentry - 1; !err && j >= 0; j--)
 
795
                                AuDebugOn(au_digen(dentries[j]) != sgen);
 
796
                }
 
797
                au_dpages_free(&dpages);
 
798
        }
 
799
#endif
 
800
        type = (inode->i_mode & S_IFMT);
 
801
        /* returns a number of positive dentries */
 
802
        err = au_refresh_hdentry(dentry, type);
 
803
        if (err >= 0)
 
804
                err = au_refresh_hinode(inode, dentry);
 
805
        di_read_unlock(parent, AuLock_IR);
 
806
        dput(parent);
 
807
        AuTraceErr(err);
 
808
        return err;
 
809
}
 
810
 
 
811
int au_reval_dpath(struct dentry *dentry, au_gen_t sgen)
 
812
{
 
813
        int err;
 
814
        struct dentry *d, *parent;
 
815
        struct inode *inode;
 
816
 
 
817
        LKTRTrace("%.*s, sgen %d\n", AuDLNPair(dentry), sgen);
 
818
        AuDebugOn(!dentry->d_inode);
 
819
        DiMustWriteLock(dentry);
 
820
 
 
821
        if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS))
 
822
                return simple_reval_dpath(dentry, sgen);
 
823
 
 
824
        /* slow loop, keep it simple and stupid */
 
825
        /* cf: au_cpup_dirs() */
 
826
        err = 0;
 
827
        parent = NULL;
 
828
        while (au_digen(dentry) != sgen || au_iigen(dentry->d_inode) != sgen) {
 
829
                d = dentry;
 
830
                while (1) {
 
831
                        dput(parent);
 
832
                        parent = dget_parent(d);
 
833
                        if (au_digen(parent) == sgen
 
834
                            && au_iigen(parent->d_inode) == sgen)
 
835
                                break;
 
836
                        d = parent;
 
837
                }
 
838
 
 
839
                inode = d->d_inode;
 
840
                if (d != dentry) {
 
841
                        //mutex_lock(&inode->i_mutex);
 
842
                        di_write_lock_child(d);
 
843
                }
 
844
 
 
845
                /* someone might update our dentry while we were sleeping */
 
846
                if (au_digen(d) != sgen || au_iigen(d->d_inode) != sgen) {
 
847
                        di_read_lock_parent(parent, AuLock_IR);
 
848
                        /* returns a number of positive dentries */
 
849
                        err = au_refresh_hdentry(d, inode->i_mode & S_IFMT);
 
850
                        //err = -1;
 
851
                        if (err >= 0)
 
852
                                err = au_refresh_hinode(inode, d);
 
853
                        //err = -1;
 
854
                        di_read_unlock(parent, AuLock_IR);
 
855
                }
 
856
 
 
857
                if (d != dentry) {
 
858
                        di_write_unlock(d);
 
859
                        //mutex_unlock(&inode->i_mutex);
 
860
                }
 
861
                dput(parent);
 
862
                if (unlikely(err))
 
863
                        break;
 
864
        }
 
865
 
 
866
        AuTraceErr(err);
 
867
        return err;
 
868
}
 
869
 
 
870
/*
 
871
 * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise.
 
872
 * nfsd passes NULL as nameidata.
 
873
 */
 
874
static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
 
875
{
 
876
        int valid, err, do_udba;
 
877
        struct super_block *sb;
 
878
        au_gen_t sgen;
 
879
        struct inode *inode;
 
880
        struct nameidata tmp_nd, *ndp;
 
881
 
 
882
        LKTRTrace("dentry %.*s\n", AuDLNPair(dentry));
 
883
        if (nd && nd->path.dentry)
 
884
                LKTRTrace("nd{%.*s, 0x%x}\n",
 
885
                          AuDLNPair(nd->path.dentry), nd->flags);
 
886
        //dir case: AuDebugOn(dentry->d_parent != nd->dentry);
 
887
        //remove failure case:AuDebugOn(!IS_ROOT(dentry) && d_unhashed(dentry));
 
888
        AuDebugOn(!dentry->d_fsdata);
 
889
        //AuDbgDentry(dentry);
 
890
 
 
891
        err = -EINVAL;
 
892
        inode = dentry->d_inode;
 
893
        sb = dentry->d_sb;
 
894
        si_read_lock(sb, AuLock_FLUSH);
 
895
 
 
896
        sgen = au_sigen(sb);
 
897
        if (au_digen(dentry) == sgen)
 
898
                di_read_lock_child(dentry, !AuLock_IR);
 
899
        else {
 
900
                AuDebugOn(IS_ROOT(dentry));
 
901
#ifdef ForceInotify
 
902
                AuDbg("UDBA or digen, %.*s\n", AuDLNPair(dentry));
 
903
#endif
 
904
                di_write_lock_child(dentry);
 
905
                if (inode)
 
906
                        err = au_reval_dpath(dentry, sgen);
 
907
                //err = -1;
 
908
                di_downgrade_lock(dentry, AuLock_IR);
 
909
                if (unlikely(err))
 
910
                        goto out;
 
911
                if (inode)
 
912
                        ii_read_unlock(inode);
 
913
                AuDebugOn(au_digen(dentry) != sgen);
 
914
        }
 
915
 
 
916
        if (inode) {
 
917
                if (au_iigen(inode) == sgen)
 
918
                        ii_read_lock_child(inode);
 
919
                else {
 
920
                        AuDebugOn(IS_ROOT(dentry));
 
921
#ifdef ForceInotify
 
922
                        AuDbg("UDBA or survived, %.*s\n", AuDLNPair(dentry));
 
923
                        //au_debug_on();
 
924
                        //AuDbgInode(inode);
 
925
                        //au_debug_off();
 
926
#endif
 
927
                        ii_write_lock_child(inode);
 
928
                        err = au_refresh_hinode(inode, dentry);
 
929
                        ii_downgrade_lock(inode);
 
930
                        if (unlikely(err))
 
931
                                goto out;
 
932
                        AuDebugOn(au_iigen(inode) != sgen);
 
933
                }
 
934
        }
 
935
 
 
936
#if 0 // fix it
 
937
        /* parent dir i_nlink is not updated in the case of setattr */
 
938
        if (S_ISDIR(inode->i_mode)) {
 
939
                mutex_lock(&inode->i_mutex);
 
940
                ii_write_lock(inode);
 
941
                au_cpup_attr_nlink(inode);
 
942
                ii_write_unlock(inode);
 
943
                mutex_unlock(&inode->i_mutex);
 
944
        }
 
945
#endif
 
946
 
 
947
        AuDebugOn(au_digen(dentry) != sgen);
 
948
        AuDebugOn(inode && au_iigen(inode) != sgen);
 
949
        err = -EINVAL;
 
950
        do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
 
951
        if (do_udba && inode) {
 
952
                aufs_bindex_t bstart = au_ibstart(inode);
 
953
                if (bstart >= 0
 
954
                    && au_test_higen(inode, au_h_iptr(inode, bstart)))
 
955
                        goto out;
 
956
        }
 
957
        ndp = au_dup_nd(au_sbi(sb), &tmp_nd, nd);
 
958
        err = h_d_revalidate(dentry, inode, ndp, do_udba);
 
959
        //err = -1;
 
960
 
 
961
 out:
 
962
#if 0
 
963
        AuDbgDentry(dentry);
 
964
        if (nd && (nd->flags & LOOKUP_OPEN)) {
 
965
                LKTRTrace("intent.open.file %p\n", nd->intent.open.file);
 
966
                if (nd->intent.open.file && nd->intent.open.file->f_dentry)
 
967
                        AuDbgFile(nd->intent.open.file);
 
968
        }
 
969
#endif
 
970
        au_store_fmode_exec(nd, inode);
 
971
 
 
972
        if (inode)
 
973
                ii_read_unlock(inode);
 
974
        di_read_unlock(dentry, !AuLock_IR);
 
975
        si_read_unlock(sb);
 
976
        AuTraceErr(err);
 
977
        valid = !err;
 
978
        if (!valid)
 
979
                LKTRTrace("%.*s invalid\n", AuDLNPair(dentry));
 
980
        return valid;
 
981
}
 
982
 
 
983
static void aufs_d_release(struct dentry *dentry)
 
984
{
 
985
        struct au_dinfo *dinfo;
 
986
        aufs_bindex_t bend, bindex;
 
987
 
 
988
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
 
989
        AuDebugOn(!d_unhashed(dentry));
 
990
 
 
991
        dinfo = dentry->d_fsdata;
 
992
        if (unlikely(!dinfo))
 
993
                return;
 
994
 
 
995
        /* dentry may not be revalidated */
 
996
        bindex = dinfo->di_bstart;
 
997
        if (bindex >= 0) {
 
998
                struct au_hdentry *p;
 
999
                bend = dinfo->di_bend;
 
1000
                AuDebugOn(bend < bindex);
 
1001
                p = dinfo->di_hdentry + bindex;
 
1002
                while (bindex++ <= bend) {
 
1003
                        if (p->hd_dentry)
 
1004
                                au_hdput(p, /*do_free*/1);
 
1005
                        p++;
 
1006
                }
 
1007
        }
 
1008
        kfree(dinfo->di_hdentry);
 
1009
        au_cache_free_dinfo(dinfo);
 
1010
}
 
1011
 
 
1012
struct dentry_operations aufs_dop = {
 
1013
        .d_revalidate   = aufs_d_revalidate,
 
1014
        .d_release      = aufs_d_release,
 
1015
        /* never use d_delete, especially in case of nfs server */
 
1016
        //.d_delete     = aufs_d_delete
 
1017
        //.d_iput               = aufs_d_iput
 
1018
};