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

« back to all changes in this revision

Viewing changes to fs/aufs25/hinotify.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) 2006-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
 * inotify handler
 
21
 *
 
22
 * $Id: hinotify.c,v 1.4 2008/05/04 23:52:19 sfjro Exp $
 
23
 */
 
24
 
 
25
#include "aufs.h"
 
26
 
 
27
/* inotify events */
 
28
static const __u32 AuInMask = (IN_MOVE | IN_DELETE | IN_CREATE
 
29
                               /* | IN_ACCESS */
 
30
                               | IN_MODIFY | IN_ATTRIB
 
31
                               /* | IN_DELETE_SELF | IN_MOVE_SELF */
 
32
        );
 
33
static struct inotify_handle *in_handle;
 
34
 
 
35
/* the size of an array for ignore counter */
 
36
static int au_hin_nignore;
 
37
 
 
38
AuCacheFuncs(hinotify, AuCache_HINOTIFY);
 
39
 
 
40
int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
 
41
                 struct inode *hidden_inode)
 
42
{
 
43
        int err, i;
 
44
        struct au_hinotify *hin;
 
45
        s32 wd;
 
46
 
 
47
        LKTRTrace("i%lu, hi%lu\n", inode->i_ino, hidden_inode->i_ino);
 
48
 
 
49
        err = -ENOMEM;
 
50
        hin = au_cache_alloc_hinotify();
 
51
        if (hin) {
 
52
                AuDebugOn(hinode->hi_notify);
 
53
                hinode->hi_notify = hin;
 
54
                hin->hin_aufs_inode = inode;
 
55
                for (i = 0; i < au_hin_nignore; i++)
 
56
                        atomic_set(hin->hin_ignore + i, 0);
 
57
 
 
58
                inotify_init_watch(&hin->hin_watch);
 
59
                wd = inotify_add_watch(in_handle, &hin->hin_watch, hidden_inode,
 
60
                                       AuInMask);
 
61
                if (wd >= 0)
 
62
                        return 0; /* success */
 
63
 
 
64
                err = wd;
 
65
                put_inotify_watch(&hin->hin_watch);
 
66
                au_cache_free_hinotify(hin);
 
67
                hinode->hi_notify = NULL;
 
68
        }
 
69
 
 
70
        AuTraceErr(err);
 
71
        return err;
 
72
}
 
73
 
 
74
void au_hin_free(struct au_hinode *hinode)
 
75
{
 
76
        int err;
 
77
        struct au_hinotify *hin;
 
78
 
 
79
        AuTraceEnter();
 
80
 
 
81
        hin = hinode->hi_notify;
 
82
        if (unlikely(hin)) {
 
83
                err = 0;
 
84
                if (atomic_read(&hin->hin_watch.count))
 
85
                        err = inotify_rm_watch(in_handle, &hin->hin_watch);
 
86
 
 
87
                if (!err) {
 
88
                        au_cache_free_hinotify(hin);
 
89
                        hinode->hi_notify = NULL;
 
90
                } else
 
91
                        AuIOErr1("failed inotify_rm_watch() %d\n", err);
 
92
        }
 
93
}
 
94
 
 
95
/* ---------------------------------------------------------------------- */
 
96
 
 
97
static void ctl_hinotify(struct au_hinode *hinode, const __u32 mask)
 
98
{
 
99
        struct inode *h_inode;
 
100
        struct inotify_watch *watch;
 
101
 
 
102
        h_inode = hinode->hi_inode;
 
103
        LKTRTrace("hi%lu, sb %p, 0x%x\n", h_inode->i_ino, h_inode->i_sb, mask);
 
104
        IMustLock(h_inode);
 
105
        if (!hinode->hi_notify)
 
106
                return;
 
107
 
 
108
        watch = &hinode->hi_notify->hin_watch;
 
109
#if 0 // temp
 
110
        {
 
111
                u32 wd;
 
112
                wd = inotify_find_update_watch(in_handle, h_inode, mask);
 
113
                AuTraceErr(wd);
 
114
                /* ignore an err; */
 
115
        }
 
116
#else
 
117
        /* struct inotify_handle is hidden */
 
118
        mutex_lock(&h_inode->inotify_mutex);
 
119
        //mutex_lock(&watch->ih->mutex);
 
120
        watch->mask = mask;
 
121
        //mutex_unlock(&watch->ih->mutex);
 
122
        mutex_unlock(&h_inode->inotify_mutex);
 
123
#endif
 
124
        LKTRTrace("watch %p, mask %u\n", watch, watch->mask);
 
125
}
 
126
 
 
127
#define suspend_hinotify(hi)    ctl_hinotify(hi, 0)
 
128
#define resume_hinotify(hi)     ctl_hinotify(hi, AuInMask)
 
129
 
 
130
void au_do_hdir_lock(struct inode *h_dir, struct inode *dir,
 
131
                     aufs_bindex_t bindex, unsigned int lsc)
 
132
{
 
133
        struct au_hinode *hinode;
 
134
 
 
135
        LKTRTrace("i%lu, b%d, lsc %d\n", dir->i_ino, bindex, lsc);
 
136
        AuDebugOn(!S_ISDIR(dir->i_mode));
 
137
        hinode = au_ii(dir)->ii_hinode + bindex;
 
138
        AuDebugOn(h_dir != hinode->hi_inode);
 
139
 
 
140
        mutex_lock_nested(&h_dir->i_mutex, lsc);
 
141
        suspend_hinotify(hinode);
 
142
}
 
143
 
 
144
void au_hdir_unlock(struct inode *h_dir, struct inode *dir,
 
145
                    aufs_bindex_t bindex)
 
