~ubuntu-branches/ubuntu/karmic/linux-mvl-dove/karmic-proposed

« back to all changes in this revision

Viewing changes to ubuntu/aufs/dentry.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader
  • Date: 2010-03-10 22:24:12 UTC
  • mto: (15.1.2 karmic-security)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20100310222412-k86m3r53jw0je7x1
Tags: upstream-2.6.31
ImportĀ upstreamĀ versionĀ 2.6.31

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2005-2009 Junjiro R. 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
 
 
23
 
#include <linux/namei.h>
24
 
#include "aufs.h"
25
 
 
26
 
static void au_h_nd(struct nameidata *h_nd, struct nameidata *nd)
27
 
{
28
 
        if (nd) {
29
 
                *h_nd = *nd;
30
 
 
31
 
                /*
32
 
                 * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
33
 
                 * due to whiteout and branch permission.
34
 
                 */
35
 
                h_nd->flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
36
 
                                 | LOOKUP_FOLLOW);
37
 
                /* unnecessary? */
38
 
                h_nd->intent.open.file = NULL;
39
 
        } else
40
 
                memset(h_nd, 0, sizeof(*h_nd));
41
 
}
42
 
 
43
 
struct au_lkup_one_args {
44
 
        struct dentry **errp;
45
 
        struct qstr *name;
46
 
        struct dentry *h_parent;
47
 
        struct au_branch *br;
48
 
        struct nameidata *nd;
49
 
};
50
 
 
51
 
struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
52
 
                           struct au_branch *br, struct nameidata *nd)
53
 
{
54
 
        struct dentry *h_dentry;
55
 
        int err;
56
 
        struct nameidata h_nd;
57
 
 
58
 
        if (au_test_fs_null_nd(h_parent->d_sb))
59
 
                return vfsub_lookup_one_len(name->name, h_parent, name->len);
60
 
 
61
 
        au_h_nd(&h_nd, nd);
62
 
        h_nd.path.dentry = h_parent;
63
 
        h_nd.path.mnt = br->br_mnt;
64
 
 
65
 
        err = __lookup_one_len(name->name, &h_nd.last, NULL, name->len);
66
 
        h_dentry = ERR_PTR(err);
67
 
        if (!err) {
68
 
                path_get(&h_nd.path);
69
 
                h_dentry = vfsub_lookup_hash(&h_nd);
70
 
                path_put(&h_nd.path);
71
 
        }
72
 
 
73
 
        return h_dentry;
74
 
}
75
 
 
76
 
static void au_call_lkup_one(void *args)
77
 
{
78
 
        struct au_lkup_one_args *a = args;
79
 
        *a->errp = au_lkup_one(a->name, a->h_parent, a->br, a->nd);
80
 
}
81
 
 
82
 
#define AuLkup_ALLOW_NEG        1
83
 
#define au_ftest_lkup(flags, name)      ((flags) & AuLkup_##name)
84
 
#define au_fset_lkup(flags, name)       { (flags) |= AuLkup_##name; }
85
 
#define au_fclr_lkup(flags, name)       { (flags) &= ~AuLkup_##name; }
86
 
 
87
 
struct au_do_lookup_args {
88
 
        unsigned int            flags;
89
 
        mode_t                  type;
90
 
        struct nameidata        *nd;
91
 
};
92
 
 
93
 
/*
94
 
 * returns positive/negative dentry, NULL or an error.
95
 
 * NULL means whiteout-ed or not-found.
96
 
 */
97
 
static struct dentry*
98
 
au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
99
 
             aufs_bindex_t bindex, struct qstr *wh_name,
100
 
             struct au_do_lookup_args *args)
101
 
