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

« back to all changes in this revision

Viewing changes to ubuntu/aufs/hinotify.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
 
 * inotify for the lower directories
21
 
 */
22
 
 
23
 
#include "aufs.h"
24
 
 
25
 
static const __u32 AuHinMask = (IN_MOVE | IN_DELETE | IN_CREATE);
26
 
static struct inotify_handle *au_hin_handle;
27
 
 
28
 
AuCacheFuncs(hinotify, HINOTIFY);
29
 
 
30
 
int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
31
 
                 struct inode *h_inode)
32
 
{
33
 
        int err;
34
 
        struct au_hinotify *hin;
35
 
        s32 wd;
36
 
 
37
 
        err = -ENOMEM;
38
 
        hin = au_cache_alloc_hinotify();
39
 
        if (hin) {
40
 
                AuDebugOn(hinode->hi_notify);
41
 
                hinode->hi_notify = hin;
42
 
                hin->hin_aufs_inode = inode;
43
 
 
44
 
                inotify_init_watch(&hin->hin_watch);
45
 
                wd = inotify_add_watch(au_hin_handle, &hin->hin_watch, h_inode,
46
 
                                       AuHinMask);
47
 
                if (wd >= 0)
48
 
                        return 0; /* success */
49
 
 
50
 
                err = wd;
51
 
                put_inotify_watch(&hin->hin_watch);
52
 
                au_cache_free_hinotify(hin);
53
 
                hinode->hi_notify = NULL;
54
 
        }
55
 
 
56
 
        return err;
57
 
}
58
 
 
59
 
void au_hin_free(struct au_hinode *hinode)
60
 
{
61
 
        int err;
62
 
        struct au_hinotify *hin;
63
 
 
64
 
        hin = hinode->hi_notify;
65
 
        if (hin) {
66
 
                err = 0;
67
 
                if (atomic_read(&hin->hin_watch.count))
68
 
                        err = inotify_rm_watch(au_hin_handle, &hin->hin_watch);
69
 
                if (unlikely(err))
70
 
                        /* it means the watch is already removed */
71
 
                        AuWarn("failed inotify_rm_watch() %d\n", err);
72
 
                au_cache_free_hinotify(hin);
73
 
                hinode->hi_notify = NULL;
74
 
        }
75
 
}
76
 
 
77
 
/* ---------------------------------------------------------------------- */
78
 
 
79
 
void au_hin_ctl(struct au_hinode *hinode, int do_set)
80
 
{
81
 
        struct inode *h_inode;
82
 
        struct inotify_watch *watch;
83
 
 
84
 
        if (!hinode->hi_notify)
85
 
                return;
86
 
 
87
 
        h_inode = hinode->hi_inode;
88
 
        IMustLock(h_inode);
89
 
 
90
 
        /* todo: try inotify_find_update_watch()? */
91
 
        watch = &hinode->hi_notify->hin_watch;
92
 
        mutex_lock(&h_inode->inotify_mutex);
93
 
        /* mutex_lock(&watch->ih->mutex); */
94
 
        if (do_set) {
95
 
                AuDebugOn(watch->mask & AuHinMask);
96
 
                watch->mask |= AuHinMask;
97
 
        } else {
98
 
                AuDebugOn(!(watch->mask & AuHinMask));
99
 
                watch->mask &= ~AuHinMask;
100
 
        }
101
 
        /* mutex_unlock(&watch->ih->mutex); */
102
 
        mutex_unlock(&h_inode->inotify_mutex);
103
 
}
104
 
 
105
 
void au_reset_hinotify(struct inode *inode, unsigned int flags)
106
 
{
107
 
        aufs_bindex_t bindex, bend;
108
 
        struct inode *hi;
109
 
        struct dentry *iwhdentry;
110
 
 
111
 
        bend = au_ibend(inode);
112
 
        for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
113
 
                hi = au_h_iptr(inode, bindex);
114
 
                if (!hi)
115
 
                        continue;
116
 
 
117
 
                /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
118
 
                iwhdentry = au_hi_wh(inode, bindex);
119
 
                if (iwhdentry)
120
 
                        dget(iwhdentry);
121
 
                au_igrab(hi);
122
 
                au_set_h_iptr(inode, bindex, NULL, 0);
123
 
                au_set_h_iptr(inode, bindex, au_igrab(hi),
124
 
                              flags & ~AuHi_XINO);
125
 
                iput(hi);
126
 
                dput(iwhdentry);
127
 
                /* mutex_unlock(&hi->i_mutex); */
128
 
        }