146
{
 
147
        struct au_hinode *hinode;
 
148
 
 
149
        LKTRTrace("i%lu, b%d\n", dir->i_ino, bindex);
 
150
        AuDebugOn(!S_ISDIR(dir->i_mode));
 
151
        hinode = au_ii(dir)->ii_hinode + bindex;
 
152
        AuDebugOn(h_dir != hinode->hi_inode);
 
153
 
 
154
        resume_hinotify(hinode);
 
155
        mutex_unlock(&h_dir->i_mutex);
 
156
}
 
157
 
 
158
struct dentry *au_hdir_lock_rename(struct dentry **h_parents,
 
159
                                   struct inode **dirs, aufs_bindex_t bindex,
 
160
                                   int issamedir)
 
161
{
 
162
        struct dentry *h_trap;
 
163
        struct au_hinode *hinode;
 
164
 
 
165
        LKTRTrace("%.*s, %.*s\n",
 
166
                  AuDLNPair(h_parents[0]), AuDLNPair(h_parents[1]));
 
167
 
 
168
        h_trap = vfsub_lock_rename(h_parents[0], h_parents[1]);
 
169
        hinode = au_ii(dirs[0])->ii_hinode + bindex;
 
170
        AuDebugOn(h_parents[0]->d_inode != hinode->hi_inode);
 
171
        suspend_hinotify(hinode);
 
172
        if (!issamedir) {
 
173
                hinode = au_ii(dirs[1])->ii_hinode + bindex;
 
174
                AuDebugOn(h_parents[1]->d_inode != hinode->hi_inode);
 
175
                suspend_hinotify(hinode);
 
176
        }
 
177
 
 
178
        return h_trap;
 
179
}
 
180
 
 
181
void au_hdir_unlock_rename(struct dentry **h_parents, struct inode **dirs,
 
182
                           aufs_bindex_t bindex, int issamedir)
 
183
{
 
184
        struct au_hinode *hinode;
 
185
 
 
186
        LKTRTrace("%.*s, %.*s\n",
 
187
                  AuDLNPair(h_parents[0]), AuDLNPair(h_parents[1]));
 
188
 
 
189
        hinode = au_ii(dirs[0])->ii_hinode + bindex;
 
190
        AuDebugOn(h_parents[0]->d_inode != hinode->hi_inode);
 
191
        resume_hinotify(hinode);
 
192
        if (!issamedir) {
 
193
                hinode = au_ii(dirs[1])->ii_hinode + bindex;
 
194
                AuDebugOn(h_parents[1]->d_inode != hinode->hi_inode);
 
195
                resume_hinotify(hinode);
 
196
        }
 
197
        vfsub_unlock_rename(h_parents[0], h_parents[1]);
 
198
}
 
199
 
 
200
void au_reset_hinotify(struct inode *inode, unsigned int flags)
 
201
{
 
202
        aufs_bindex_t bindex, bend;
 
203
        struct inode *hi;
 
204
        struct dentry *iwhdentry;
 
205
 
 
206
        LKTRTrace("i%lu, 0x%x\n", inode->i_ino, flags);
 
207
 
 
208
        bend = au_ibend(inode);
 
209
        for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
 
210
                hi = au_h_iptr(inode, bindex);
 
211
                if (hi) {
 
212
                        //mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD);
 
213
                        iwhdentry = au_hi_wh(inode, bindex);
 
214
                        if (unlikely(iwhdentry))
 
215
                                dget(iwhdentry);
 
216
                        igrab(hi);
 
217
                        au_set_h_iptr(inode, bindex, NULL, 0);
 
218
                        au_set_h_iptr(inode, bindex, igrab(hi),
 
219
                                      flags & ~AuHi_XINO);
 
220
                        iput(hi);
 
221
                        dput(iwhdentry);
 
222
                        //mutex_unlock(&hi->i_mutex);
 
223
                }
 
224
        }
 
225
}
 
226
 
 
227
/* ---------------------------------------------------------------------- */
 
228
 
 
229
/* cf. fsnotify_change() */
 
230
__u32 vfsub_events_notify_change(struct iattr *ia)
 
231
{
 
232
        __u32 events;
 
233
        const unsigned int amtime = (ATTR_ATIME | ATTR_MTIME);
 
234
 
 
235
        events = 0;
 
236
        if ((ia->ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE))
 
237
            || (ia->ia_valid & amtime) == amtime)
 
238
                events |= IN_ATTRIB;
 
239
        if ((ia->ia_valid & ATTR_SIZE)
 
240
            || (ia->ia_valid & amtime) == ATTR_MTIME)
 
241
                events |= IN_MODIFY;
 
242
        return events;
 
243
}
 
244
 
 
245
void vfsub_ign_hinode(struct vfsub_args *vargs, __u32 events,
 
246
                      struct au_hinode *hinode)
 
247
{
 
248
        struct au_hin_ignore *ign;
 
249
 
 
250
        AuDebugOn(!hinode);
 
251
 
 
252
        ign = vargs->ignore + vargs->nignore++;
 
253
        ign->ign_events = events;
 
254
        ign->ign_hinode = hinode;
 
255
}
 
256
 
 
257
void vfsub_ignore(struct vfsub_args *vargs)
 
258
{
 
259
        int n;
 
260
        struct au_hin_ignore *ign;
 
261
 
 
262
        n = vargs->nignore;
 
263
        ign = vargs->ignore;
 
264
        while (n-- > 0) {
 
265
                au_hin_ignore(ign->ign_hinode, ign->ign_events);
 
266
                ign++;
 
267
        }
 
268
}
 
269
 
 
270
void vfsub_unignore(struct vfsub_args *vargs)
 
271
{
 
272
        int n;
 
273
        struct au_hin_ignore *ign;
 
274
 
 
275
        n = vargs->nignore;
 
276
        ign = vargs->ignore;
 
277
        while (n-- > 0) {
 
278
                au_hin_unignore(ign->ign_hinode, ign->ign_events);
 
279
                ign++;
 
280
        }
 
281
}
 
