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

« back to all changes in this revision

Viewing changes to fs/aufs/hinotify.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2007-12-15 23:32:51 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20071215233251-2vgs2lmg8mai5d9e
Tags: 0+20071211-1ubuntu1
* Merge from debian unstable (LP: #175705), remaining changes:
  - Fix for Ubuntu Kernels (updated)
* patches/01_vserver.dpatch: Removed
* patches/06_ubuntu.dpatch: Added (update of ubuntu patch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 */
18
18
 
19
 
/* $Id: hinotify.c,v 1.22 2007/06/04 02:15:44 sfjro Exp $ */
 
19
/* $Id: hinotify.c,v 1.38 2007/12/10 01:19:07 sfjro Exp $ */
20
20
 
21
21
#include "aufs.h"
22
22
 
 
23
/* inotify events */
 
24
static const __u32 AuInMask = (IN_MOVE | IN_DELETE | IN_CREATE
 
25
                               /* | IN_ACCESS */
 
26
                               | IN_MODIFY | IN_ATTRIB
 
27
                               | IN_DELETE_SELF | IN_MOVE_SELF);
23
28
static struct inotify_handle *in_handle;
24
 
static const __u32 in_mask = (IN_MOVE | IN_DELETE | IN_CREATE /* | IN_ACCESS */
25
 
                              | IN_MODIFY | IN_ATTRIB
26
 
                              | IN_DELETE_SELF | IN_MOVE_SELF);
27
29
 
28
 
int alloc_hinotify(struct aufs_hinode *hinode, struct inode *inode,
29
 
                   struct inode *hidden_inode)
 
30
int au_hin_alloc(struct aufs_hinode *hinode, struct inode *inode,
 
31
                 struct inode *hidden_inode)
30
32
{
31
 
        int err;
 
33
        int err, i;
32
34
        struct aufs_hinotify *hin;
33
35
        s32 wd;
34
36
 
35
37
        LKTRTrace("i%lu, hi%lu\n", inode->i_ino, hidden_inode->i_ino);
36
38
 
37
39
        err = -ENOMEM;
38
 
        hin = cache_alloc_hinotify();
 
40
        hin = au_cache_alloc_hinotify();
39
41
        if (hin) {
40
42
                AuDebugOn(hinode->hi_notify);
41
43
                hinode->hi_notify = hin;
42
44
                hin->hin_aufs_inode = inode;
 
45
                for (i = 0; i < au_hin_nignore; i++)
 
46
                        atomic_set(hin->hin_ignore + i, 0);
 
47
 
43
48
                inotify_init_watch(&hin->hin_watch);
44
49
                wd = inotify_add_watch(in_handle, &hin->hin_watch, hidden_inode,
45
 
                                       in_mask);
 
50
                                       AuInMask);
46
51
                if (wd >= 0)
47
52
                        return 0; /* success */
48
53
 
49
54
                err = wd;
50
55
                put_inotify_watch(&hin->hin_watch);
51
 
                cache_free_hinotify(hin);
 
56
                au_cache_free_hinotify(hin);
52
57
                hinode->hi_notify = NULL;
53
58
        }
54
59
 
55
 
        TraceErr(err);
 
60
        AuTraceErr(err);
56
61
        return err;
57
62
}
58
63
 
59
 
void do_free_hinotify(struct aufs_hinode *hinode)
 
64
void au_hin_free(struct aufs_hinode *hinode)
60
65
{
61
66
        int err;
62
67
        struct aufs_hinotify *hin;
63
68
 
64
 
        TraceEnter();
 
69
        AuTraceEnter();
65
70
 
66
71
        hin = hinode->hi_notify;
67
 
        if (hin) {
 
72
        if (unlikely(hin)) {
68
73
                err = 0;
69
74
                if (atomic_read(&hin->hin_watch.count))
70
75
                        err = inotify_rm_watch(in_handle, &hin->hin_watch);
71
76
 
72
77
                if (!err) {
73
 
                        cache_free_hinotify(hin);
 
78
                        au_cache_free_hinotify(hin);
74
79
                        hinode->hi_notify = NULL;
75
80
                } else
76
 
                        IOErr1("failed inotify_rm_watch() %d\n", err);
 
81
                        AuIOErr1("failed inotify_rm_watch() %d\n", err);
77
82
        }
78
83
}
79
84
 
81
86
 
82
87
static void ctl_hinotify(struct aufs_hinode *hinode, const __u32 mask)
83
88
{
84
 
        struct inode *hi;
 
89
        struct inode *h_inode;
85
90
        struct inotify_watch *watch;
86
91
 
87
 
        hi = hinode->hi_inode;
88
 
        LKTRTrace("hi%lu, sb %p, 0x%x\n", hi->i_ino, hi->i_sb, mask);
89
 
        if (0 && !strcmp(current->comm, "link"))
90
 
                dump_stack();
91
 
        IMustLock(hi);
 
92
        h_inode = hinode->hi_inode;
 
93
        LKTRTrace("hi%lu, sb %p, 0x%x\n", h_inode->i_ino, h_inode->i_sb, mask);
 
94
        IMustLock(h_inode);
92
95
        if (!hinode->hi_notify)
93
96
                return;
94
97
 
95
98
        watch = &hinode->hi_notify->hin_watch;
96
 
#if 0
 
99
#if 0 // temp
97
100
        {
98
101
                u32 wd;
99
 
                wd = inotify_find_update_watch(in_handle, hi, mask);
100
 
                TraceErr(wd);
101
 
                // ignore an err;
 
102
                wd = inotify_find_update_watch(in_handle, h_inode, mask);
 
103
                AuTraceErr(wd);
 
104
                /* ignore an err; */
102
105
        }
103
106
#else
 
107
        /* struct inotify_handle is hidden */
 
108
        mutex_lock(&h_inode->inotify_mutex);
 
109
        //mutex_lock(&watch->ih->mutex);
104
110
        watch->mask = mask;
105
 
        smp_mb();
 
111
        //mutex_unlock(&watch->ih->mutex);
 
112
        mutex_unlock(&h_inode->inotify_mutex);
106
113
#endif
107
114
        LKTRTrace("watch %p, mask %u\n", watch, watch->mask);
108
115
}
109
116
 
110
117
#define suspend_hinotify(hi)    ctl_hinotify(hi, 0)
111
 
#define resume_hinotify(hi)     ctl_hinotify(hi, in_mask)
 
118
#define resume_hinotify(hi)     ctl_hinotify(hi, AuInMask)
112
119
 
113
 
void do_hdir_lock(struct inode *h_dir, struct inode *dir, aufs_bindex_t bindex,
114
 
                  unsigned int lsc)
 
120
void au_do_hdir_lock(struct inode *h_dir, struct inode *dir,
 
121
                     aufs_bindex_t bindex, unsigned int lsc)
115
122
{
116
123
        struct aufs_hinode *hinode;
117
124
 
120
127
        hinode = itoii(dir)->ii_hinode + bindex;
121
128
        AuDebugOn(h_dir != hinode->hi_inode);
122
129
 
123
 
        hi_lock(h_dir, lsc);
124
 
        if (1 /* unlikely(au_flag_test(dir->i_sb, AuFlag_UDBA_HINOTIFY) */)
125
 
                suspend_hinotify(hinode);
 
130
        vfsub_i_lock_nested(h_dir, lsc);
 
131
        suspend_hinotify(hinode);
126
132
}
127
133
 
128
134
void hdir_unlock(struct inode *h_dir, struct inode *dir, aufs_bindex_t bindex)
134
140
        hinode = itoii(dir)->ii_hinode + bindex;
135
141
        AuDebugOn(h_dir != hinode->hi_inode);
136
142
 
137
 
        if (1 /* unlikely(au_flag_test(dir->i_sb, AuFlag_UDBA_HINOTIFY) */)
138
 
            resume_hinotify(hinode);
139
 
        i_unlock(h_dir);
 
143
        resume_hinotify(hinode);
 
144
        vfsub_i_unlock(h_dir);
140
145
}
141
146
 
142
147
void hdir_lock_rename(struct dentry **h_parents, struct inode **dirs,
144
149
{
145
150
        struct aufs_hinode *hinode;
146
151
 
147
 
        LKTRTrace("%.*s, %.*s\n", DLNPair(h_parents[0]), DLNPair(h_parents[1]));
 
152
        LKTRTrace("%.*s, %.*s\n",
 
153
                  AuDLNPair(h_parents[0]), AuDLNPair(h_parents[1]));
148
154
 
149
155
        vfsub_lock_rename(h_parents[0], h_parents[1]);
150
156
        hinode = itoii(dirs[0])->ii_hinode + bindex;
162
168
{
163
169
        struct aufs_hinode *hinode;
164
170
 
165
 
        LKTRTrace("%.*s, %.*s\n", DLNPair(h_parents[0]), DLNPair(h_parents[1]));
 
171
        LKTRTrace("%.*s, %.*s\n",
 
172
                  AuDLNPair(h_parents[0]), AuDLNPair(h_parents[1]));
166
173
 
167
174
        hinode = itoii(dirs[0])->ii_hinode + bindex;
168
175
        AuDebugOn(h_parents[0]->d_inode != hinode->hi_inode);
179
186
{
180
187
        aufs_bindex_t bindex, bend;
181
188
        struct inode *hi;
 
189
        struct dentry *iwhdentry;
182
190
 
183
191
        LKTRTrace("i%lu, 0x%x\n", inode->i_ino, flags);
184
192
 
186
194
        for (bindex = ibstart(inode); bindex <= bend; bindex++) {
187
195
                hi = au_h_iptr_i(inode, bindex);
188
196
                if (hi) {
189
 
                        //hi_lock(hi, AUFS_LSC_H_CHILD);
 
197
                        //vfsub_i_lock_nested(hi, AuLsc_I_CHILD);
 
198
                        iwhdentry = au_hi_wh(inode, bindex);
 
199
                        if (unlikely(iwhdentry))
 
200
                                dget(iwhdentry);
190
201
                        igrab(hi);
191
202
                        set_h_iptr(inode, bindex, NULL, 0);
192
 
                        set_h_iptr(inode, bindex, igrab(hi), flags);
 
203
                        set_h_iptr(inode, bindex, igrab(hi),
 
204
                                   flags & ~AUFS_HI_XINO);
193
205
                        iput(hi);
194
 
                        //i_unlock(hi);
 
206
                        dput(iwhdentry);
 
207
                        //vfsub_i_unlock(hi);
195
208
                }
196
209
        }
197
210
}
198
211
 
199
212
/* ---------------------------------------------------------------------- */
200
213
 
 
214
void au_hin_ignore(struct aufs_hinode *hinode, __u32 events)
 
215
{
 
216
        int i;
 
217
        atomic_t *ign;
 
218
 
 
219
        AuDebugOn(!hinode || !events);
 
220
        LKTRTrace("hi%lu, 0x%x\n", hinode->hi_inode->i_ino, events);
 
221
#ifdef DbgInotify
 
222
        AuDbg("hi%lu, 0x%x\n", hinode->hi_inode->i_ino, events);
 
223
#endif
 
224
        AuDebugOn(!hinode->hi_notify);
 
225
 
 
226
        ign = hinode->hi_notify->hin_ignore;
 
227
        for (i = 0; i < au_hin_nignore; i++)
 
228
                if (1U << i & events)
 
229
                        atomic_inc_return(ign + i);
 
230
}
 
231
 
 
232
void au_hin_unignore(struct aufs_hinode *hinode, __u32 events)
 
233
{
 
234
        int i;
 
235
        atomic_t *ign;
 
236
 
 
237
        AuDebugOn(!hinode || !events);
 
238
        LKTRTrace("hi%lu, 0x%x\n", hinode->hi_inode->i_ino, events);
 
239
#ifdef DbgInotify
 
240
        AuDbg("hi%lu, 0x%x\n", hinode->hi_inode->i_ino, events);
 
241
#endif
 
242
        AuDebugOn(!hinode->hi_notify);
 
243
 
 
244
        ign = hinode->hi_notify->hin_ignore;
 
245
        for (i = 0; i < au_hin_nignore; i++)
 
246
                if (1U << i & events)
 
247
                        atomic_dec_return(ign + i);
 
248
}
 
249
 
 
250
/* ---------------------------------------------------------------------- */
 
251
 
 
252
static char *in_name(u32 mask)
 
253
{
201
254
#ifdef CONFIG_AUFS_DEBUG
202
 
static char *in_name(u32 mask)
203
 
{
204
255
#define test_ret(flag)  if (mask & flag) return #flag;
205
256
        test_ret(IN_ACCESS);
206
257
        test_ret(IN_MODIFY);
219
270
        test_ret(IN_IGNORED);
220
271
        return "";
221
272
#undef test_ret
222
 
}
223
273
#else
224
 
#define in_name(m) "??"
 
274
        return "??";
225
275
#endif
226
 
 
227
 
static int dec_gen_by_name(struct inode *dir, const char *_name, u32 mask)
 
276
}
 
277
 
 
278
/* ---------------------------------------------------------------------- */
 
279
 
 
280
static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
 
281
                                           struct inode *dir)
228
282
{
229
 
        int err;
230
 
        struct dentry *parent, *child;
231
 
        struct inode *inode;
 
283
        struct dentry *dentry, *d, *parent;
232
284
        struct qstr *dname;
233
 
        char *name = (void*)_name;
234
 
        unsigned int len;
235
 
 
236
 
        LKTRTrace("i%lu, %s, 0x%x %s\n",
237
 
                  dir->i_ino, name, mask, in_name(mask));
238
 
 
239
 
        err = -1;
 
285
 
 
286
        LKTRTrace("%.*s, dir%lu\n", nlen, name, dir->i_ino);
 
287
 
240
288
        parent = d_find_alias(dir);
241
 
        if (unlikely(!parent))
242
 
                goto out;
 
289
        if (!parent)
 
290
                return NULL;
243
291
 
244
 
#if 0
245
 
        if (unlikely(!memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
246
 
                name += AUFS_WH_PFX_LEN;
247
 
#endif
248
 
        len = strlen(name);
 
292
        dentry = NULL;
249
293
        spin_lock(&dcache_lock);
250
 
        list_for_each_entry(child, &parent->d_subdirs, d_u.d_child) {
251
 
                dname = &child->d_name;
252
 
                if (len == dname->len && !memcmp(dname->name, name, len)) {
253
 
                        if (unlikely(child == dir->i_sb->s_root)) {
254
 
                                err = 0;
255
 
                                break;
256
 
                        }
257
 
 
258
 
                        au_digen_dec(child);
259
 
#if 1
260
 
                        //todo: why both are needed
261
 
                        if (mask & IN_MOVE) {
262
 
                                spin_lock(&child->d_lock);
263
 
                                __d_drop(child);
264
 
                                spin_unlock(&child->d_lock);
265
 
                        }
266
 
#endif
267
 
 
268
 
                        inode = child->d_inode;
269
 
                        if (inode)
270
 
                                au_iigen_dec(inode);
271
 
                        err = !!inode;
272
 
 
273
 
                        // todo: the i_nlink of newly created name by link(2)
274
 
                        // should be updated
275
 
                        // todo: some nfs dentry doesn't notified at deleteing
276
 
                        break;
 
294
        list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
 
295
                LKTRTrace("%.*s\n", AuDLNPair(d));
 
296
                dname = &d->d_name;
 
297
                if (dname->len != nlen
 
298
                    || memcmp(dname->name, name, nlen))
 
299
                        continue;
 
300
                if (!atomic_read(&d->d_count)) {
 
301
                        spin_lock(&d->d_lock);
 
302
                        __d_drop(d);
 
303
                        spin_unlock(&d->d_lock);
 
304
                        continue;
277
305
                }
 
306
 
 
307
                dentry = dget(d);
 
308
                break;
278
309
        }
279
310
        spin_unlock(&dcache_lock);
280
311
        dput(parent);
281
312
 
282
 
 out:
283
 
        TraceErr(err);
284
 
        return err;
285
 
}
286
 
 
 
313
        if (dentry)
 
314
                di_write_lock_child(dentry);
 
315
        return dentry;
 
316
}
 
317
 
 
318
static struct inode *lookup_wlock_by_ino(struct super_block *sb,
 
319
                                         aufs_bindex_t bindex, ino_t h_ino)
 
320
{
 
321
        struct inode *inode;
 
322
        struct xino_entry xinoe;
 
323
        int err;
 
324
 
 
325
        LKTRTrace("b%d, hi%lu\n", bindex, h_ino);
 
326
        AuDebugOn(AuFlag(stosi(sb), f_xino) == AuXino_NONE);
 
327
 
 
328
        inode = NULL;
 
329
        err = xino_read(sb, bindex, h_ino, &xinoe);
 
330
        if (!err && xinoe.ino)
 
331
                inode = ilookup(sb, xinoe.ino);
 
332
        if (!inode)
 
333
                goto out;
 
334
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
 
335
                AuWarn("wrong root branch\n");
 
336
                iput(inode);
 
337
                inode = NULL;
 
338
                goto out;
 
339
        }
 
340
 
 
341
        ii_write_lock_child(inode);
 
342
#if 0 // debug
 
343
        if (au_iigen(inode) == au_sigen(sb))
 
344
                goto out; /* success */
 
345
 
 
346
        err = au_refresh_hinode_self(inode);
 
347
        if (!err)
 
348
                goto out; /* success */
 
349
 
 
350
        AuIOErr1("err %d ignored, but ino will be broken\n", err);
 
351
        ii_write_unlock(inode);
 
352
        iput(inode);
 
353
        inode = NULL;
 
354
#endif
 
355
 
 
356
 out:
 
357
        return inode;
 
358
}
 
359
 
 
360
static int hin_xino(struct inode *inode, struct inode *h_inode)
 
361
{
 
362
        int err;
 
363
        aufs_bindex_t bindex, bend, bfound;
 
364
 
 
365
        LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino);
 
366
 
 
367
        err = 0;
 
368
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
 
369
                AuWarn("branch root dir was changed\n");
 
370
                goto out;
 
371
        }
 
372
 
 
373
        bfound = -1;
 
374
        bend = ibend(inode);
 
375
        for (bindex = ibstart(inode); bindex <= bend; bindex++) {
 
376
                if (au_h_iptr_i(inode, bindex) == h_inode) {
 
377
                        bfound = bindex;
 
378
                        break;
 
379
                }
 
380
        }
 
381
        if (bfound < 0)
 
382
                goto out;
 
383
 
 
384
        err = xino_write0(inode->i_sb, bindex, h_inode->i_ino, 0);
 
385
        /* ignore this error */
 
386
        /* bad action? */
 
387
 
 
388
        /* children inode number will be broken */
 
389
 
 
390
 out:
 
391
        AuTraceErr(err);
 
392
        return err;
 
393
}
 
394
 
 
395
static int hin_iigen(struct inode *inode)
 
396
{
 
397
        LKTRTrace("i%lu\n", inode->i_ino);
 
398
 
 
399
        if (inode->i_ino != AUFS_ROOT_INO)
 
400
                au_iigen_dec(inode);
 
401
        else
 
402
                AuWarn("branch root dir was changed\n");
 
403
        return 0;
 
404
}
 
405
 
 
406
static int hin_digen_tree(struct dentry *dentry, int dec_iigen)
 
407
{
 
408
        int err, i, j, ndentry;
 
409
        struct au_dcsub_pages dpages;
 
410
        struct au_dpage *dpage;
 
411
        struct dentry **dentries;
 
412
 
 
413
        LKTRTrace("%.*s, iigen %d\n", AuDLNPair(dentry), dec_iigen);
 
414
 
 
415
        err = au_dpages_init(&dpages, GFP_TEMPORARY);
 
416
        if (unlikely(err))
 
417
                goto out;
 
418
        err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
 
419
        if (unlikely(err))
 
420
                goto out_dpages;
 
421
 
 
422
        for (i = 0; i < dpages.ndpage; i++) {
 
423
                dpage = dpages.dpages + i;
 
424
                dentries = dpage->dentries;
 
425
                ndentry = dpage->ndentry;
 
426
                for (j = 0; j < ndentry; j++) {
 
427
                        struct dentry *d;
 
428
                        d = dentries[j];
 
429
                        LKTRTrace("%.*s\n", AuDLNPair(d));
 
430
                        if (IS_ROOT(d))
 
431
                                continue;
 
432
                        d_drop(d);
 
433
                        au_digen_dec(d);
 
434
                        if (dec_iigen && d->d_inode)
 
435
                                //reset children xino? cached children only?
 
436
                                hin_iigen(d->d_inode);
 
437
                }
 
438
        }
 
439
 
 
440
 out_dpages:
 
441
        au_dpages_free(&dpages);
 
442
 
 
443
        /* discard children */
 
444
        dentry_unhash(dentry);
 
445
        dput(dentry);
 
446
 out:
 
447
        AuTraceErr(err);
 
448
        return err;
 
449
}
 
450
 
 
451
/*
 
452
 * return 0 if processed.
 
453
 */
 
454
static int hin_digen_by_inode(char *name, unsigned int nlen,
 
455
                              struct inode *inode, int dec_iigen)
 
456
{
 
457
        int err;
 
458
        struct dentry *d;
 
459
        struct qstr *dname;
 
460
 
 
461
        LKTRTrace("%.*s, i%lu, iigen %d\n",
 
462
                  nlen, name, inode->i_ino, dec_iigen);
 
463
 
 
464
        err = 1;
 
465
        if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
 
466
                AuWarn("branch root dir was changed\n");
 
467
                err = 0;
 
468
                goto out;
 
469
        }
 
470
 
 
471
        if (!S_ISDIR(inode->i_mode)) {
 
472
                AuDebugOn(!name);
 
473
                spin_lock(&dcache_lock);
 
474
                list_for_each_entry(d, &inode->i_dentry, d_alias) {
 
475
                        dname = &d->d_name;
 
476
                        if (dname->len != nlen
 
477
                            && memcmp(dname->name, name, nlen))
 
478
                                continue;
 
479
                        err = 0;
 
480
                        spin_lock(&d->d_lock);
 
481
                        __d_drop(d);
 
482
                        au_digen_dec(d);
 
483
                        spin_unlock(&d->d_lock);
 
484
                        break;
 
485
                }
 
486
                spin_unlock(&dcache_lock);
 
487
        } else {
 
488
                d = d_find_alias(inode);
 
489
                if (d) {
 
490
                        dname = &d->d_name;
 
491
                        if (dname->len == nlen
 
492
                            && !memcmp(dname->name, name, nlen))
 
493
                                err = hin_digen_tree(d, dec_iigen);
 
494
                        dput(d);
 
495
                }
 
496
        }
 
497
 
 
498
 out:
 
499
        AuTraceErr(err);
 
500
        return err;
 
501
}
 
502
 
 
503
static int hin_digen_by_name(struct dentry *dentry, int dec_iigen)
 
504
{
 
505
        struct inode *inode;
 
506
 
 
507
        LKTRTrace("%.*s, iigen %d\n", AuDLNPair(dentry), dec_iigen);
 
508
 
 
509
        if (IS_ROOT(dentry)) {
 
510
                AuWarn("branch root dir was changed\n");
 
511
                return 0;
 
512
        }
 
513
 
 
514
        inode = dentry->d_inode;
 
515
        if (!inode) {
 
516
                d_drop(dentry);
 
517
                au_digen_dec(dentry);
 
518
        } else if (unlikely(inode->i_ino == AUFS_ROOT_INO))
 
519
                AuWarn("branch root dir was changed\n");
 
520
        else {
 
521
                if (!S_ISDIR(inode->i_mode)) {
 
522
                        au_digen_dec(dentry);
 
523
                        d_drop(dentry);
 
524
                } else
 
525
                        hin_digen_tree(dentry, dec_iigen);
 
526
        }
 
527
 
 
528
        return 0;
 
529
}
 
530
 
 
531
/* ---------------------------------------------------------------------- */
 
532
 
 
533
union hin_job {
 
534
        unsigned int flags;
 
535
        struct {
 
536
                unsigned int xino0:1;
 
537
                unsigned int iigen:1;
 
538
                unsigned int digen:1;
 
539
                unsigned int dirent:1;
 
540
                unsigned int attr:1;
 
541
        };
 
542
};
 
543
 
 
544
struct hin_job_args {
 
545
        union hin_job *jobs;
 
546
        struct inode *inode, *h_inode, *dir, *h_dir;
 
547
        struct dentry *dentry;
 
548
        char *h_name;
 
549
        int h_nlen;
 
550
};
 
551
 
 
552
static int hin_job(struct hin_job_args *a)
 
553
{
 
554
        /* reset xino */
 
555
        if (a->inode && a->jobs->xino0)
 
556
                hin_xino(a->inode, a->h_inode);
 
557
        /* ignore this error */
 
558
 
 
559
        /* make the generation obsolete */
 
560
        if (a->jobs->iigen && a->inode)
 
561
                hin_iigen(a->inode);
 
562
        /* ignore this error */
 
563
 
 
564
        if (a->jobs->digen) {
 
565
                int err;
 
566
                err = -1;
 
567
                if (a->inode)
 
568
                        err = hin_digen_by_inode(a->h_name, a->h_nlen, a->inode,
 
569
                                                 a->jobs->iigen);
 
570
                if (err && a->dentry)
 
571
                        hin_digen_by_name(a->dentry, a->jobs->iigen);
 
572
                /* ignore this error */
 
573
        }
 
574
 
 
575
        /* make dir entries obsolete */
 
576
        if (a->jobs->dirent) {
 
577
                struct aufs_vdir *vdir;
 
578
                vdir = ivdir(a->inode);
 
579
                if (vdir)
 
580
                        vdir->vd_jiffy = 0;
 
581
                IMustLock(a->inode);
 
582
                a->inode->i_version++;
 
583
        }
 
584
 
 
585
        /* update the attr */
 
586
        if (a->jobs->attr
 
587
            && a->inode
 
588
            && au_h_iptr(a->inode) == a->h_inode)
 
589
                au_cpup_attr_all(a->inode);
 
590
        return 0;
 
591
}
 
592
 
 
593
/* ---------------------------------------------------------------------- */
 
594
 
 
595
enum { CHILD, PARENT };
287
596
struct postproc_args {
288
597
        struct inode *h_dir, *dir, *h_child_inode;
289
 
        char *h_child_name;
290
598
        u32 mask;
 
599
        union hin_job jobs[2];
 
600
        unsigned int h_child_nlen;
 
601
        char h_child_name[];
291
602
};
292
603
 
293
 
static void dec_gen_by_ino(struct postproc_args *a)
 
604
static void postproc(void *_args)
294
605
{
 
606
        struct postproc_args *a = _args;
295
607
        struct super_block *sb;
296
608
        aufs_bindex_t bindex, bend, bfound;
297
 
        struct xino xino;
298
 
        struct inode *cinode;
299
 
 
300
 
        TraceEnter();
301
 
 
302
 
        sb = a->dir->i_sb;
303
 
        AuDebugOn(!au_flag_test(sb, AuFlag_XINO));
304
 
 
305
 
        bfound = -1;
306
 
        bend = ibend(a->dir);
307
 
        for (bindex = ibstart(a->dir); bfound == -1 && bindex <= bend; bindex++)
308
 
                if (au_h_iptr_i(a->dir, bindex) == a->h_dir)
309
 
                        bfound = bindex;
310
 
        if (bfound < 0)
311
 
                return;
312
 
 
313
 
        bindex = find_brindex(sb, itoii(a->dir)->ii_hinode[bfound + 0].hi_id);
314
 
        if (bindex < 0)
315
 
                return;
316
 
        if (unlikely(xino_read(sb, bindex, a->h_child_inode->i_ino, &xino)))
317
 
                return;
318
 
        cinode = NULL;
319
 
        if (xino.ino != AUFS_ROOT_INO)
320
 
                cinode = ilookup(sb, xino.ino);
321
 
        if (cinode) {
322
 
#if 1
323
 
                if (1 || a->mask & IN_MOVE) {
324
 
                        struct dentry *child;
325
 
                        spin_lock(&dcache_lock);
326
 
                        list_for_each_entry(child, &cinode->i_dentry, d_alias)
327
 
                                au_digen_dec(child);
328
 
                        spin_unlock(&dcache_lock);
329
 
                }
330
 
#endif
331
 
                au_iigen_dec(cinode);
332
 
                iput(cinode);
333
 
        }
334
 
}
335
 
 
336
 
static void reset_ino(struct postproc_args *a)
337
 
{
338
 
        aufs_bindex_t bindex, bend;
339
 
        struct super_block *sb;
340
 
        struct inode *h_dir;
341
 
 
342
 
        sb = a->dir->i_sb;
343
 
        bend = ibend(a->dir);
344
 
        for (bindex = ibstart(a->dir); bindex <= bend; bindex++) {
345
 
                h_dir = au_h_iptr_i(a->dir, bindex);
346
 
                if (h_dir && h_dir != a->h_dir)
347
 
                        xino_write0(sb, bindex, h_dir->i_ino);
348
 
                /* ignore this error */
349
 
        }
350
 
}
351
 
 
352
 
static void postproc(void *args)
353
 
{
354
 
        struct postproc_args *a = args;
355
 
        struct super_block *sb;
356
 
        struct aufs_vdir *vdir;
 
609
        int xino, err;
 
610
        struct inode *inode;
 
611
        ino_t h_ino;
 
612
        struct hin_job_args args;
 
613
        struct dentry *dentry;
 
614
        struct aufs_sbinfo *sbinfo;
357
615
 
358
616
        //au_debug_on();
359
617
        LKTRTrace("mask 0x%x %s, i%lu, hi%lu, hci%lu\n",
360
618
                  a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino,
361
619
                  a->h_child_inode ? a->h_child_inode->i_ino : 0);
362
 
        AuDebugOn(!a->dir);
363
 
#if 0//def ForceInotify
364
 
        Dbg("mask 0x%x %s, i%lu, hi%lu, hci%lu\n",
365
 
                  a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino,
366
 
                  a->h_child_inode ? a->h_child_inode->i_ino : 0);
367
 
#endif
368
620
 
369
 
        i_lock(a->dir);
 
621
        inode = NULL;
 
622
        dentry = NULL;
 
623
        vfsub_i_lock(a->dir);
370
624
        sb = a->dir->i_sb;
371
 
        si_read_lock(sb); // consider write_lock
 
625
        sbinfo = stosi(sb);
 
626
        si_read_lock(sb, !AuLock_FLUSH);
 
627
 
 
628
        ii_read_lock_parent(a->dir);
 
629
        bfound = -1;
 
630
        bend = ibend(a->dir);
 
631
        for (bindex = ibstart(a->dir); bindex <= bend; bindex++)
 
632
                if (au_h_iptr_i(a->dir, bindex) == a->h_dir) {
 
633
                        bfound = bindex;
 
634
                        break;
 
635
                }
 
636
        ii_read_unlock(a->dir);
 
637
        if (unlikely(bfound < 0))
 
638
                goto out;
 
639
 
 
640
        xino = (AuFlag(sbinfo, f_xino) != AuXino_NONE);
 
641
        h_ino = 0;
 
642
        if (a->h_child_inode)
 
643
                h_ino = a->h_child_inode->i_ino;
 
644
 
 
645
        if (a->h_child_nlen && a->jobs[CHILD].digen)
 
646
                dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
 
647
                                              a->dir);
 
648
        if (dentry)
 
649
                inode = dentry->d_inode;
 
650
        if (xino && !inode && h_ino
 
651
            && (a->jobs[CHILD].xino0
 
652
                || a->jobs[CHILD].iigen
 
653
                || a->jobs[CHILD].digen
 
654
                || a->jobs[CHILD].attr))
 
655
                inode = lookup_wlock_by_ino(sb, bfound, h_ino);
 
656
 
 
657
        args.jobs = a->jobs + CHILD;
 
658
        args.dentry = dentry;
 
659
        args.inode = inode;
 
660
        args.h_inode = a->h_child_inode;
 
661
        args.dir = a->dir;
 
662
        args.h_dir = a->h_dir;
 
663
        args.h_name = a->h_child_name;
 
664
        args.h_nlen = a->h_child_nlen;
 
665
        err = hin_job(&args);
 
666
        if (dentry) {
 
667
                di_write_unlock(dentry);
 
668
                dput(dentry);
 
669
        } else if (inode) {
 
670
                ii_write_unlock(inode);
 
671
                iput(inode);
 
672
        }
 
673
 
372
674
        ii_write_lock_parent(a->dir);
373
 
 
374
 
        /* make dir entries obsolete */
375
 
        vdir = ivdir(a->dir);
376
 
        if (vdir)
377
 
                vdir->vd_jiffy = 0;
378
 
        a->dir->i_version++;
379
 
 
380
 
        /*
381
 
         * special handling root directory,
382
 
         * sine d_revalidate may not be called later.
383
 
         * main purpose is maintaining i_nlink.
384
 
         */
385
 
        if (unlikely(a->dir->i_ino == AUFS_ROOT_INO))
386
 
                au_cpup_attr_all(a->dir);
387
 
 
388
 
        if (a->h_child_inode && au_flag_test(sb, AuFlag_XINO)) {
389
 
                if (a->dir->i_ino != AUFS_ROOT_INO)
390
 
                        dec_gen_by_ino(a);
391
 
        } else if (a->mask & (IN_MOVE_SELF | IN_DELETE_SELF))
392
 
                reset_ino(a);
393
 
 
 
675
        args.jobs = a->jobs + PARENT;
 
676
        args.dentry = NULL;
 
677
        args.inode = a->dir;
 
678
        args.h_inode = a->h_dir;
 
679
        args.dir = NULL;
 
680
        args.h_dir = NULL;
 
681
        args.h_name = NULL;
 
682
        args.h_nlen = 0;
 
683
        err = hin_job(&args);
394
684
        ii_write_unlock(a->dir);
 
685
 
 
686
 out:
395
687
        si_read_unlock(sb);
396
 
        i_unlock(a->dir);
 
688
        vfsub_i_unlock(a->dir);
 
689
        au_nwt_dec(&sbinfo->si_nowait);
397
690
 
398
691
        iput(a->h_child_inode);
399
692
        iput(a->h_dir);
402
695
        //au_debug_off();
403
696
}
404
697
 
 
698
//todo: endian?
 