{
102
 
        struct dentry *h_dentry;
103
 
        struct inode *h_inode, *inode;
104
 
        struct qstr *name;
105
 
        struct au_branch *br;
106
 
        int wh_found, opq;
107
 
        unsigned char wh_able;
108
 
        const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
109
 
 
110
 
        name = &dentry->d_name;
111
 
        wh_found = 0;
112
 
        br = au_sbr(dentry->d_sb, bindex);
113
 
        wh_able = !!au_br_whable(br->br_perm);
114
 
        if (wh_able)
115
 
                wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
116
 
        h_dentry = ERR_PTR(wh_found);
117
 
        if (!wh_found)
118
 
                goto real_lookup;
119
 
        if (unlikely(wh_found < 0))
120
 
                goto out;
121
 
 
122
 
        /* We found a whiteout */
123
 
        /* au_set_dbend(dentry, bindex); */
124
 
        au_set_dbwh(dentry, bindex);
125
 
        if (!allow_neg)
126
 
                return NULL; /* success */
127
 
 
128
 
 real_lookup:
129
 
        h_dentry = au_lkup_one(name, h_parent, br, args->nd);
130
 
        if (IS_ERR(h_dentry))
131
 
                goto out;
132
 
 
133
 
        h_inode = h_dentry->d_inode;
134
 
        if (!h_inode) {
135
 
                if (!allow_neg)
136
 
                        goto out_neg;
137
 
        } else if (wh_found
138
 
                   || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
139
 
                goto out_neg;
140
 
 
141
 
        if (au_dbend(dentry) <= bindex)
142
 
                au_set_dbend(dentry, bindex);
143
 
        if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
144
 
                au_set_dbstart(dentry, bindex);
145
 
        au_set_h_dptr(dentry, bindex, h_dentry);
146
 
 
147
 
        inode = dentry->d_inode;
148
 
        if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
149
 
            || (inode && !S_ISDIR(inode->i_mode)))
150
 
                goto out; /* success */
151
 
 
152
 
        mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
153
 
        opq = au_diropq_test(h_dentry, br);
154
 
        mutex_unlock(&h_inode->i_mutex);
155
 
        if (opq > 0)
156
 
                au_set_dbdiropq(dentry, bindex);
157
 
        else if (unlikely(opq < 0)) {
158
 
                au_set_h_dptr(dentry, bindex, NULL);
159
 
                h_dentry = ERR_PTR(opq);
160
 
        }
161
 
        goto out;
162
 
 
163
 
 out_neg:
164
 
        dput(h_dentry);
165
 
        h_dentry = NULL;
166
 
 out:
167
 
        return h_dentry;
168
 
}
169
 
 
170
 
static int au_test_shwh(struct super_block *sb, const struct qstr *name)
171
 
{
172
 
        if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
173
 
                     && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
174
 
                return -EPERM;
175
 
        return 0;
176
 
}
177
 
 
178
 
/*
179
 
 * returns the number of lower positive dentries,
180
 
 * otherwise an error.
181
 
 * can be called at unlinking with @type is zero.
182
 
 */
183
 
int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
184
 
                   struct nameidata *nd)
185
 
{
186
 
        int npositive, err;
187
 
        aufs_bindex_t bindex, btail, bdiropq;
188
 
        unsigned char isdir;
189
 
        struct qstr whname;
190
 
        struct au_do_lookup_args args = {
191
 
                .flags  = 0,
192
 
                .type   = type,
193
 
                .nd     = nd
194
 
        };
195
 
        const struct qstr *name = &dentry->d_name;
196
 
        struct dentry *parent;
197
 
        struct inode *inode;
198
 
 
199
 
        parent = dget_parent(dentry);
200
 
        err = au_test_shwh(dentry->d_sb, name);
201
 
        if (unlikely(err))
202
 
                goto out;
203
 
 
204
 
        err = au_wh_name_alloc(&whname, name);
205
 
        if (unlikely(err))
206
 
                goto out;
207
 
 
208
 
        inode = dentry->d_inode;
209
 
        isdir = !!(inode && S_ISDIR(inode->i_mode));
210
 
        if (!type)
211
 
                au_fset_lkup(args.flags, ALLOW_NEG);
212
 
 
213
 
        npositive = 0;
214
 
        btail = au_dbtaildir(parent);
215
 
        for (bindex = bstart; bindex <= btail; bindex++) {
216
 
                struct dentry *h_parent, *h_dentry;
217
 
                struct inode *h_inode, *h_dir;
218
 
 
219
 
                h_dentry = au_h_dptr(dentry, bindex);
220
 
                if (h_dentry) {
221
 
                        if (h_dentry->d_inode)
222
 
                                npositive++;
223
 
                        if (type != S_IFDIR)
224
 
                                break;
225
 
                        continue;
226
 
                }
227
 
                h_parent = au_h_dptr(parent, bindex);
228
 
                if (!h_parent)
229
 
                        continue;
230
 
                h_dir = h_parent->d_inode;
231
 
                if (!h_dir || !S_ISDIR(h_dir->i_mode))
232
 
                        continue;
233
 
 
234
 
                mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
235
 
                h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
236
 
                                        &args);
237
 
                mutex_unlock(&h_dir->i_mutex);
238
 
                err = PTR_ERR(h_dentry);
239
 
                if (IS_ERR(h_dentry))
240
 
                        goto out_wh;
241
 
                au_fclr_lkup(args.flags, ALLOW_NEG);
242
 
 
243
 
                if (au_dbwh(dentry) >= 0)
244
 
                        break;
245
 
                if (!h_dentry)
246
 
                        continue;
247
 
                h_inode = h_dentry->d_inode;
248
 
                if (!h_inode)
249
 
                        continue;
250
 
                npositive++;
251
 
                if (!args.type)
252
 
                        args.type = h_inode->i_mode & S_IFMT;
253
 
                if (args.type != S_IFDIR)
254
 
                        break;
255
 
                else if (isdir) {
256
 
                        /* the type of lower may be different */
257
 
                        bdiropq = au_dbdiropq(dentry);
258
 
                        if (bdiropq >= 0 && bdiropq <= bindex)
259
 
                                break;
260
 
                }
261
 
        }