282
 
 
283
/* ---------------------------------------------------------------------- */
 
284
 
 
285
void au_hin_ignore(struct au_hinode *hinode, __u32 events)
 
286
{
 
287
        int i;
 
288
        atomic_t *ign;
 
289
 
 
290
        LKTRTrace("0x%x\n", events);
 
291
        AuDebugOn(!hinode || !events);
 
292
        if (unlikely(!hinode->hi_inode || !hinode->hi_notify)) {
 
293
                /*
 
294
                 * it may happen by this scenario.
 
295
                 * - a file and its parent dir exist on two branches
 
296
                 * - a file on the upper branch is opened
 
297
                 * - the parent dir and the file are removed by udba
 
298
                 * - the parent is re-accessed, and new dentry/inode in
 
299
                 *   aufs is generated for it, based upon the one on the lower
 
300
                 *   branch
 
301
                 * - the opened file is re-accessed, re-validated, and it may be
 
302
                 *   re-connected to the new parent dentry
 
303
                 * it means the file in aufs cannot get the actual removed
 
304
                 * parent dir on the branch.
 
305
                 */
 
306
                return;
 
307
        }
 
308
        LKTRTrace("hi%lu\n", hinode->hi_inode->i_ino);
 
309
#ifdef DbgInotify
 
310
        AuDbg("hi%lu, 0x%x\n", hinode->hi_inode->i_ino, events);
 
311
#endif
 
312
        AuDebugOn(!hinode->hi_notify);
 
313
 
 
314
        ign = hinode->hi_notify->hin_ignore;
 
315
        for (i = 0; i < au_hin_nignore; i++)
 
316
                if (1U << i & events)
 
317
                        atomic_inc_return(ign + i);
 
318
}
 
319
 
 
320
void au_hin_unignore(struct au_hinode *hinode, __u32 events)
 
321
{
 
322
        int i;
 
323
        atomic_t *ign;
 
324
 
 
325
        LKTRTrace("0x%x\n", events);
 
326
        AuDebugOn(!hinode || !events);
 
327
        if (unlikely(!hinode->hi_inode || !hinode->hi_notify))
 
328
                return;
 
329
        LKTRTrace("hi%lu\n", hinode->hi_inode->i_ino);
 
330
#ifdef DbgInotify
 
331
        AuDbg("hi%lu, 0x%x\n", hinode->hi_inode->i_ino, events);
 
332
#endif
 
333
        AuDebugOn(!hinode->hi_notify);
 
334
 
 
335
        ign = hinode->hi_notify->hin_ignore;
 
336
        for (i = 0; i < au_hin_nignore; i++)
 
337
                if (1U << i & events)
 
338
                        atomic_dec_return(ign + i);
 
339
}
 
340
 
 
341
/* ---------------------------------------------------------------------- */
 
342
 
 
343
static char *in_name(u32 mask)
 
344
{
 
345
#ifdef CONFIG_AUFS_DEBUG
 
346
#define test_ret(flag)  if (mask & flag) return #flag;
 
347
        test_ret(IN_ACCESS);
 
348
        test_ret(IN_MODIFY);
 
349
        test_ret(IN_ATTRIB);
 
350
        test_ret(IN_CLOSE_WRITE);
 
351
        test_ret(IN_CLOSE_NOWRITE);
 
352
        test_ret(IN_OPEN);
 
353
        test_ret(IN_MOVED_FROM);
 
354
        test_ret(IN_MOVED_TO);
 
355
        test_ret(IN_CREATE);
 
356
        test_ret(IN_DELETE);
 
357
        test_ret(IN_DELETE_SELF);
 
358
        test_ret(IN_MOVE_SELF);
 
359
        test_ret(IN_UNMOUNT);
 
360
        test_ret(IN_Q_OVERFLOW);
 
361
        test_ret(IN_IGNORED);
 
362
        return "";
 
363
#undef test_ret
 
364
#else
 
365
        return "??";
 
366
#endif
 
367
}
 
368
 
 
369
/* ---------------------------------------------------------------------- */
 
370
 
 
371
static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
 
372
                                           struct inode *dir)
 
373
{
 
374
        struct dentry *dentry, *d, *parent;
 
375
        struct qstr *dname;
 
376
 
 
377
        LKTRTrace("%.*s, dir%lu\n", nlen, name, dir->i_ino);
 
378
 
 
379
        parent = d_find_alias(dir);
 
380
        if (!parent)
 
381
                return NULL;
 
382
 
 
383
        dentry = NULL;
 
384
        spin_lock(&dcache_lock);
 
385
        list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
 
386
                LKTRTrace("%.*s\n", AuDLNPair(d));
 
387
                dname = &d->d_name;
 
388
                if (dname->len != nlen || memcmp(dname->name, name, nlen))
 
389
                        continue;
 
390
                if (!atomic_read(&d->d_count)) {
 
391
                        spin_lock(&d->d_lock);
 
392
                        __d_drop(d);
 
393
                        spin_unlock(&d->d_lock);
 
394
                        continue;
 
395
                }
 
396
 
 
397
                dentry = dget(d);
 
398
                break;
 
399
        }
 
400
        spin_unlock(&dcache_lock);
 
401
        dput(parent);
 
402
 
 
403
        if (dentry)
 
404
                di_write_lock_child(dentry);
 
405
        return dentry;
 
406
}
 
407
 
 
408
static struct inode *lookup_wlock_by_ino(struct super_block *sb,
 
409
                                         aufs_bindex_t bindex, ino_t h_ino)
 