699
#ifndef ilog2
 
700
#define ilog2(n) ffz(~(n))
 
701
#endif
 
702
 
405
703
static void aufs_inotify(struct inotify_watch *watch, u32 wd, u32 mask,
406
704
                         u32 cookie, const char *h_child_name,
407
705
                         struct inode *h_child_inode)
408
706
{
409
707
        struct aufs_hinotify *hinotify;
410
708
        struct postproc_args *args;
411
 
        int len, wkq_err;
 
709
        int len, wkq_err, isdir, isroot, wh, idx;
412
710
        char *p;
413
711
        struct inode *dir;
414
 
        //static DECLARE_WAIT_QUEUE_HEAD(wq);
 
712
        union hin_job jobs[2];
 
713
        struct super_block *sb;
 
714
        atomic_t *cnt;
415
715
 
416
 
        //au_debug_on();
417
716
        LKTRTrace("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n",
418
717
                  watch->inode->i_ino, wd, mask, in_name(mask), cookie,
419
718
                  h_child_name ? h_child_name : "",
420
719
                  h_child_inode ? h_child_inode->i_ino : 0);
421
 
        //au_debug_off();
422
 
        //IMustLock(h_dir);
423
720
#if 0 //defined(ForceInotify) || defined(DbgInotify)
424
 
        Dbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n",
425
 
                  watch->inode->i_ino, wd, mask, in_name(mask), cookie,
426
 
                  h_child_name ? h_child_name : "",
427
 
                  h_child_inode ? h_child_inode->i_ino : 0);
 