129
 
}
130
 
 
131
 
/* ---------------------------------------------------------------------- */
132
 
 
133
 
static int hin_xino(struct inode *inode, struct inode *h_inode)
134
 
{
135
 
        int err;
136
 
        aufs_bindex_t bindex, bend, bfound, bstart;
137
 
        struct inode *h_i;
138
 
 
139
 
        err = 0;
140
 
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
141
 
                AuWarn("branch root dir was changed\n");
142
 
                goto out;
143
 
        }
144
 
 
145
 
        bfound = -1;
146
 
        bend = au_ibend(inode);
147
 
        bstart = au_ibstart(inode);
148
 
#if 0 /* reserved for future use */
149
 
        if (bindex == bend) {
150
 
                /* keep this ino in rename case */
151
 
                goto out;
152
 
        }
153
 
#endif
154
 
        for (bindex = bstart; bindex <= bend; bindex++) {
155
 
                if (au_h_iptr(inode, bindex) == h_inode) {
156
 
                        bfound = bindex;
157
 
                        break;
158
 
                }
159
 
        }
160
 
        if (bfound < 0)
161
 
                goto out;
162
 
 
163
 
        for (bindex = bstart; bindex <= bend; bindex++) {
164
 
                h_i = au_h_iptr(inode, bindex);
165
 
                if (!h_i)
166
 
                        continue;
167
 
 
168
 
                err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
169
 
                /* ignore this error */
170
 
                /* bad action? */
171
 
        }
172
 
 
173
 
        /* children inode number will be broken */
174
 
 
175
 
 out:
176
 
        AuTraceErr(err);
177
 
        return err;
178
 
}
179
 
 
180
 
static int hin_gen_tree(struct dentry *dentry)
181
 
{
182
 
        int err, i, j, ndentry;
183
 
        struct au_dcsub_pages dpages;
184
 
        struct au_dpage *dpage;
185
 
        struct dentry **dentries;
186
 
 
187
 
        err = au_dpages_init(&dpages, GFP_NOFS);
188
 
        if (unlikely(err))
189
 
                goto out;
190
 
        err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
191
 
        if (unlikely(err))
192
 
                goto out_dpages;
193
 
 
194
 
        for (i = 0; i < dpages.ndpage; i++) {
195
 
                dpage = dpages.dpages + i;
196
 
                dentries = dpage->dentries;
197
 
                ndentry = dpage->ndentry;
198
 
                for (j = 0; j < ndentry; j++) {
199
 
                        struct dentry *d;
200
 
 
201
 
                        d = dentries[j];
202
 
                        if (IS_ROOT(d))
203
 
                                continue;
204
 
 
205
 
                        d_drop(d);
206
 
                        au_digen_dec(d);
207
 
                        if (d->d_inode)
208
 
                                /* todo: reset children xino?
209
 
                                   cached children only? */
210
 
                                au_iigen_dec(d->d_inode);
211
 
                }
212
 
        }
213
 
 
214
 
 out_dpages:
215
 
        au_dpages_free(&dpages);
216
 
 
217
 
        /* discard children */
218
 
        dentry_unhash(dentry);
219
 
        dput(dentry);
220
 
 out:
221
 
        return err;
222
 
}
223
 
 
224
 
/*
225
 
 * return 0 if processed.
226
 
 */
227
 
static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
228
 
                            const unsigned int isdir)
229
 
{
230
 
        int err;
231
 
        struct dentry *d;
232
 
        struct qstr *dname;
233
 
 
234
 
        err = 1;
235
 
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
236
 
                AuWarn("branch root dir was changed\n");
237
 
                err = 0;
238
 
                goto out;
239
 
        }