410
{
 
411
        struct inode *inode;
 
412
        struct au_xino_entry xinoe;
 
413
        int err;
 
414
 
 
415
        LKTRTrace("b%d, hi%lu\n", bindex, h_ino);
 
416
        AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
 
417
 
 
418
        inode = NULL;
 
419
        err = au_xino_read(sb, bindex, h_ino, &xinoe);
 
420
        if (!err && xinoe.ino)
 
421
                inode = ilookup(sb, xinoe.ino);
 
422
        if (!inode)
 
423
                goto out;
 
424
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
 
425
                AuWarn("wrong root branch\n");
 
426
                iput(inode);
 
427
                inode = NULL;
 
428
                goto out;
 
429
        }
 
430
 
 
431
        ii_write_lock_child(inode);
 
432
#if 0 // debug
 
433
        if (au_iigen(inode) == au_sigen(sb))
 
434
                goto out; /* success */
 
435
 
 
436
        err = au_refresh_hinode_self(inode);
 
437
        if (!err)
 
438
                goto out; /* success */
 
439
 
 
440
        AuIOErr1("err %d ignored, but ino will be broken\n", err);
 
441
        ii_write_unlock(inode);
 
442
        iput(inode);
 
443
        inode = NULL;
 
444
#endif
 
445
 
 
446
 out:
 
447
        return inode;
 
448
}
 
449
 
 
450
static int hin_xino(struct inode *inode, struct inode *h_inode)
 
451
{
 
452
        int err;
 
453
        aufs_bindex_t bindex, bend, bfound, bstart;
 
454
        struct inode *h_i;
 
455
 
 
456
        LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino);
 
457
 
 
458
        err = 0;
 
459
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
 
460
                AuWarn("branch root dir was changed\n");
 
461
                goto out;
 
462
        }
 
463
 
 
464
        bfound = -1;
 
465
        bend = au_ibend(inode);
 
466
        bstart = au_ibstart(inode);
 
467
#if 0
 
468
        if (bindex == bend) {
 
469
                /* keep this ino in rename case */
 
470
                goto out;
 
471
        }
 
472
#endif
 
473
        for (bindex = bstart; bindex <= bend; bindex++) {
 
474
                if (au_h_iptr(inode, bindex) == h_inode) {
 
475
                        bfound = bindex;
 
476
                        break;
 
477
                }
 
478
        }
 
479
        if (bfound < 0)
 
480
                goto out;
 
481
 
 
482
        for (bindex = bstart; bindex <= bend; bindex++) {
 
483
                h_i = au_h_iptr(inode, bindex);
 
484
                if (h_i)
 
485
                        err = au_xino_write0(inode->i_sb, bindex, h_i->i_ino,
 
486
                                             0);
 
487
                /* ignore this error */
 
488
                /* bad action? */
 
489
        }
 
490
 
 
491
        /* children inode number will be broken */
 
492
 
 
493
 out:
 
494
        AuTraceErr(err);
 
495
        return err;
 
496
}
 
497
 
 
498
static int hin_gen_tree(struct dentry *dentry)
 
499
{
 
500
        int err, i, j, ndentry;
 
501
        struct au_dcsub_pages dpages;
 
502
        struct au_dpage *dpage;
 
503
        struct dentry **dentries;
 
504
 
 
505
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
 
506
 
 
507
        err = au_dpages_init(&dpages, GFP_TEMPORARY);
 
508
        if (unlikely(err))
 
509
                goto out;
 
510
        err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
 
511
        if (unlikely(err))
 
512
                goto out_dpages;
 
513
 
 
514
        for (i = 0; i < dpages.ndpage; i++) {
 
515
                dpage = dpages.dpages + i;
 
516
                dentries = dpage->dentries;
 
517
                ndentry = dpage->ndentry;
 
518
                for (j = 0; j < ndentry; j++) {
 
519
                        struct dentry *d;
 
520
                        d = dentries[j];
 
521
                        LKTRTrace("%.*s\n", AuDLNPair(d));
 
522
                        if (IS_ROOT(d))
 
523
                                continue;
 
524
 
 
525
                        d_drop(d);
 
526
                        au_digen_dec(d);
 
527
                        if (d->d_inode)
 
528
                                //reset children xino? cached children only?
 
529
                                au_iigen_dec(d->d_inode);
 
530
                }
 
531
        }
 
532
 
 
533
 out_dpages:
 
534
        au_dpages_free(&dpages);
 
535
 
 
536
        /* discard children */
 
537
        dentry_unhash(dentry);
 
538
        dput(dentry);
 
539
 out:
 
540
        AuTraceErr(err);
 
541
        return err;
 
542
}
 
543
 
 
544
/*
 
545
 * return 0 if processed.
 
546
 */
 
547
static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
 
548
                            const unsigned int isdir)
 
549
{
 
550
        int err;
 
551
        struct dentry *d;
 
552
        struct qstr *dname;
 
553
 
 
554
        LKTRTrace("%.*s, i%lu\n", nlen, name, inode->i_ino);
 
555
 
 
556
        err = 1;
 
557
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
 
558
                AuWarn("branch root dir was changed\n");
 
559
                err = 0;
 
560
                goto out;
 
561
        }
 
562
 
 
563
        if (!isdir) {
 
564
                AuDebugOn(!name);
 
565
                au_iigen_dec(inode);
 
566
                spin_lock(&dcache_lock);
 
567
                list_for_each_entry(d, &inode->i_dentry, d_alias) {
 
568
                        dname = &d->d_name;
 
569
                        if (dname->len != nlen
 
570
                            && memcmp(dname->name, name, nlen))
 
571
                                continue;
 
572
                        err = 0;
 
573
                        spin_lock(&d->d_lock);
 
574
                        __d_drop(d);
 
575
                        au_digen_dec(d);
 
576
                        spin_unlock(&d->d_lock);
 
577
                        break;
 
578
                }
 
579
                spin_unlock(&dcache_lock);
 
580
        } else {
 
581
                au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS);
 