721
        AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n",
 
722
              watch->inode->i_ino, wd, mask, in_name(mask), cookie,
 
723
              h_child_name ? h_child_name : "",
 
724
              h_child_inode ? h_child_inode->i_ino : 0);
428
725
#endif
429
726
        /* if IN_UNMOUNT happens, there must be another bug */
430
727
        if (mask & (IN_IGNORED | IN_UNMOUNT)) {
 
728
                //WARN_ON(watch->inode->i_ino == 15);
431
729
                put_inotify_watch(watch);
432
730
                return;
433
731
        }
434
732
 
 
733
#ifdef DbgInotify
 
734
        if (!h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME))
 
735
                AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s,"
 
736
                      " hi%lu\n",
 
737
                      watch->inode->i_ino, wd, mask, in_name(mask), cookie,
 
738
                      h_child_name ? h_child_name : "",
 
739
                      h_child_inode ? h_child_inode->i_ino : 0);
 
740
        //WARN_ON(1);
 
741
#endif
 
742
 
 
743
        hinotify = container_of(watch, struct aufs_hinotify, hin_watch);
 
744
        AuDebugOn(!hinotify || !hinotify->hin_aufs_inode);
 
745
        idx = ilog2(mask & IN_ALL_EVENTS);
 
746
        AuDebugOn(au_hin_nignore <= idx);
 