240
 
 
241
 
        if (!isdir) {
242
 
                AuDebugOn(!name);
243
 
                au_iigen_dec(inode);
244
 
                spin_lock(&dcache_lock);
245
 
                list_for_each_entry(d, &inode->i_dentry, d_alias) {
246
 
                        dname = &d->d_name;
247
 
                        if (dname->len != nlen
248
 
                            && memcmp(dname->name, name, nlen))
249
 
                                continue;
250
 
                        err = 0;
251
 
                        spin_lock(&d->d_lock);
252
 
                        __d_drop(d);
253
 
                        au_digen_dec(d);
254
 
                        spin_unlock(&d->d_lock);
255
 
                        break;
256
 
                }
257
 
                spin_unlock(&dcache_lock);
258
 
        } else {
259
 
                au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS);
260
 
                d = d_find_alias(inode);
261
 
                if (!d) {
262
 
                        au_iigen_dec(inode);
263
 
                        goto out;
264
 
                }
265
 
 
266
 
                dname = &d->d_name;
267
 
                if (dname->len == nlen && !memcmp(dname->name, name, nlen))
268
 
                        err = hin_gen_tree(d);
269
 
                dput(d);
270
 
        }
271
 
 
272
 
 out:
273
 
        AuTraceErr(err);
274
 
        return err;
275
 
}
276
 
 
277
 
static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir)
278
 
{
279
 
        int err;
280
 
        struct inode *inode;
281
 
 
282
 
        inode = dentry->d_inode;
283
 
        if (IS_ROOT(dentry)
284
 
            /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
285
 
                ) {
286
 
                AuWarn("branch root dir was changed\n");
287
 
                return 0;
288
 
        }
289
 
 
290
 
        err = 0;
291
 
        if (!isdir) {
292
 
                d_drop(dentry);
293
 
                au_digen_dec(dentry);
294
 
                if (inode)
295
 
                        au_iigen_dec(inode);
296
 
        } else {
297
 
                au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS);
298
 
                if (inode)
299
 
                        err = hin_gen_tree(dentry);
300
 
        }
301
 
 
302
 
        AuTraceErr(err);
303
 
        return err;
304
 
}
305
 
 
306
 
/* ---------------------------------------------------------------------- */
307
 
 
308
 
/* hinotify job flags */
309
 
#define AuHinJob_XINO0          1
310
 
#define AuHinJob_GEN            (1 << 1)
311
 
#define AuHinJob_DIRENT         (1 << 2)
312
 
#define AuHinJob_ISDIR          (1 << 3)
313
 
#define AuHinJob_TRYXINO0       (1 << 4)
314
 
#define AuHinJob_MNTPNT         (1 << 5)
315
 
#define au_ftest_hinjob(flags, name)    ((flags) & AuHinJob_##name)
316
 
#define au_fset_hinjob(flags, name)     { (flags) |= AuHinJob_##name; }
317
 
#define au_fclr_hinjob(flags, name)     { (flags) &= ~AuHinJob_##name; }
318
 
 
319
 
struct hin_job_args {
320
 
        unsigned int flags;
321
 
        struct inode *inode, *h_inode, *dir, *h_dir;
322
 
        struct dentry *dentry;
323
 
        char *h_name;
324
 
        int h_nlen;
325
 
};
326
 
 
327
 
static int hin_job(struct hin_job_args *a)
328
 
{
329
 
        const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR);
330
 
 
331
 
        /* reset xino */
332
 
        if (au_ftest_hinjob(a->flags, XINO0) && a->inode)
333
 
                hin_xino(a->inode, a->h_inode); /* ignore this error */
334
 
 
335
 
        if (au_ftest_hinjob(a->flags, TRYXINO0)
336
 
            && a->inode
337
 
            && a->h_inode) {
338
 
                mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
339
 
                if (!a->h_inode->i_nlink)
340
 
                        hin_xino(a->inode, a->h_inode); /* ignore this error */
341
 
                mutex_unlock(&a->h_inode->i_mutex);
342
 
        }
343
 
 
344
 
        /* make the generation obsolete */
345
 
        if (au_ftest_hinjob(a->flags, GEN)) {
346
 
                int err = -1;
347
 
                if (a->inode)
348
 
                        err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode,
349
 
                                               isdir);