582
                d = d_find_alias(inode);
 
583
                if (!d) {
 
584
                        au_iigen_dec(inode);
 
585
                        goto out;
 
586
                }
 
587
 
 
588
                dname = &d->d_name;
 
589
                if (dname->len == nlen && !memcmp(dname->name, name, nlen))
 
590
                        err = hin_gen_tree(d);
 
591
                dput(d);
 
592
        }
 
593
 
 
594
 out:
 
595
        AuTraceErr(err);
 
596
        return err;
 
597
}
 
598
 
 
599
static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir)
 
600
{
 
601
        int err;
 
602
        struct inode *inode;
 
603
 
 
604
        LKTRTrace("%.*s\n", AuDLNPair(dentry));
 
605
 
 
606
        inode = dentry->d_inode;
 
607
        if (IS_ROOT(dentry)
 
608
            //|| (inode && inode->i_ino == AUFS_ROOT_INO)
 
609
                ) {
 
610
                AuWarn("branch root dir was changed\n");
 
611
                return 0;
 
612
        }
 
613
 
 
614
        err = 0;
 
615
        if (!isdir) {
 
616
                d_drop(dentry);
 
617
                au_digen_dec(dentry);
 
618
                if (inode)
 
619
                        au_iigen_dec(inode);
 
620
        } else {
 
621
                au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS);
 
622
                if (inode)
 
623
                        err = hin_gen_tree(dentry);
 
624
        }
 
625
 
 
626
        AuTraceErr(err);
 
627
        return err;
 
628
}
 
629
 
 
630
static void hin_attr(struct inode *inode, struct inode *h_inode)
 
631
{
 
632
        struct dentry *h_dentry;
 
633
 
 
634
        LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino);
 
635
 
 
636
        if (au_h_iptr(inode, au_ibstart(inode)) != h_inode)
 
637
                return;
 
638
 
 
639
        h_dentry = d_find_alias(h_inode);
 
640
        if (h_dentry) {
 
641
                au_update_fuse_h_inode(NULL, h_dentry);
 
642
                /* ignore an error*/
 
643
                dput(h_dentry);
 
644
        }
 
645
 
 
646
        au_cpup_attr_all(inode);
 
647
}
 
648
 
 
649
/* ---------------------------------------------------------------------- */
 
650
 
 
651
/* hinotify job flags */
 
652
#define AuHinJob_XINO0  1
 
653
#define AuHinJob_GEN    (1 << 1)
 
654
#define AuHinJob_DIRENT (1 << 2)
 
655
#define AuHinJob_ATTR   (1 << 3)
 
656
#define AuHinJob_ISDIR  (1 << 4)
 
657
#define AuHinJob_TRYXINO0 (1 << 5)
 
658
#define AuHinJob_MNTPNT (1 << 6)
 
659
#define au_ftest_hinjob(flags, name)    ((flags) & AuHinJob_##name)
 
660
#define au_fset_hinjob(flags, name)     { (flags) |= AuHinJob_##name; }
 
661
#define au_fclr_hinjob(flags, name)     { (flags) &= ~AuHinJob_##name; }
 
662
 
 
663
struct hin_job_args {
 
664
        unsigned int flags;
 
665
        struct inode *inode, *h_inode, *dir, *h_dir;
 
666
        struct dentry *dentry;
 
667
        char *h_name;
 
668
        int h_nlen;
 
669
};
 
670
 
 
671
static int hin_job(struct hin_job_args *a)
 
672
{
 
673
        const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR);
 
674
 
 
675
        /* reset xino */
 
676
        if (au_ftest_hinjob(a->flags, XINO0) && a->inode)
 
677
                hin_xino(a->inode, a->h_inode);
 
678
        /* ignore this error */
 
679
 
 
680
        if (au_ftest_hinjob(a->flags, TRYXINO0)
 
681
            && a->inode
 
682
            && a->h_inode) {
 
683
                mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
 
684
#if 0
 
685
                au_debug_on();
 
686
                AuDbgInode(a->inode);
 
687
                AuDbgInode(a->h_inode);
 
688
                au_debug_off();
 
689
#endif
 
690
                if (!a->h_inode->i_nlink)
 
691
                        hin_xino(a->inode, a->h_inode);
 
692
                /* ignore this error */
 
693
                mutex_unlock(&a->h_inode->i_mutex);
 
694
        }
 
695
 
 
696
        /* make the generation obsolete */
 
697
        if (au_ftest_hinjob(a->flags, GEN)) {
 
698
                int err = -1;
 
699
                if (a->inode)
 
700
                        err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode,
 
701
                                               isdir);
 
702
                if (err && a->dentry)
 
703
                        hin_gen_by_name(a->dentry, isdir);
 
704
                /* ignore this error */
 
705
        }
 
706
 
 
707
        /* make dir entries obsolete */
 
708
        if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) {
 
709
                struct au_vdir *vdir;
 
710
                IiMustWriteLock(a->inode);
 
711
                vdir = au_ivdir(a->inode);
 
712
                if (vdir)
 
713
                        vdir->vd_jiffy = 0;
 
714
                //IMustLock(a->inode);
 
715
                //a->inode->i_version++;
 
716
        }
 
717
 
 
718
        /* update the attr */
 
719
        if (au_ftest_hinjob(a->flags, ATTR) && a->inode && a->h_inode)
 
720
                hin_attr(a->inode, a->h_inode);
 
721
 
 
722
        /* can do nothing but warn */
 
723
        if (au_ftest_hinjob(a->flags, MNTPNT)
 
724
            && a->dentry
 
725
            && d_mountpoint(a->dentry))
 