262
 
 
263
 
        if (npositive) {
264
 
                AuLabel(positive);
265
 
                au_update_dbstart(dentry);
266
 
        }
267
 
        err = npositive;
268
 
        if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
269
 
                     && au_dbstart(dentry) < 0))
270
 
                /* both of real entry and whiteout found */
271
 
                err = -EIO;
272
 
 
273
 
 out_wh:
274
 
        kfree(whname.name);
275
 
 out:
276
 
        dput(parent);
277
 
        return err;
278
 
}
279
 
 
280
 
struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
281
 
                               struct au_branch *br)
282
 
{
283
 
        struct dentry *dentry;
284
 
        int wkq_err;
285
 
 
286
 
        if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
287
 
                dentry = au_lkup_one(name, parent, br, /*nd*/NULL);
288
 
        else {
289
 
                struct au_lkup_one_args args = {
290
 
                        .errp           = &dentry,
291
 
                        .name           = name,
292
 
                        .h_parent       = parent,
293
 
                        .br             = br,
294
 
                        .nd             = NULL
295
 
                };
296
 
 
297
 
                wkq_err = au_wkq_wait(au_call_lkup_one, &args);
298
 
                if (unlikely(wkq_err))
299
 
                        dentry = ERR_PTR(wkq_err);
300
 
        }
301
 
 
302
 
        return dentry;
303
 
}
304
 
 
305
 
/*
306
 
 * lookup @dentry on @bindex which should be negative.
307
 
 */
308
 
int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex)
309
 
{
310
 
        int err;
311
 
        struct dentry *parent, *h_parent, *h_dentry;
312
 
        struct qstr *name;
313
 
 
314
 
        name = &dentry->d_name;
315
 
        parent = dget_parent(dentry);
316
 
        h_parent = au_h_dptr(parent, bindex);
317
 
        h_dentry = au_sio_lkup_one(name, h_parent,
318
 
                                   au_sbr(dentry->d_sb, bindex));
319
 
        err = PTR_ERR(h_dentry);
320
 
        if (IS_ERR(h_dentry))
321
 
                goto out;
322
 
        if (unlikely(h_dentry->d_inode)) {
323
 
                err = -EIO;
324
 
                AuIOErr("b%d %.*s should be negative.\n",
325
 
                        bindex, AuDLNPair(h_dentry));
326
 
                dput(h_dentry);
327
 
                goto out;
328
 
        }
329
 
 
330
 
        if (bindex < au_dbstart(dentry))
331
 
                au_set_dbstart(dentry, bindex);
332
 
        if (au_dbend(dentry) < bindex)
333
 
                au_set_dbend(dentry, bindex);
334
 
        au_set_h_dptr(dentry, bindex, h_dentry);
335
 
        err = 0;
336
 
 
337
 
 out:
338
 
        dput(parent);
339
 
        return err;
340
 
}
341
 
 
342
 
/* ---------------------------------------------------------------------- */
343
 
 
344
 
/* subset of struct inode */
345
 