350
 
                if (err && a->dentry)
351
 
                        hin_gen_by_name(a->dentry, isdir);
352
 
                /* ignore this error */
353
 
        }
354
 
 
355
 
        /* make dir entries obsolete */
356
 
        if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) {
357
 
                struct au_vdir *vdir;
358
 
 
359
 
                vdir = au_ivdir(a->inode);
360
 
                if (vdir)
361
 
                        vdir->vd_jiffy = 0;
362
 
                /* IMustLock(a->inode); */
363
 
                /* a->inode->i_version++; */
364
 
        }
365
 
 
366
 
        /* can do nothing but warn */
367
 
        if (au_ftest_hinjob(a->flags, MNTPNT)
368
 
            && a->dentry
369
 
            && d_mountpoint(a->dentry))
370
 
                AuWarn("mount-point %.*s is removed or renamed\n",
371
 
                       AuDLNPair(a->dentry));
372
 
 
373
 
        return 0;
374
 
}
375
 
 
376
 
/* ---------------------------------------------------------------------- */
377
 
 
378
 
static char *in_name(u32 mask)
379
 
{
380
 
#ifdef CONFIG_AUFS_DEBUG
381
 
#define test_ret(flag)  if (mask & flag) \
382
 
                                return #flag;
383
 
        test_ret(IN_ACCESS);
384
 
        test_ret(IN_MODIFY);
385
 
        test_ret(IN_ATTRIB);
386
 
        test_ret(IN_CLOSE_WRITE);
387
 
        test_ret(IN_CLOSE_NOWRITE);
388
 
        test_ret(IN_OPEN);
389
 
        test_ret(IN_MOVED_FROM);
390
 
        test_ret(IN_MOVED_TO);
391
 
        test_ret(IN_CREATE);
392
 
        test_ret(IN_DELETE);
393
 
        test_ret(IN_DELETE_SELF);
394
 
        test_ret(IN_MOVE_SELF);
395
 
        test_ret(IN_UNMOUNT);
396
 
        test_ret(IN_Q_OVERFLOW);
397
 
        test_ret(IN_IGNORED);
398
 
        return "";
399
 
#undef test_ret
400
 
#else
401
 
        return "??";
402
 
#endif
403
 
}
404
 
 
405
 
static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
406
 
                                           struct inode *dir)
407
 
{
408
 
        struct dentry *dentry, *d, *parent;
409
 
        struct qstr *dname;
410
 
 
411
 
        parent = d_find_alias(dir);
412
 
        if (!parent)
413
 
                return NULL;
414
 
 
415
 
        dentry = NULL;
416
 
        spin_lock(&dcache_lock);
417
 
        list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
418
 
                /* AuDbg("%.*s\n", AuDLNPair(d)); */
419
 
                dname = &d->d_name;
420
 
                if (dname->len != nlen || memcmp(dname->name, name, nlen))
421
 
                        continue;
422
 
                if (!atomic_read(&d->d_count) || !d->d_fsdata) {
423
 
                        spin_lock(&d->d_lock);
424
 
                        __d_drop(d);
425
 
                        spin_unlock(&d->d_lock);
426
 
                        continue;
427
 
                }
428
 
 
429
 
                dentry = dget(d);
430
 
                break;
431
 
        }
432
 
        spin_unlock(&dcache_lock);
433
 
        dput(parent);
434
 
 
435
 
        if (dentry)
436
 
                di_write_lock_child(dentry);
437
 
 
438
 
        return dentry;
439
 
}
440
 
 
441
 
static struct inode *lookup_wlock_by_ino(struct super_block *sb,
442
 
                                         aufs_bindex_t bindex, ino_t h_ino)
443
 
{
444
 
        struct inode *inode;
445
 
        ino_t ino;
446
 
        int err;
447
 
 
448
 
        inode = NULL;
449
 
        err = au_xino_read(sb, bindex, h_ino, &ino);
450
 
        if (!err && ino)
451
 
                inode = ilookup(sb, ino);
452
 
        if (!inode)
453
 
                goto out;
454
 
 
455
 
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
456
 
                AuWarn("wrong root branch\n");
457
 
                iput(inode);
458
 
                inode = NULL;
459
 
                goto out;
460
 
        }