747
        cnt = hinotify->hin_ignore + idx;
 
748
        if (0 <= atomic_dec_return(cnt))
 
749
                return;
 
750
        atomic_inc_return(cnt);
 
751
#ifdef DbgInotify
 
752
#if 0
 
753
        AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n",
 
754
              watch->inode->i_ino, wd, mask, in_name(mask), cookie,
 
755
              h_child_name ? h_child_name : "",
 
756
              h_child_inode ? h_child_inode->i_ino : 0);
 
757
#endif
 
758
        if (!h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME))
 
759
                WARN_ON(1);
 
760
#endif
 
761
 
 
762
        dir = hinotify->hin_aufs_inode;
 
763
        isroot = (dir->i_ino == AUFS_ROOT_INO);
 
764
        len = 0;
 
765
        wh = 0;
 
766
        if (h_child_name) {
 
767
                len = strlen(h_child_name);
 
768
                if (unlikely(!memcmp(h_child_name, AUFS_WH_PFX,
 
769
                                     AUFS_WH_PFX_LEN))) {
 
770
                        h_child_name += AUFS_WH_PFX_LEN;
 
771
                        len -= AUFS_WH_PFX_LEN;
 
772
                        wh = 1;
 
773
                }
 
774
        }
 
775
 
 
776
        isdir = 0;
 