struct au_iattr {
346
 
        unsigned long           i_ino;
347
 
        /* unsigned int         i_nlink; */
348
 
        uid_t                   i_uid;
349
 
        gid_t                   i_gid;
350
 
        u64                     i_version;
351
 
/*
352
 
        loff_t                  i_size;
353
 
        blkcnt_t                i_blocks;
354
 
*/
355
 
        umode_t                 i_mode;
356
 
};
357
 
 
358
 
static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
359
 
{
360
 
        ia->i_ino = h_inode->i_ino;
361
 
        /* ia->i_nlink = h_inode->i_nlink; */
362
 
        ia->i_uid = h_inode->i_uid;
363
 
        ia->i_gid = h_inode->i_gid;
364
 
        ia->i_version = h_inode->i_version;
365
 
/*
366
 
        ia->i_size = h_inode->i_size;
367
 
        ia->i_blocks = h_inode->i_blocks;
368
 
*/
369
 
        ia->i_mode = (h_inode->i_mode & S_IFMT);
370
 
}
371
 
 
372
 
static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
373
 
{
374
 
        return ia->i_ino != h_inode->i_ino
375
 
                /* || ia->i_nlink != h_inode->i_nlink */
376
 
                || ia->i_uid != h_inode->i_uid
377
 
                || ia->i_gid != h_inode->i_gid
378
 
                || ia->i_version != h_inode->i_version
379
 
/*
380
 
                || ia->i_size != h_inode->i_size
381
 
                || ia->i_blocks != h_inode->i_blocks
382
 
*/
383
 
                || ia->i_mode != (h_inode->i_mode & S_IFMT);
384
 
}
385
 
 
386
 
static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
387
 
                              struct au_branch *br)
388
 
{
389
 
        int err;
390
 
        struct au_iattr ia;
391
 
        struct inode *h_inode;
392
 
        struct dentry *h_d;
393
 
        struct super_block *h_sb;
394
 
 
395
 
        err = 0;
396
 
        memset(&ia, -1, sizeof(ia));
397
 
        h_sb = h_dentry->d_sb;
398
 
        h_inode = h_dentry->d_inode;
399
 
        if (h_inode)
400
 
                au_iattr_save(&ia, h_inode);
401
 
        else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
402
 
                /* nfs d_revalidate may return 0 for negative dentry */
403
 
                /* fuse d_revalidate always return 0 for negative dentry */
404
 
                goto out;
405
 
 
406
 
        /* main purpose is namei.c:cached_lookup() and d_revalidate */
407
 
        h_d = au_lkup_one(&h_dentry->d_name, h_parent, br, /*nd*/NULL);
408
 
        err = PTR_ERR(h_d);
409
 
        if (IS_ERR(h_d))
410
 
                goto out;
411
 
 
412
 
        err = 0;
413
 
        if (unlikely(h_d != h_dentry
414
 
                     || h_d->d_inode != h_inode
415
 
                     || (h_inode && au_iattr_test(&ia, h_inode))))
416
 
                err = au_busy_or_stale();
417
 
        dput(h_d);
418
 
 
419
 
 out:
420
 
        AuTraceErr(err);
421
 
        return err;
422
 
}
423
 
 
424
 
int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
425
 
                struct dentry *h_parent, struct au_branch *br)
426
 
{
427
 
        int err;
428
 
 
429
 
        err = 0;
430
 
        if (udba == AuOpt_UDBA_REVAL) {
431
 
                IMustLock(h_dir);
432
 
                err = (h_dentry->d_parent->d_inode != h_dir);
433
 
        } else if (udba == AuOpt_UDBA_HINOTIFY)
434
 
                err = au_h_verify_dentry(h_dentry, h_parent, br);
435
 
 
436
 
        return err;
437
 
}
438
 
 
439
 
/* ---------------------------------------------------------------------- */
440
 
 
441
 
static void au_do_refresh_hdentry(struct au_hdentry *p, struct au_dinfo *dinfo,
442
 
                                  struct dentry *parent)
443
 