726
                AuWarn("mount-point %.*s is removed or renamed\n",
 
727
                       AuDLNPair(a->dentry));
 
728
 
 
729
        return 0;
 
730
}
 
731
 
 
732
/* ---------------------------------------------------------------------- */
 
733
 
 
734
enum { CHILD, PARENT };
 
735
struct postproc_args {
 
736
        struct inode *h_dir, *dir, *h_child_inode;
 
737
        u32 mask;
 
738
        unsigned int flags[2];
 
739
        unsigned int h_child_nlen;
 
740
        char h_child_name[];
 
741
};
 
742
 
 
743
static void postproc(void *_args)
 
744
{
 
745
        struct postproc_args *a = _args;
 
746
        struct super_block *sb;
 
747
        aufs_bindex_t bindex, bend, bfound;
 
748
        int xino, err;
 
749
        struct inode *inode;
 
750
        ino_t h_ino;
 
751
        struct hin_job_args args;
 
752
        struct dentry *dentry;
 
753
        struct au_sbinfo *sbinfo;
 
754
 
 
755
        AuDebugOn(!_args);
 
756
        AuDebugOn(!a->h_dir);
 
757
        AuDebugOn(!a->dir);
 
758
        AuDebugOn(!a->mask);
 
759
        //au_debug_on();
 
760
        LKTRTrace("mask 0x%x %s, i%lu, hi%lu, hci%lu\n",
 
761
                  a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino,
 
762
                  a->h_child_inode ? a->h_child_inode->i_ino : 0);
 
763
 
 
764
        inode = NULL;
 
765
        dentry = NULL;
 
766
        // do not lock here because of d_revalidate() may cause a deadlock.
 
767
        //mutex_lock(&a->dir->i_mutex);
 
768
        sb = a->dir->i_sb;
 
769
        AuDebugOn(!sb);
 
770
        sbinfo = au_sbi(sb);
 
771
        AuDebugOn(!sbinfo);
 
772
        /* big aufs lock */
 
773
        si_noflush_write_lock(sb);
 
774
 
 
775
        ii_read_lock_parent(a->dir);
 
776
        bfound = -1;
 
777
        bend = au_ibend(a->dir);
 
778
        for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
 
779
                if (au_h_iptr(a->dir, bindex) == a->h_dir) {
 
780
                        bfound = bindex;
 
781
                        break;
 
782
                }
 
783
        ii_read_unlock(a->dir);
 
784
        if (unlikely(bfound < 0))
 
785
                goto out;
 
786
 
 
787
        xino = !!au_opt_test(au_mntflags(sb), XINO);
 
788
        h_ino = 0;
 
789
        if (a->h_child_inode)
 
790
                h_ino = a->h_child_inode->i_ino;
 
791
        //AuDbg("here\n");
 
792
 
 
793
        if (a->h_child_nlen
 
794
            && (au_ftest_hinjob(a->flags[CHILD], GEN)
 
795
                || au_ftest_hinjob(a->flags[CHILD], MNTPNT)))
 
796
                dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
 
797
                                              a->dir);
 
798
        //AuDbg("here\n");
 
799
        if (dentry)
 
800
                inode = dentry->d_inode;
 
801
        if (xino && !inode && h_ino
 
802
            && (au_ftest_hinjob(a->flags[CHILD], XINO0)
 
803
                || au_ftest_hinjob(a->flags[CHILD], TRYXINO0)
 
804
                || au_ftest_hinjob(a->flags[CHILD], GEN)
 
805
                || au_ftest_hinjob(a->flags[CHILD], ATTR)))
 
806
                inode = lookup_wlock_by_ino(sb, bfound, h_ino);
 
807
        //AuDbg("here\n");
 
808
 
 
809
        args.flags = a->flags[CHILD];
 
810
        args.dentry = dentry;
 
811
        args.inode = inode;
 
812
        args.h_inode = a->h_child_inode;
 
813
        args.dir = a->dir;
 
814
        args.h_dir = a->h_dir;
 
815
        args.h_name = a->h_child_name;
 
816
        args.h_nlen = a->h_child_nlen;
 
817
        err = hin_job(&args);
 
818
        if (dentry) {
 
819
                di_write_unlock(dentry);
 
820
                dput(dentry);
 
821
        } else if (inode) {
 
822
                ii_write_unlock(inode);
 
823
                iput(inode);
 
824
        }
 
825
        //AuDbg("here\n");
 
826
 
 
827
        ii_write_lock_parent(a->dir);
 
828
        args.flags = a->flags[PARENT];
 
829
        args.dentry = NULL;
 
830
        args.inode = a->dir;
 
831
        args.h_inode = a->h_dir;
 
832
        args.dir = NULL;
 
833
        args.h_dir = NULL;
 
834
        args.h_name = NULL;
 
835
        args.h_nlen = 0;
 
836
        err = hin_job(&args);
 
837
        ii_write_unlock(a->dir);
 
838
        //AuDbg("here\n");
 
839
 
 
840
 out:
 
841
        si_write_unlock(sb);
 
842
        //mutex_unlock(&a->dir->i_mutex);
 
843
        au_nwt_dec(&sbinfo->si_nowait);
 
844
 
 
845
        iput(a->h_child_inode);
 
846
        iput(a->h_dir);
 
847
        iput(a->dir);
 
848
        kfree(a);
 
849
        //au_debug_off();
 
850
}
 
851
 
 
852
//todo: endian?
 
853
#ifndef ilog2
 
854
#define ilog2(n) ffz(~(n))
 
855
#endif
 
856
 
 
857
static void aufs_inotify(struct inotify_watch *watch, u32 wd, u32 mask,
 
858
                         u32 cookie, const char *h_child_name,
 
859
                         struct inode *h_child_inode)
 