777
        if (h_child_inode)
 
778
                isdir = !!S_ISDIR(h_child_inode->i_mode);
 
779
        jobs[PARENT].flags = 0;
 
780
        jobs[CHILD].flags = 0;
435
781
        switch (mask & IN_ALL_EVENTS) {
436
782
        case IN_MODIFY:
 
783
                /*FALLTHROUGH*/
437
784
        case IN_ATTRIB:
438
 
                if (h_child_name)
439
 
                        return;
 
785
                if (h_child_inode) {
 
786
                        if (!wh)
 
787
                                jobs[CHILD].attr = 1;
 
788
                } else
 
789
                        jobs[PARENT].attr = 1;
440
790
                break;
441
791
 
 
792
                /* IN_MOVED_FROM is the first event in rename(2) */
442
793
        case IN_MOVED_FROM:
443
794
        case IN_MOVED_TO:
 
795
                AuDebugOn(!h_child_name || !h_child_inode);
 
796
                jobs[CHILD].iigen = 1;
 
797
                jobs[CHILD].attr = 1;
 
798
                jobs[CHILD].xino0 = 1;//!!isdir;
 
799
                jobs[CHILD].digen = 1;
 
800
                jobs[PARENT].attr = 1;
 
801
                jobs[PARENT].dirent = 1;
 
802
                break;
 
803
 
444
804
        case IN_CREATE:
445
805
                AuDebugOn(!h_child_name || !h_child_inode);
 
806
                jobs[PARENT].attr = 1;
 
807
                jobs[PARENT].dirent = 1;
 
808
                jobs[CHILD].digen = 1;
 
809
                jobs[CHILD].iigen = 1;
 
810
                /* hard link */
 
811
                jobs[CHILD].attr = (!isdir && h_child_inode->i_nlink > 1);
446
812
                break;
 
813
 
447
814
        case IN_DELETE:
448
815
                /*
449
816
                 * aufs never be able to get this child inode.
450
 
                 * revalidation should be in d_revalide()
 
817
                 * revalidation should be in d_revalidate()
451
818
                 * by checking i_nlink, i_generation or d_unhashed().
452
819
                 */
453
820
                AuDebugOn(!h_child_name);
 
821
                jobs[PARENT].attr = 1;
 
822
                jobs[PARENT].dirent = 1;
 
823
                jobs[CHILD].iigen = 1;
 
824
                jobs[CHILD].digen = 1;
454
825
                break;
455
826
 
456
827
        case IN_DELETE_SELF:
 
828
                jobs[PARENT].iigen = !isroot;
 
829
                /*FALLTHROUGH*/
 
830
 
457
831
        case IN_MOVE_SELF:
458
832
                AuDebugOn(h_child_name || h_child_inode);
 
833
                if (unlikely(isroot)) {
 
834
                        AuWarn("root branch was moved\n");
 
835
                        return;
 
836
                }
 
837
#if 1
 
838
                return;
 
839
#else
 
840
                jobs[PARENT].xino0 = !isroot;
 
841
                jobs[PARENT].iigen = !isroot;
 
842
                jobs[PARENT].digen = !isroot;
 
843
                jobs[PARENT].attr = !isroot;
 
844
                jobs[PARENT].dirent = !isroot;
459
845
                break;
460
 
 
 
846
#endif
461
847
        case IN_ACCESS:
462
848
        default:
463
849
                AuDebugOn(1);
464
850
        }