461
 
 
462
 
        ii_write_lock_child(inode);
463
 
 
464
 
 out:
465
 
        return inode;
466
 
}
467
 
 
468
 
enum { CHILD, PARENT };
469
 
struct postproc_args {
470
 
        struct inode *h_dir, *dir, *h_child_inode;
471
 
        u32 mask;
472
 
        unsigned int flags[2];
473
 
        unsigned int h_child_nlen;
474
 
        char h_child_name[];
475
 
};
476
 
 
477
 
static void postproc(void *_args)
478
 
{
479
 
        struct postproc_args *a = _args;
480
 
        struct super_block *sb;
481
 
        aufs_bindex_t bindex, bend, bfound;
482
 
        unsigned char xino, try_iput;
483
 
        int err;
484
 
        struct inode *inode;
485
 
        ino_t h_ino;
486
 
        struct hin_job_args args;
487
 
        struct dentry *dentry;
488
 
        struct au_sbinfo *sbinfo;
489
 
 
490
 
        AuDebugOn(!_args);
491
 
        AuDebugOn(!a->h_dir);
492
 
        AuDebugOn(!a->dir);
493
 
        AuDebugOn(!a->mask);
494
 
        AuDbg("mask 0x%x %s, i%lu, hi%lu, hci%lu\n",
495
 
              a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino,
496
 
              a->h_child_inode ? a->h_child_inode->i_ino : 0);
497
 
 
498
 
        inode = NULL;
499
 
        dentry = NULL;
500
 
        /*
501
 
         * do not lock a->dir->i_mutex here
502
 
         * because of d_revalidate() may cause a deadlock.
503
 
         */
504
 
        sb = a->dir->i_sb;
505
 
        AuDebugOn(!sb);
506
 
        sbinfo = au_sbi(sb);
507
 
        AuDebugOn(!sbinfo);
508
 
        /* big aufs lock */
509
 
        si_noflush_write_lock(sb);
510
 
 
511
 
        ii_read_lock_parent(a->dir);
512
 
        bfound = -1;
513
 
        bend = au_ibend(a->dir);
514
 
        for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
515
 
                if (au_h_iptr(a->dir, bindex) == a->h_dir) {
516
 
                        bfound = bindex;
517
 
                        break;
518
 
                }
519
 
        ii_read_unlock(a->dir);
520
 
        if (unlikely(bfound < 0))
521
 
                goto out;
522
 
 
523
 
        xino = !!au_opt_test(au_mntflags(sb), XINO);
524
 
        h_ino = 0;
525
 
        if (a->h_child_inode)
526
 
                h_ino = a->h_child_inode->i_ino;
527
 
 
528
 
        if (a->h_child_nlen
529
 
            && (au_ftest_hinjob(a->flags[CHILD], GEN)
530
 
                || au_ftest_hinjob(a->flags[CHILD], MNTPNT)))
531
 
                dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
532
 
                                              a->dir);
533
 
        try_iput = 0;
534
 
        if (dentry)
535
 
                inode = dentry->d_inode;
536
 
        if (xino && !inode && h_ino
537
 
            && (au_ftest_hinjob(a->flags[CHILD], XINO0)
538
 
                || au_ftest_hinjob(a->flags[CHILD], TRYXINO0)
539
 
                || au_ftest_hinjob(a->flags[CHILD], GEN))) {
540
 
                inode = lookup_wlock_by_ino(sb, bfound, h_ino);
541
 
                try_iput = 1;
542
 
            }
543
 
 
544
 
        args.flags = a->flags[CHILD];
545
 
        args.dentry = dentry;
546
 
        args.inode = inode;
547
 
        args.h_inode = a->h_child_inode;
548
 
        args.dir = a->dir;
549
 
        args.h_dir = a->h_dir;
550
 
        args.h_name = a->h_child_name;
551
 
        args.h_nlen = a->h_child_nlen;
552
 
        err = hin_job(&args);
553
 
        if (dentry) {
554
 
                if (dentry->d_fsdata)
555
 
                        di_write_unlock(dentry);
556
 
                dput(dentry);
557
 
        }