860
{
 
861
        struct au_hinotify *hinotify;
 
862
        struct postproc_args *args;
 
863
        int len, wkq_err, isdir, isroot, wh, idx;
 
864
        char *p;
 
865
        struct inode *dir;
 
866
        unsigned int flags[2];
 
867
        struct super_block *sb;
 
868
        atomic_t *cnt;
 
869
 
 
870
        LKTRTrace("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n",
 
871
                  watch->inode->i_ino, wd, mask, in_name(mask), cookie,
 
872
                  h_child_name ? h_child_name : "",
 
873
                  h_child_inode ? h_child_inode->i_ino : 0);
 
874
#if 0 //defined(ForceInotify) || defined(DbgInotify)
 
875
        AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n",
 
876
              watch->inode->i_ino, wd, mask, in_name(mask), cookie,
 
877
              h_child_name ? h_child_name : "",
 
878
              h_child_inode ? h_child_inode->i_ino : 0);
 
879
#endif
 
880
        /* if IN_UNMOUNT happens, there must be another bug */
 
881
        if (mask & (IN_IGNORED | IN_UNMOUNT)) {
 
882
                //WARN_ON(watch->inode->i_ino == 15);
 
883
                put_inotify_watch(watch);
 
884
                return;
 
885
        }
 
886
 
 
887
#ifdef DbgInotify
 
888
        if (!h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME))
 
889
                AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s,"
 
890
                      " hi%lu\n",
 
891
                      watch->inode->i_ino, wd, mask, in_name(mask), cookie,
 
892
                      h_child_name ? h_child_name : "",
 
893
                      h_child_inode ? h_child_inode->i_ino : 0);
 
894
        //WARN_ON(1);
 
895
#endif
 
896
 
 
897
        hinotify = container_of(watch, struct au_hinotify, hin_watch);
 
898
        AuDebugOn(!hinotify || !hinotify->hin_aufs_inode);
 
899
        idx = ilog2(mask & IN_ALL_EVENTS);
 
900
        AuDebugOn(au_hin_nignore <= idx);
 
901
        cnt = hinotify->hin_ignore + idx;
 
902
        if (0 <= atomic_dec_return(cnt))
 
903
                return;
 
904
        atomic_inc_return(cnt);
 
905
#ifdef DbgInotify
 
906
#if 0
 
907
        AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n",
 
908
              watch->inode->i_ino, wd, mask, in_name(mask), cookie,
 
909
              h_child_name ? h_child_name : "",
 
910
              h_child_inode ? h_child_inode->i_ino : 0);
 
911
#endif
 
912
#if 0
 
913
        if (!h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME))
 
914
                WARN_ON(1);
 
915
#endif
 
916
#endif
 
917
 
 
918
        dir = igrab(hinotify->hin_aufs_inode);
 
919
        if (!dir)
 
920
                return;
 
921
        isroot = (dir->i_ino == AUFS_ROOT_INO);
 
922
        len = 0;
 
923
        wh = 0;
 
924
        if (h_child_name) {
 
925
                len = strlen(h_child_name);
 
926
                if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
 
927
                        h_child_name += AUFS_WH_PFX_LEN;
 
928
                        len -= AUFS_WH_PFX_LEN;
 
929
                        wh = 1;
 
930
                }
 
931
        }
 
932
 
 
933
        isdir = 0;
 
934
        if (h_child_inode)
 
935
                isdir = !!S_ISDIR(h_child_inode->i_mode);
 
936
        flags[PARENT] = AuHinJob_ISDIR;
 
937
        flags[CHILD] = 0;
 
938
        if (isdir)
 
939
                flags[CHILD] = AuHinJob_ISDIR;
 
940
        switch (mask & IN_ALL_EVENTS) {
 
941
        case IN_MODIFY:
 
942
                /*FALLTHROUGH*/
 
943
        case IN_ATTRIB:
 
944
                if (h_child_inode) {
 
945
                        if (!wh)
 
946
                                au_fset_hinjob(flags[CHILD], ATTR);
 
947
                } else
 
948
                        au_fset_hinjob(flags[PARENT], ATTR);
 
949
                break;
 
950
 
 
951
                /* IN_MOVED_FROM is the first event in rename(2) */
 
952
        case IN_MOVED_FROM:
 
953
        case IN_MOVED_TO:
 
954
                AuDebugOn(!h_child_name || !h_child_inode);
 
955
                au_fset_hinjob(flags[CHILD], GEN);
 
956
                au_fset_hinjob(flags[CHILD], ATTR);
 
957
                if (1 || isdir)
 
958
                        au_fset_hinjob(flags[CHILD], XINO0);
 
959
                au_fset_hinjob(flags[CHILD], MNTPNT);
 
960
 
 
961
                au_fset_hinjob(flags[PARENT], ATTR);
 
962
                au_fset_hinjob(flags[PARENT], DIRENT);
 
963
                break;
 
964
 
 
965
        case IN_CREATE:
 
966
                AuDebugOn(!h_child_name || !h_child_inode);
 
967
                au_fset_hinjob(flags[PARENT], ATTR);
 
968
                au_fset_hinjob(flags[PARENT], DIRENT);
 
969
                au_fset_hinjob(flags[CHILD], GEN);
 
970
                /* hard link */
 
971
                if (!isdir && h_child_inode->i_nlink > 1)
 
972
                        au_fset_hinjob(flags[CHILD], ATTR);
 
973
                break;
 
974
 
 
975
        case IN_DELETE:
 
976
                /*
 
977
                 * aufs never be able to get this child inode.
 
978
                 * revalidation should be in d_revalidate()
 
979
                 * by checking i_nlink, i_generation or d_unhashed().
 
980
                 */
 
981
                AuDebugOn(!h_child_name);
 
982
                au_fset_hinjob(flags[PARENT], ATTR);
 
983
                au_fset_hinjob(flags[PARENT], DIRENT);
 
984
                au_fset_hinjob(flags[CHILD], GEN);
 
985
                au_fset_hinjob(flags[CHILD], TRYXINO0);
 
986
                au_fset_hinjob(flags[CHILD], MNTPNT);
 
987
                break;
 
988
 
 
989
        case IN_DELETE_SELF:
 
990
                if (!isroot)
 
991
                        au_fset_hinjob(flags[PARENT], GEN);
 
992
                /*FALLTHROUGH*/
 
993
 
 
994
        case IN_MOVE_SELF:
 
995
                /*
 
996
                 * when an inotify is set to an aufs inode,
 
997
                 * such inode can be isolated and this event can be fired
 
998
                 * solely.
 
999
                 */
 
1000
                AuDebugOn(h_child_name || h_child_inode);
 
1001
                if (unlikely(isroot)) {
 
1002
                        AuWarn("root branch was moved\n");
 
1003
                        iput(dir);
 
1004
                        return;
 
1005
                }
 
1006
#if 0
 
1007
                return;
 
1008
#else
 
1009
                au_fset_hinjob(flags[PARENT], XINO0);
 
1010
                au_fset_hinjob(flags[PARENT], GEN);
 
1011
                au_fset_hinjob(flags[PARENT], ATTR);
 
1012
                au_fset_hinjob(flags[PARENT], DIRENT);
 
1013
                //au_fset_hinjob(flags[PARENT], MNTPNT);
 
1014
                break;
 
1015
#endif
 
1016
        case IN_ACCESS:
 
1017
        default:
 
1018
                AuDebugOn(1);
 
1019
        }
 