{
444
 
        struct dentry *h_d, *h_dp;
445
 
        struct au_hdentry tmp, *q;
446
 
        struct super_block *sb;
447
 
        aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
448
 
 
449
 
        AuRwMustWriteLock(&dinfo->di_rwsem);
450
 
 
451
 
        bend = dinfo->di_bend;
452
 
        bwh = dinfo->di_bwh;
453
 
        bdiropq = dinfo->di_bdiropq;
454
 
        for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
455
 
                h_d = p->hd_dentry;
456
 
                if (!h_d)
457
 
                        continue;
458
 
 
459
 
                h_dp = dget_parent(h_d);
460
 
                if (h_dp == au_h_dptr(parent, bindex)) {
461
 
                        dput(h_dp);
462
 
                        continue;
463
 
                }
464
 
 
465
 
                new_bindex = au_find_dbindex(parent, h_dp);
466
 
                dput(h_dp);
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) {
472
 
                        au_hdput(p);
473
 
                        p->hd_dentry = NULL;
474
 
                        continue;
475
 
                }
476
 
 
477
 
                /* swap two lower dentries, and loop again */
478
 
                q = dinfo->di_hdentry + new_bindex;
479
 
                tmp = *q;
480
 
                *q = *p;
481
 
                *p = tmp;
482
 
                if (tmp.hd_dentry) {
483
 
                        bindex--;
484
 
                        p--;
485
 
                }
486
 
        }
487
 
 
488
 
        sb = parent->d_sb;
489
 
        dinfo->di_bwh = -1;
490
 
        if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
491
 
                dinfo->di_bwh = bwh;
492
 
 
493
 
        dinfo->di_bdiropq = -1;
494
 
        if (bdiropq >= 0
495
 
            && bdiropq <= au_sbend(sb)
496
 
            && au_sbr_whable(sb, bdiropq))
497
 
                dinfo->di_bdiropq = bdiropq;
498
 
 
499
 
        bend = au_dbend(parent);
500
 
        p = dinfo->di_hdentry;
501
 
        for (bindex = 0; bindex <= bend; bindex++, p++)
502
 
                if (p->hd_dentry) {
503
 
                        dinfo->di_bstart = bindex;
504
 
                        break;
505
 
                }
506
 
 
507
 
        p = dinfo->di_hdentry + bend;
508
 
        for (bindex = bend; bindex >= 0; bindex--, p--)
509
 
                if (p->hd_dentry) {
510
 
                        dinfo->di_bend = bindex;
511
 
                        break;
512
 
                }
513
 
}
514
 
 
515
 
/*
516
 
 * returns the number of found lower positive dentries,
517
 
 * otherwise an error.
518
 
 */
519
 
int au_refresh_hdentry(struct dentry *dentry, mode_t type)
520
 
{
521
 
        int npositive, err;
522
 
        unsigned int sigen;
523
 
        aufs_bindex_t bstart;
524
 
        struct au_dinfo *dinfo;
525
 
        struct super_block *sb;
526
 
        struct dentry *parent;
527
 
 
528
 
        DiMustWriteLock(dentry);
529
 
 
530
 
        sb = dentry->d_sb;
531
 
        AuDebugOn(IS_ROOT(dentry));
532
 
        sigen = au_sigen(sb);
533
 
        parent = dget_parent(dentry);
534
 
        AuDebugOn(au_digen(parent) != sigen
535
 
                  || au_iigen(parent->d_inode) != sigen);
536
 
 
537
 
        dinfo = au_di(dentry);
538
 
        err = au_di_realloc(dinfo, au_sbend(sb) + 1);
539
 
        npositive = err;
540
 
        if (unlikely(err))
541
 
                goto out;
542
 
        au_do_refresh_hdentry(dinfo->di_hdentry + dinfo->di_bstart, dinfo,
543
 
                              parent);
544
 
 
545
 
        npositive = 0;
546
 
        bstart = au_dbstart(parent);
547
 
        if (type != S_IFDIR && dinfo->di_bstart == bstart)
548
 
                goto out_dgen; /* success */
549
 
 
550
 
        npositive = au_lkup_dentry(dentry, bstart, type, /*nd*/NULL);
551
 
        if (npositive < 0)
552
 
                goto out;
553
 
        if (dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart)
554
 
                d_drop(dentry);
555
 
 
556
 
 out_dgen:
557
 
        au_update_digen(dentry);
558
 
 out:
559
 
        dput(parent);
560
 
        AuTraceErr(npositive);
561
 
        return npositive;
562
 
}
563
 
 
564
 