558
 
        if (inode && try_iput) {
559
 
                ii_write_unlock(inode);
560
 
                iput(inode);
561
 
        }
562
 
 
563
 
        ii_write_lock_parent(a->dir);
564
 
        args.flags = a->flags[PARENT];
565
 
        args.dentry = NULL;
566
 
        args.inode = a->dir;
567
 
        args.h_inode = a->h_dir;
568
 
        args.dir = NULL;
569
 
        args.h_dir = NULL;
570
 
        args.h_name = NULL;
571
 
        args.h_nlen = 0;
572
 
        err = hin_job(&args);
573
 
        ii_write_unlock(a->dir);
574
 
 
575
 
 out:
576
 
        au_nwt_done(&sbinfo->si_nowait);
577
 
        si_write_unlock(sb);
578
 
 
579
 
        iput(a->h_child_inode);
580
 
        iput(a->h_dir);
581
 
        iput(a->dir);
582
 
        kfree(a);
583
 
}
584
 
 
585
 
/* ---------------------------------------------------------------------- */
586
 
 
587
 
static void aufs_inotify(struct inotify_watch *watch, u32 wd __maybe_unused,
588
 
                         u32 mask, u32 cookie __maybe_unused,
589
 
                         const char *h_child_name, struct inode *h_child_inode)
590
 
{
591
 
        struct au_hinotify *hinotify;
592
 
        struct postproc_args *args;
593
 
        int len, wkq_err;
594
 
        unsigned char isdir, isroot, wh;
595
 
        char *p;
596
 
        struct inode *dir;
597
 
        unsigned int flags[2];
598
 
 
599
 
        /* if IN_UNMOUNT happens, there must be another bug */
600
 
        AuDebugOn(mask & IN_UNMOUNT);
601
 
        if (mask & (IN_IGNORED | IN_UNMOUNT)) {
602
 
                put_inotify_watch(watch);
603
 
                return;
604
 
        }
605
 
#ifdef AuDbgHinotify
606
 
        au_debug(1);
607
 
        if (1 || !h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) {
608
 
                AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s,"
609
 
                      " hi%lu\n",
610
 
                      watch->inode->i_ino, wd, mask, in_name(mask), cookie,
611
 
                      h_child_name ? h_child_name : "",
612
 
                      h_child_inode ? h_child_inode->i_ino : 0);
613
 
                WARN_ON(1);
614
 
        }
615
 
        au_debug(0);
616
 
#endif
617
 
 
618
 
        hinotify = container_of(watch, struct au_hinotify, hin_watch);
619
 
        AuDebugOn(!hinotify || !hinotify->hin_aufs_inode);
620
 
        dir = igrab(hinotify->hin_aufs_inode);
621
 
        if (!dir)
622
 
                return;
623
 
 
624
 
        isroot = (dir->i_ino == AUFS_ROOT_INO);
625
 
        len = 0;
626
 
        wh = 0;
627
 
        if (h_child_name) {
628
 
                len = strlen(h_child_name);
629
 
                if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
630
 
                        h_child_name += AUFS_WH_PFX_LEN;
631
 
                        len -= AUFS_WH_PFX_LEN;
632
 
                        wh = 1;
633
 
                }
634
 
        }
635
 
 
636
 
        isdir = 0;
637
 
        if (h_child_inode)
638
 
                isdir = !!S_ISDIR(h_child_inode->i_mode);
639
 
        flags[PARENT] = AuHinJob_ISDIR;
640
 
        flags[CHILD] = 0;
641
 
        if (isdir)
642
 
                flags[CHILD] = AuHinJob_ISDIR;