465
851
 
466
 
#ifdef DbgInotify
 
852
#if 0 //def DbgInotify
467
853
        WARN_ON(1);
468
854
#endif
469
855
 
470
 
        /* iput() will be called in postproc() */
471
 
        hinotify = container_of(watch, struct aufs_hinotify, hin_watch);
472
 
        AuDebugOn(!hinotify || !hinotify->hin_aufs_inode);
473
 
        dir = hinotify->hin_aufs_inode;
474
 
 
475
 
        /* force re-lookup in next d_revalidate() */
476
 
        if (dir->i_ino != AUFS_ROOT_INO)
477
 
                au_iigen_dec(dir);
478
 
        len = 0;
479
 
        if (h_child_name && dec_gen_by_name(dir, h_child_name, mask))
480
 
                len = strlen(h_child_name);
481
 
 
482
 
        //wait_event(wq, (args = kmalloc(sizeof(*args), GFP_KERNEL)));
483
 
        args = kmalloc(sizeof(*args) + len + 1, GFP_KERNEL);
 
856
        if (wh)
 
857
                h_child_inode = NULL;
 
858
 
 
859
        /* iput() and kfree() will be called in postproc() */
 
860
        args = kmalloc(sizeof(*args) + len + 1, GFP_TEMPORARY);