static noinline_for_stack
565
 
int au_do_h_d_reval(struct dentry *h_dentry, struct nameidata *nd,
566
 
                    struct dentry *dentry, aufs_bindex_t bindex)
567
 
{
568
 
        int err, valid;
569
 
        int (*reval)(struct dentry *, struct nameidata *);
570
 
 
571
 
        err = 0;
572
 
        reval = NULL;
573
 
        if (h_dentry->d_op)
574
 
                reval = h_dentry->d_op->d_revalidate;
575
 
        if (!reval)
576
 
                goto out;
577
 
 
578
 
        AuDbg("b%d\n", bindex);
579
 
        if (au_test_fs_null_nd(h_dentry->d_sb))
580
 
                /* it may return tri-state */
581
 
                valid = reval(h_dentry, NULL);
582
 
        else {
583
 
                struct nameidata h_nd;
584
 
                int locked;
585
 
                struct dentry *parent;
586
 
 
587
 
                au_h_nd(&h_nd, nd);
588
 
                parent = nd->path.dentry;
589
 
                locked = (nd && nd->path.dentry != dentry);
590
 
                if (locked)
591
 
                        di_read_lock_parent(parent, AuLock_IR);
592
 
                BUG_ON(bindex > au_dbend(parent));
593
 
                h_nd.path.dentry = au_h_dptr(parent, bindex);
594
 
                BUG_ON(!h_nd.path.dentry);
595
 
                h_nd.path.mnt = au_sbr(parent->d_sb, bindex)->br_mnt;
596
 
                path_get(&h_nd.path);
597
 
                valid = reval(h_dentry, &h_nd);
598
 
                path_put(&h_nd.path);
599
 
                if (locked)
600
 
                        di_read_unlock(parent, AuLock_IR);
601
 
        }
602
 
 
603
 
        if (unlikely(valid < 0))
604
 
                err = valid;
605
 
        else if (!valid)
606
 
                err = -EINVAL;
607
 
 
608
 
 out:
609
 
        AuTraceErr(err);
610
 
        return err;
611
 
}
612
 
 
613
 
/* todo: remove this */
614
 
static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
615
 
                          struct nameidata *nd, int do_udba)
616
 
{
617
 
        int err;
618
 
        umode_t mode, h_mode;
619
 
        aufs_bindex_t bindex, btail, bstart, ibs, ibe;
620
 
        unsigned char plus, unhashed, is_root, h_plus;
621
 
        struct inode *first, *h_inode, *h_cached_inode;
622
 
        struct dentry *h_dentry;
623
 
        struct qstr *name, *h_name;
624
 
 
625
 
        err = 0;
626
 
        plus = 0;
627
 
        mode = 0;
628
 
        first = NULL;
629
 
        ibs = -1;
630
 
        ibe = -1;
631
 
        unhashed = !!d_unhashed(dentry);
632
 
        is_root = !!IS_ROOT(dentry);
633
 
        name = &dentry->d_name;
634
 
 
635
 
        /*
636
 
         * Theoretically, REVAL test should be unnecessary in case of INOTIFY.
637
 
         * But inotify doesn't fire some necessary events,
638
 
         *      IN_ATTRIB for atime/nlink/pageio
639
 
         *      IN_DELETE for NFS dentry
640
 
         * Let's do REVAL test too.
641
 
         */
642
 
        if (do_udba && inode) {
643
 
                mode = (inode->i_mode & S_IFMT);
644
 
                plus = (inode->i_nlink > 0);
645
 
                first = au_h_iptr(inode, au_ibstart(inode));
646
 
                ibs = au_ibstart(inode);
647
 
                ibe = au_ibend(inode);
648
 
        }
649
 
 
650
 
        bstart = au_dbstart(dentry);
651
 
        btail = bstart;
652
 
        if (inode && S_ISDIR(inode->i_mode))
653
 
                btail = au_dbtaildir(dentry);
654
 
        for (bindex = bstart; bindex <= btail; bindex++) {
655
 
                h_dentry = au_h_dptr(dentry, bindex);
656
 
                if (!h_dentry)
657
 
                        continue;
658
 
 
659
 
                AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
660
 
                h_name = &h_dentry->d_name;
661
 
                if (unlikely(do_udba
662
 
                             && !is_root
663
 
                             && (unhashed != !!d_unhashed(h_dentry)
664
 
                                 || name->len != h_name->len
665
 
                                 || memcmp(name->name, h_name->name, name->len))
666
 
                            )) {
667
 
                        AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
668
 
                                  unhashed, d_unhashed(h_dentry),
669
 
                                  AuDLNPair(dentry), AuDLNPair(h_dentry));
670
 
                        goto err;
671
 
                }
672
 
 
673
 
                err = au_do_h_d_reval(h_dentry, nd, dentry, bindex);
674
 
                if (unlikely(err))
675
 
                        /* do not goto err, to keep the errno */
676
 
                        break;
677
 
 
678
 
                /* todo: plink too? */
679
 
                if (!do_udba)
680
 
                        continue;
681
 
 
682
 
                /* UDBA tests */
683
 
                h_inode = h_dentry->d_inode;
684
 
                if (unlikely(!!inode != !!h_inode))
685
 
                        goto err;
686
 
 
687
 
                h_plus = plus;
688
 
                h_mode = mode;
689
 
                h_cached_inode = h_inode;
690
 
                if (h_inode) {
691
 
                        h_mode = (h_inode->i_mode & S_IFMT);
692
 
                        h_plus = (h_inode->i_nlink > 0);
693
 
                }
694
 
                if (inode && ibs <= bindex && bindex <= ibe)
695
 
                        h_cached_inode = au_h_iptr(inode, bindex);
696
 
 
697
 
                if (unlikely(plus != h_plus
698
 
                             || mode != h_mode
699
 
                             || h_cached_inode != h_inode))
700
 
                        goto err;
701
 
                continue;
702
 
 
703
 
        err:
704
 
                err = -EINVAL;
705
 
                break;
706
 
        }