1020
 
 
1021
#if 0 //def DbgInotify
 
1022
        WARN_ON(1);
 
1023
#endif
 
1024
 
 
1025
        if (wh)
 
1026
                h_child_inode = NULL;
 
1027
 
 
1028
        /* iput() and kfree() will be called in postproc() */
 
1029
        /*
 
1030
         * inotify_mutex is already acquired and kmalloc/prune_icache may lock
 
1031
         * iprune_mutex. strange.
 
1032
         */
 
1033
        lockdep_off();
 
1034
        args = kmalloc(sizeof(*args) + len + 1, GFP_TEMPORARY);
 
1035
        lockdep_on();
 
1036
        if (unlikely(!args)) {
 
1037
                AuErr1("no memory\n");
 
1038
                iput(dir);
 
1039
                return;
 
1040
        }
 
1041
        args->flags[PARENT] = flags[PARENT];
 
1042
        args->flags[CHILD] = flags[CHILD];
 
1043
        args->mask = mask;
 
1044
        args->dir = dir;
 
1045
        args->h_dir = igrab(watch->inode);
 
1046
        if (h_child_inode)
 
1047
                igrab(h_child_inode);
 
1048
        args->h_child_inode = h_child_inode;
 
1049
        args->h_child_nlen = len;
 
1050
        if (len) {
 
1051
                p = (void *)args;
 
1052
                p += sizeof(*args);
 
1053
                memcpy(p, h_child_name, len + 1);
 
1054
        }
 
1055
 
 
1056
        sb = dir->i_sb;
 
1057
        au_nwt_inc(&au_sbi(sb)->si_nowait);
 
1058
        lockdep_off();
 
1059
        wkq_err = au_wkq_nowait(postproc, args, sb, /*dlgt*/0);
 
1060
        lockdep_on();
 
1061
        if (unlikely(wkq_err)) {
 
1062
                AuErr("wkq %d\n", wkq_err);
 
1063
                au_nwt_dec(&au_sbi(sb)->si_nowait);
 
1064
        }
 
1065
}
 
1066
 
 
1067
static void aufs_inotify_destroy(struct inotify_watch *watch)
 
1068
{
 
1069
        return;
 
1070
}
 
1071
 
 
1072
static struct inotify_operations aufs_inotify_ops = {
 
1073
        .handle_event   = aufs_inotify,
 
1074
        .destroy_watch  = aufs_inotify_destroy
 
1075
};
 
1076
 
 
1077
/* ---------------------------------------------------------------------- */
 
1078
 
 
1079
static void au_hin_destroy_cache(void)
 
1080
{
 
1081
        kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]);
 
1082
        au_cachep[AuCache_HINOTIFY] = NULL;
 
1083
}
 
1084
 
 
1085
int __init au_inotify_init(void)
 
1086
{
 
1087
        au_hin_nignore = 6;
 
1088
        while (1U << au_hin_nignore < AuInMask)
 
1089
                au_hin_nignore++;
 
1090
        //AuDbg("au_hin_nignore %d\n", au_hin_nignore);
 
1091
        AuDebugOn(au_hin_nignore != 10);
 
1092
 
 
1093
        in_handle = ERR_PTR(-ENOMEM);
 
1094
        au_cachep[AuCache_HINOTIFY]
 
1095
                = AuCacheX(au_hinotify, sizeof(atomic_t) * au_hin_nignore);
 
1096
        if (unlikely(!au_cachep[AuCache_HINOTIFY]))
 
1097
                goto out;
 
1098
 
 
1099
        in_handle = inotify_init(&aufs_inotify_ops);
 
1100
        if (!IS_ERR(in_handle))
 
1101
                return 0;
 
1102
 
 
1103
        au_hin_destroy_cache();
 
1104
 out:
 
1105
        AuTraceErrPtr(in_handle);
 
1106
        return PTR_ERR(in_handle);
 
1107
}
 
1108
 
 
1109
void au_inotify_fin(void)
 
1110
{
 
1111
        inotify_destroy(in_handle);
 
1112
        if (au_cachep[AuCache_HINOTIFY])
 
1113
                au_hin_destroy_cache();
 
1114
}