484
861
        if (unlikely(!args)) {
485
 
                Err("no memory\n");
 
862
                AuErr1("no memory\n");
486
863
                return;
487
864
        }
 
865
        memcpy(args->jobs, jobs, sizeof(jobs));
488
866
        args->mask = mask;
489
867
        args->dir = igrab(dir);
490
868
        args->h_dir = igrab(watch->inode);
491
 
        args->h_child_inode = NULL;
 
869
        if (h_child_inode)
 
870
                igrab(h_child_inode);
 
871
        args->h_child_inode = h_child_inode;
 
872
        args->h_child_nlen = len;
492
873
        if (len) {
493
 
                if (h_child_inode)
494
 
                        args->h_child_inode = igrab(h_child_inode);
495
 
                p = (void*)args;
496
 
                args->h_child_name = p + sizeof(*args);
497
 
                memcpy(args->h_child_name, h_child_name, len + 1);
498
 
        }
499
 
        //atomic_inc(&stosi(args->dir->i_sb)->si_hinotify);
500
 
        wkq_err = au_wkq_nowait(postproc, args, dir->i_sb, /*dlgt*/0);
501
 
        if (unlikely(wkq_err))
502
 
                Err("wkq %d\n", wkq_err);
 
874
                p = (void *)args;
 
875
                p += sizeof(*args);
 