707
 
 
708
 
        return err;
709
 
}
710
 
 
711
 
static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
712
 
{
713
 
        int err;
714
 
        struct dentry *parent;
715
 
        struct inode *inode;
716
 
 
717
 
        inode = dentry->d_inode;
718
 
        if (au_digen(dentry) == sigen && au_iigen(inode) == sigen)
719
 
                return 0;
720
 
 
721
 
        parent = dget_parent(dentry);
722
 
        di_read_lock_parent(parent, AuLock_IR);
723
 
        AuDebugOn(au_digen(parent) != sigen
724
 
                  || au_iigen(parent->d_inode) != sigen);
725
 
        au_dbg_verify_gen(parent, sigen);
726
 
 
727
 
        /* returns a number of positive dentries */
728
 
        err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT);
729
 
        if (err >= 0)
730
 
                err = au_refresh_hinode(inode, dentry);
731
 
 
732
 
        di_read_unlock(parent, AuLock_IR);
733
 
        dput(parent);
734
 
        return err;
735
 
}
736
 
 
737
 
int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
738
 
{
739
 
        int err;
740
 
        struct dentry *d, *parent;
741
 
        struct inode *inode;
742
 
 
743
 
        if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS))
744
 
                return simple_reval_dpath(dentry, sigen);
745
 
 
746
 
        /* slow loop, keep it simple and stupid */
747
 
        /* cf: au_cpup_dirs() */
748
 
        err = 0;
749
 
        parent = NULL;
750
 
        while (au_digen(dentry) != sigen
751
 
               || au_iigen(dentry->d_inode) != sigen) {
752
 
                d = dentry;
753
 
                while (1) {
754
 
                        dput(parent);
755
 
                        parent = dget_parent(d);
756
 
                        if (au_digen(parent) == sigen
757
 
                            && au_iigen(parent->d_inode) == sigen)
758
 
                                break;
759
 
                        d = parent;
760
 
                }
761
 
 
762
 
                inode = d->d_inode;
763
 
                if (d != dentry)
764
 
                        di_write_lock_child(d);
765
 
 
766
 
                /* someone might update our dentry while we were sleeping */
767
 
                if (au_digen(d) != sigen || au_iigen(d->d_inode) != sigen) {
768
 
                        di_read_lock_parent(parent, AuLock_IR);
769
 
                        /* returns a number of positive dentries */
770
 
                        err = au_refresh_hdentry(d, inode->i_mode & S_IFMT);
771
 
                        if (err >= 0)
772
 
                                err = au_refresh_hinode(inode, d);
773
 
                        di_read_unlock(parent, AuLock_IR);
774
 
                }
775
 
 
776
 
                if (d != dentry)
777
 
                        di_write_unlock(d);
778
 
                dput(parent);
779
 
                if (unlikely(err))
780
 
                        break;
781
 
        }