643
 
        switch (mask & IN_ALL_EVENTS) {
644
 
        case IN_MOVED_FROM:
645
 
        case IN_MOVED_TO:
646
 
                AuDebugOn(!h_child_name || !h_child_inode);
647
 
                au_fset_hinjob(flags[CHILD], GEN);
648
 
                au_fset_hinjob(flags[CHILD], XINO0);
649
 
                au_fset_hinjob(flags[CHILD], MNTPNT);
650
 
                au_fset_hinjob(flags[PARENT], DIRENT);
651
 
                break;
652
 
 
653
 
        case IN_CREATE:
654
 
                AuDebugOn(!h_child_name || !h_child_inode);
655
 
                au_fset_hinjob(flags[PARENT], DIRENT);
656
 
                au_fset_hinjob(flags[CHILD], GEN);
657
 
                break;
658
 
 
659
 
        case IN_DELETE:
660
 
                /*
661
 
                 * aufs never be able to get this child inode.
662
 
                 * revalidation should be in d_revalidate()
663
 
                 * by checking i_nlink, i_generation or d_unhashed().
664
 
                 */
665
 
                AuDebugOn(!h_child_name);
666
 
                au_fset_hinjob(flags[PARENT], DIRENT);
667
 
                au_fset_hinjob(flags[CHILD], GEN);
668
 
                au_fset_hinjob(flags[CHILD], TRYXINO0);
669
 
                au_fset_hinjob(flags[CHILD], MNTPNT);
670
 
                break;
671
 
 
672
 
        default:
673
 
                AuDebugOn(1);
674
 
        }
675
 
 
676
 
        if (wh)
677
 
                h_child_inode = NULL;
678
 
 
679
 
        /* iput() and kfree() will be called in postproc() */
680
 
        /*
681
 
         * inotify_mutex is already acquired and kmalloc/prune_icache may lock
682
 
         * iprune_mutex. strange.
683
 
         */
684
 
        lockdep_off();
685
 
        args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
686
 
        lockdep_on();
687
 
        if (unlikely(!args)) {
688
 
                AuErr1("no memory\n");
689
 
                iput(dir);
690
 
                return;
691
 
        }
692
 
        args->flags[PARENT] = flags[PARENT];
693
 
        args->flags[CHILD] = flags[CHILD];
694
 
        args->mask = mask;
695
 
        args->dir = dir;
696
 
        args->h_dir = igrab(watch->inode);
697
 
        if (h_child_inode)
698
 
                h_child_inode = igrab(h_child_inode); /* can be NULL */
699
 
        args->h_child_inode = h_child_inode;
700
 
        args->h_child_nlen = len;
701
 
        if (len) {
702
 
                p = (void *)args;
703
 
                p += sizeof(*args);
704
 
                memcpy(p, h_child_name, len + 1);
705
 
        }
706
 
 
707
 
        lockdep_off();
708
 
        wkq_err = au_wkq_nowait(postproc, args, dir->i_sb);
709
 
        lockdep_on();
710
 
        if (unlikely(wkq_err))
711
 
                AuErr("wkq %d\n", wkq_err);
712
 
}
713
 
 
714
 
static void aufs_inotify_destroy(struct inotify_watch *watch __maybe_unused)
715
 
{
716
 
        return;
717
 
}
718
 
 
719
 
static struct inotify_operations aufs_inotify_ops = {
720
 
        .handle_event   = aufs_inotify,
721
 
        .destroy_watch  = aufs_inotify_destroy
722
 
};
723
 
 
724
 
/* ---------------------------------------------------------------------- */
725
 
 
726
 
static void au_hin_destroy_cache(void)
727
 
{
728
 
        kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]);
729
 
        au_cachep[AuCache_HINOTIFY] = NULL;
730
 
}
731
 
 
732
 
int __init au_hinotify_init(void)
733
 
{
734
 
        int err;
735
 
 
736
 
        err = -ENOMEM;
737
 
        au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify);
738
 
        if (au_cachep[AuCache_HINOTIFY]) {
739
 
                err = 0;
740
 
                au_hin_handle = inotify_init(&aufs_inotify_ops);
741
 
                if (IS_ERR(au_hin_handle)) {
742
 
                        err = PTR_ERR(au_hin_handle);
743
 
                        au_hin_destroy_cache();
744
 
                }
745
 
        }
746
 
        AuTraceErr(err);
747
 
        return err;
748
 
}
749
 
 
750
 
void au_hinotify_fin(void)
751
 
{
752
 
        inotify_destroy(au_hin_handle);
753
 
        if (au_cachep[AuCache_HINOTIFY])
754
 
                au_hin_destroy_cache();
755
 
}