876
                memcpy(p, h_child_name, len + 1);
 
877
        }
 
878
 
 
879
        sb = dir->i_sb;
 
880
        au_nwt_inc(&stosi(sb)->si_nowait);
 
881
        wkq_err = au_wkq_nowait(postproc, args, sb, /*dlgt*/0);
 
882
        if (unlikely(wkq_err)) {
 
883
                AuErr("wkq %d\n", wkq_err);
 
884
                au_nwt_dec(&stosi(sb)->si_nowait);
 
885
        }
503
886
}
504
887
 
505
888
static void aufs_inotify_destroy(struct inotify_watch *watch)
516
899
 
517
900
int __init au_inotify_init(void)
518
901
{
 
902
        au_hin_nignore = 6;
 
903
        while (1U << au_hin_nignore < AuInMask)
 
904
                au_hin_nignore++;
 
905
        //AuDbg("au_hin_nignore %d\n", au_hin_nignore);
 
906
        AuDebugOn(au_hin_nignore != 12);
 
907
 
519
908
        in_handle = inotify_init(&aufs_inotify_ops);
520
909
        if (!IS_ERR(in_handle))
521
910
                return 0;
522
 
        TraceErrPtr(in_handle);
 
911
        AuTraceErrPtr(in_handle);
523
912
        return PTR_ERR(in_handle);
524
913
}
525
914