782
 
 
783
 
        return err;
784
 
}
785
 
 
786
 
/*
787
 
 * if valid returns 1, otherwise 0.
788
 
 */
789
 
static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
790
 
{
791
 
        int valid, err;
792
 
        unsigned int sigen;
793
 
        unsigned char do_udba;
794
 
        struct super_block *sb;
795
 
        struct inode *inode;
796
 
 
797
 
        err = -EINVAL;
798
 
        sb = dentry->d_sb;
799
 
        inode = dentry->d_inode;
800
 
        aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW);
801
 
        sigen = au_sigen(sb);
802
 
        if (au_digen(dentry) != sigen) {
803
 
                AuDebugOn(IS_ROOT(dentry));
804
 
                if (inode)
805
 
                        err = au_reval_dpath(dentry, sigen);
806
 
                if (unlikely(err))
807
 
                        goto out_dgrade;
808
 
                AuDebugOn(au_digen(dentry) != sigen);
809
 
        }
810
 
        if (inode && au_iigen(inode) != sigen) {
811
 
                AuDebugOn(IS_ROOT(dentry));
812
 
                err = au_refresh_hinode(inode, dentry);
813
 
                if (unlikely(err))
814
 
                        goto out_dgrade;
815
 
                AuDebugOn(au_iigen(inode) != sigen);
816
 
        }
817
 
        di_downgrade_lock(dentry, AuLock_IR);
818
 
 
819
 
        AuDebugOn(au_digen(dentry) != sigen);
820
 
        AuDebugOn(inode && au_iigen(inode) != sigen);
821
 
        err = -EINVAL;
822
 
        do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
823
 
        if (do_udba && inode) {
824
 
                aufs_bindex_t bstart = au_ibstart(inode);
825
 
 
826
 
                if (bstart >= 0
827
 
                    && au_test_higen(inode, au_h_iptr(inode, bstart)))
828
 
                        goto out;
829
 
        }
830
 
 
831
 
        err = h_d_revalidate(dentry, inode, nd, do_udba);
832
 
        if (unlikely(!err && do_udba && au_dbstart(dentry) < 0))
833
 
                /* both of real entry and whiteout found */
834
 
                err = -EIO;
835
 
        goto out;
836
 
 
837
 
 out_dgrade:
838
 
        di_downgrade_lock(dentry, AuLock_IR);
839
 
 out:
840
 
        au_store_oflag(nd, inode);
841
 
        aufs_read_unlock(dentry, AuLock_IR);
842
 
        AuTraceErr(err);
843
 
        valid = !err;
844
 
        if (!valid)
845
 
                AuDbg("%.*s invalid\n", AuDLNPair(dentry));
846
 
        return valid;
847
 
}
848
 
 
849
 
static void aufs_d_release(struct dentry *dentry)
850
 
{
851
 
        struct au_dinfo *dinfo;
852
 
        aufs_bindex_t bend, bindex;
853
 
 
854
 
        dinfo = dentry->d_fsdata;
855
 
        if (!dinfo)
856
 
                return;
857
 
 
858
 
        /* dentry may not be revalidated */
859
 
        bindex = dinfo->di_bstart;
860
 
        if (bindex >= 0) {
861
 
                struct au_hdentry *p;
862
 
 
863
 
                bend = dinfo->di_bend;
864
 
                p = dinfo->di_hdentry + bindex;
865
 
                while (bindex++ <= bend) {
866
 
                        if (p->hd_dentry)
867
 
                                au_hdput(p);
868
 
                        p++;
869
 
                }
870
 
        }
871
 
        kfree(dinfo->di_hdentry);
872
 
        AuRwDestroy(&dinfo->di_rwsem);
873
 
        au_cache_free_dinfo(dinfo);
874
 
        au_hin_di_reinit(dentry);
875
 
}
876
 
 
877
 
struct dentry_operations aufs_dop = {
878
 
        .d_revalidate   = aufs_d_revalidate,
879
 
        .d_release      = aufs_d_release
880
 
};