~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: 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
1
/*
2
 
 * Copyright (C) 2005, 2006, 2007, 2008 Junjiro Okajima
 
2
 * Copyright (C) 2006-2008 Junjiro Okajima
3
3
 *
4
4
 * This program, aufs is free software; you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
16
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 */
18
18
 
19
 
/* $Id: hinotify.c,v 1.45 2008/03/24 02:15:47 sfjro Exp $ */
 
19
/*
 
20
 * inotify handler
 
21
 *
 
22
 * $Id: hinotify.c,v 1.48 2008/04/28 03:02:50 sfjro Exp $
 
23
 */
20
24
 
21
25
#include "aufs.h"
22
26
 
27
31
                               | IN_DELETE_SELF | IN_MOVE_SELF);
28
32
static struct inotify_handle *in_handle;
29
33
 
30
 
int au_hin_alloc(struct aufs_hinode *hinode, struct inode *inode,
 
34
/* the size of an array for ignore counter */
 
35
static int au_hin_nignore;
 
36
 
 
37
AuCacheFuncs(hinotify, AuCache_HINOTIFY);
 
38
 
 
39
int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
31
40
                 struct inode *hidden_inode)
32
41
{
33
42
        int err, i;
34
 
        struct aufs_hinotify *hin;
 
43
        struct au_hinotify *hin;
35
44
        s32 wd;
36
45
 
37
46
        LKTRTrace("i%lu, hi%lu\n", inode->i_ino, hidden_inode->i_ino);
61
70
        return err;
62
71
}
63
72
 
64
 
void au_hin_free(struct aufs_hinode *hinode)
 
73
void au_hin_free(struct au_hinode *hinode)
65
74
{
66
75
        int err;
67
 
        struct aufs_hinotify *hin;
 
76
        struct au_hinotify *hin;
68
77
 
69
78
        AuTraceEnter();
70
79
 
84
93
 
85
94
/* ---------------------------------------------------------------------- */
86
95
 
87
 
static void ctl_hinotify(struct aufs_hinode *hinode, const __u32 mask)
 
96
static void ctl_hinotify(struct au_hinode *hinode, const __u32 mask)
88
97
{
89
98
        struct inode *h_inode;
90
99
        struct inotify_watch *watch;
120
129
void au_do_hdir_lock(struct inode *h_dir, struct inode *dir,
121
130
                     aufs_bindex_t bindex, unsigned int lsc)
122
131
{
123
 
        struct aufs_hinode *hinode;
 
132
        struct au_hinode *hinode;
124
133
 
125
134
        LKTRTrace("i%lu, b%d, lsc %d\n", dir->i_ino, bindex, lsc);
126
135
        AuDebugOn(!S_ISDIR(dir->i_mode));
127
 
        hinode = itoii(dir)->ii_hinode + bindex;
 
136
        hinode = au_ii(dir)->ii_hinode + bindex;
128
137
        AuDebugOn(h_dir != hinode->hi_inode);
129
138
 
130
139
        vfsub_i_lock_nested(h_dir, lsc);
131
140
        suspend_hinotify(hinode);
132
141
}
133
142
 
134
 
void hdir_unlock(struct inode *h_dir, struct inode *dir, aufs_bindex_t bindex)
 
143
void au_hdir_unlock(struct inode *h_dir, struct inode *dir,
 
144
                    aufs_bindex_t bindex)
135
145
{
136
 
        struct aufs_hinode *hinode;
 
146
        struct au_hinode *hinode;
137
147
 
138
148
        LKTRTrace("i%lu, b%d\n", dir->i_ino, bindex);
139
149
        AuDebugOn(!S_ISDIR(dir->i_mode));
140
 
        hinode = itoii(dir)->ii_hinode + bindex;
 
150
        hinode = au_ii(dir)->ii_hinode + bindex;
141
151
        AuDebugOn(h_dir != hinode->hi_inode);
142
152
 
143
153
        resume_hinotify(hinode);
144
154
        vfsub_i_unlock(h_dir);
145
155
}
146
156
 
147
 
struct dentry *hdir_lock_rename(struct dentry **h_parents, struct inode **dirs,
148
 
                                aufs_bindex_t bindex, int issamedir)
 
157
struct dentry *au_hdir_lock_rename(struct dentry **h_parents,
 
158
                                   struct inode **dirs, aufs_bindex_t bindex,
 
159
                                   int issamedir)
149
160
{
150
161
        struct dentry *h_trap;
151
 
        struct aufs_hinode *hinode;
 
162
        struct au_hinode *hinode;
152
163
 
153
164
        LKTRTrace("%.*s, %.*s\n",
154
165
                  AuDLNPair(h_parents[0]), AuDLNPair(h_parents[1]));
155
166
 
156
167
        h_trap = vfsub_lock_rename(h_parents[0], h_parents[1]);
157
 
        hinode = itoii(dirs[0])->ii_hinode + bindex;
 
168
        hinode = au_ii(dirs[0])->ii_hinode + bindex;
158
169
        AuDebugOn(h_parents[0]->d_inode != hinode->hi_inode);
159
170
        suspend_hinotify(hinode);
160
171
        if (!issamedir) {
161
 
                hinode = itoii(dirs[1])->ii_hinode + bindex;
 
172
                hinode = au_ii(dirs[1])->ii_hinode + bindex;
162
173
                AuDebugOn(h_parents[1]->d_inode != hinode->hi_inode);
163
174
                suspend_hinotify(hinode);
164
175
        }
166
177
        return h_trap;
167
178
}
168
179
 
169
 
void hdir_unlock_rename(struct dentry **h_parents, struct inode **dirs,
170
 
                        aufs_bindex_t bindex, int issamedir)
 
180
void au_hdir_unlock_rename(struct dentry **h_parents, struct inode **dirs,
 
181
                           aufs_bindex_t bindex, int issamedir)
171
182
{
172
 
        struct aufs_hinode *hinode;
 
183
        struct au_hinode *hinode;
173
184
 
174
185
        LKTRTrace("%.*s, %.*s\n",
175
186
                  AuDLNPair(h_parents[0]), AuDLNPair(h_parents[1]));
176
187
 
177
 
        hinode = itoii(dirs[0])->ii_hinode + bindex;
 
188
        hinode = au_ii(dirs[0])->ii_hinode + bindex;
178
189
        AuDebugOn(h_parents[0]->d_inode != hinode->hi_inode);
179
190
        resume_hinotify(hinode);
180
191
        if (!issamedir) {
181
 
                hinode = itoii(dirs[1])->ii_hinode + bindex;
 
192
                hinode = au_ii(dirs[1])->ii_hinode + bindex;
182
193
                AuDebugOn(h_parents[1]->d_inode != hinode->hi_inode);
183
194
                resume_hinotify(hinode);
184
195
        }
193
204
 
194
205
        LKTRTrace("i%lu, 0x%x\n", inode->i_ino, flags);
195
206
 
196
 
        bend = ibend(inode);
197
 
        for (bindex = ibstart(inode); bindex <= bend; bindex++) {
 
207
        bend = au_ibend(inode);
 
208
        for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
198
209
                hi = au_h_iptr_i(inode, bindex);
199
210
                if (hi) {
200
211
                        //vfsub_i_lock_nested(hi, AuLsc_I_CHILD);
202
213
                        if (unlikely(iwhdentry))
203
214
                                dget(iwhdentry);
204
215
                        igrab(hi);
205
 
                        set_h_iptr(inode, bindex, NULL, 0);
206
 
                        set_h_iptr(inode, bindex, igrab(hi),
207
 
                                   flags & ~AuHi_XINO);
 
216
                        au_set_h_iptr(inode, bindex, NULL, 0);
 
217
                        au_set_h_iptr(inode, bindex, igrab(hi),
 
218
                                      flags & ~AuHi_XINO);
208
219
                        iput(hi);
209
220
                        dput(iwhdentry);
210
221
                        //vfsub_i_unlock(hi);
214
225
 
215
226
/* ---------------------------------------------------------------------- */
216
227
 
217
 
void au_hin_ignore(struct aufs_hinode *hinode, __u32 events)
 
228
/* cf. fsnotify_change() */
 
229
__u32 vfsub_events_notify_change(struct iattr *ia)
 
230
{
 
231
        __u32 events;
 
232
        const unsigned int amtime = (ATTR_ATIME | ATTR_MTIME);
 
233
 
 
234
        events = 0;
 
235
        if ((ia->ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE))
 
236
            || (ia->ia_valid & amtime) == amtime)
 
237
                events |= IN_ATTRIB;
 
238
        if ((ia->ia_valid & ATTR_SIZE)
 
239
            || (ia->ia_valid & amtime) == ATTR_MTIME)
 
240
                events |= IN_MODIFY;
 
241
        return events;
 
242
}
 
243
 
 
244
void vfsub_ign_hinode(struct vfsub_args *vargs, __u32 events,
 
245
                      struct au_hinode *hinode)
 
246
{
 
247
        struct au_hin_ignore *ign;
 
248
 
 
249
        AuDebugOn(!hinode);
 
250
 
 
251
        ign = vargs->ignore + vargs->nignore++;
 
252
        ign->ign_events = events;
 
253
        ign->ign_hinode = hinode;
 
254
}
 
255
 
 
256
void vfsub_ignore(struct vfsub_args *vargs)
 
257
{
 
258
        int n;
 
259
        struct au_hin_ignore *ign;
 
260
 
 
261
        n = vargs->nignore;
 
262
        ign = vargs->ignore;
 
263
        while (n-- > 0) {
 
264
                au_hin_ignore(ign->ign_hinode, ign->ign_events);
 
265
                ign++;
 
266
        }
 
267
}
 
268
 
 
269
void vfsub_unignore(struct vfsub_args *vargs)
 
270
{
 
271
        int n;
 
272
        struct au_hin_ignore *ign;
 
273
 
 
274
        n = vargs->nignore;
 
275
        ign = vargs->ignore;
 
276
        while (n-- > 0) {
 
277
                au_hin_unignore(ign->ign_hinode, ign->ign_events);
 
278
                ign++;
 
279
        }
 
280
}
 
281
 
 
282
/* ---------------------------------------------------------------------- */
 
283
 
 
284
void au_hin_ignore(struct au_hinode *hinode, __u32 events)
218
285
{
219
286
        int i;
220
287
        atomic_t *ign;
249
316
                        atomic_inc_return(ign + i);
250
317
}
251
318
 
252
 
void au_hin_unignore(struct aufs_hinode *hinode, __u32 events)
 
319
void au_hin_unignore(struct au_hinode *hinode, __u32 events)
253
320
{
254
321
        int i;
255
322
        atomic_t *ign;
317
384
        list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
318
385
                LKTRTrace("%.*s\n", AuDLNPair(d));
319
386
                dname = &d->d_name;
320
 
                if (dname->len != nlen
321
 
                    || memcmp(dname->name, name, nlen))
 
387
                if (dname->len != nlen || memcmp(dname->name, name, nlen))
322
388
                        continue;
323
389
                if (!atomic_read(&d->d_count)) {
324
390
                        spin_lock(&d->d_lock);
342
408
                                         aufs_bindex_t bindex, ino_t h_ino)
343
409
{
344
410
        struct inode *inode;
345
 
        struct xino_entry xinoe;
 
411
        struct au_xino_entry xinoe;
346
412
        int err;
347
413
 
348
414
        LKTRTrace("b%d, hi%lu\n", bindex, h_ino);
349
 
        AuDebugOn(AuFlag(stosi(sb), f_xino) == AuXino_NONE);
 
415
        AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
350
416
 
351
417
        inode = NULL;
352
 
        err = xino_read(sb, bindex, h_ino, &xinoe);
 
418
        err = au_xino_read(sb, bindex, h_ino, &xinoe);
353
419
        if (!err && xinoe.ino)
354
420
                inode = ilookup(sb, xinoe.ino);
355
421
        if (!inode)
395
461
        }
396
462
 
397
463
        bfound = -1;
398
 
        bend = ibend(inode);
399
 
        bstart = ibstart(inode);
 
464
        bend = au_ibend(inode);
 
465
        bstart = au_ibstart(inode);
400
466
#if 0
401
467
        if (bindex == bend) {
402
468
                /* keep this ino in rename case */
415
481
        for (bindex = bstart; bindex <= bend; bindex++) {
416
482
                h_i = au_h_iptr_i(inode, bindex);
417
483
                if (h_i)
418
 
                        err = xino_write0(inode->i_sb, bindex, h_i->i_ino, 0);
 
484
                        err = au_xino_write0(inode->i_sb, bindex, h_i->i_ino,
 
485
                                             0);
419
486
                /* ignore this error */
420
487
                /* bad action? */
421
488
        }
510
577
                }
511
578
                spin_unlock(&dcache_lock);
512
579
        } else {
513
 
                au_fset_si(stosi(inode->i_sb), FAILED_REFRESH_DIRS);
 
580
                au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS);
514
581
                d = d_find_alias(inode);
515
582
                if (!d) {
516
583
                        au_iigen_dec(inode);
518
585
                }
519
586
 
520
587
                dname = &d->d_name;
521
 
                if (dname->len == nlen
522
 
                    && !memcmp(dname->name, name, nlen))
 
588
                if (dname->len == nlen && !memcmp(dname->name, name, nlen))
523
589
                        err = hin_gen_tree(d);
524
590
                dput(d);
525
591
        }
551
617
                if (inode)
552
618
                        au_iigen_dec(inode);
553
619
        } else {
554
 
                au_fset_si(stosi(dentry->d_sb), FAILED_REFRESH_DIRS);
 
620
                au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS);
555
621
                if (inode)
556
622
                        err = hin_gen_tree(dentry);
557
623
        }
639
705
 
640
706
        /* make dir entries obsolete */
641
707
        if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) {
642
 
                struct aufs_vdir *vdir;
 
708
                struct au_vdir *vdir;
643
709
                IiMustWriteLock(a->inode);
644
 
                vdir = ivdir(a->inode);
 
710
                vdir = au_ivdir(a->inode);
645
711
                if (vdir)
646
712
                        vdir->vd_jiffy = 0;
647
713
                //IMustLock(a->inode);
683
749
        ino_t h_ino;
684
750
        struct hin_job_args args;
685
751
        struct dentry *dentry;
686
 
        struct aufs_sbinfo *sbinfo;
 
752
        struct au_sbinfo *sbinfo;
687
753
 
688
754
        //au_debug_on();
689
755
        LKTRTrace("mask 0x%x %s, i%lu, hi%lu, hci%lu\n",
695
761
        // do not lock here because of d_revalidate() may cause a deadlock.
696
762
        //vfsub_i_lock(a->dir);
697
763
        sb = a->dir->i_sb;
698
 
        sbinfo = stosi(sb);
 
764
        sbinfo = au_sbi(sb);
699
765
        /* big aufs lock */
700
766
        si_noflush_write_lock(sb);
701
767
 
702
768
        ii_read_lock_parent(a->dir);
703
769
        bfound = -1;
704
 
        bend = ibend(a->dir);
705
 
        for (bindex = ibstart(a->dir); bindex <= bend; bindex++)
 
770
        bend = au_ibend(a->dir);
 
771
        for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
706
772
                if (au_h_iptr_i(a->dir, bindex) == a->h_dir) {
707
773
                        bfound = bindex;
708
774
                        break;
711
777
        if (unlikely(bfound < 0))
712
778
                goto out;
713
779
 
714
 
        xino = (AuFlag(sbinfo, f_xino) != AuXino_NONE);
 
780
        xino = !!au_opt_test(au_mntflags(sb), XINO);
715
781
        h_ino = 0;
716
782
        if (a->h_child_inode)
717
783
                h_ino = a->h_child_inode->i_ino;
780
846
                         u32 cookie, const char *h_child_name,
781
847
                         struct inode *h_child_inode)
782
848
{
783
 
        struct aufs_hinotify *hinotify;
 
849
        struct au_hinotify *hinotify;
784
850
        struct postproc_args *args;
785
851
        int len, wkq_err, isdir, isroot, wh, idx;
786
852
        char *p;
816
882
        //WARN_ON(1);
817
883
#endif
818
884
 
819
 
        hinotify = container_of(watch, struct aufs_hinotify, hin_watch);
 
885
        hinotify = container_of(watch, struct au_hinotify, hin_watch);
820
886
        AuDebugOn(!hinotify || !hinotify->hin_aufs_inode);
821
887
        idx = ilog2(mask & IN_ALL_EVENTS);
822
888
        AuDebugOn(au_hin_nignore <= idx);
837
903
#endif
838
904
#endif
839
905
 
840
 
        dir = hinotify->hin_aufs_inode;
 
906
        dir = igrab(hinotify->hin_aufs_inode);
 
907
        if (!dir)
 
908
                return;
841
909
        isroot = (dir->i_ino == AUFS_ROOT_INO);
842
910
        len = 0;
843
911
        wh = 0;
920
988
                AuDebugOn(h_child_name || h_child_inode);
921
989
                if (unlikely(isroot)) {
922
990
                        AuWarn("root branch was moved\n");
 
991
                        iput(dir);
923
992
                        return;
924
993
                }
925
994
#if 0
954
1023
        lockdep_on();
955
1024
        if (unlikely(!args)) {
956
1025
                AuErr1("no memory\n");
 
1026
                iput(dir);
957
1027
                return;
958
1028
        }
959
1029
        args->flags[PARENT] = flags[PARENT];
960
1030
        args->flags[CHILD] = flags[CHILD];
961
1031
        args->mask = mask;
962
 
        args->dir = igrab(dir);
 
1032
        args->dir = dir;
963
1033
        args->h_dir = igrab(watch->inode);
964
1034
        if (h_child_inode)
965
1035
                igrab(h_child_inode);
972
1042
        }
973
1043
 
974
1044
        sb = dir->i_sb;
975
 
        au_nwt_inc(&stosi(sb)->si_nowait);
 
1045
        au_nwt_inc(&au_sbi(sb)->si_nowait);
976
1046
        lockdep_off();
977
1047
        wkq_err = au_wkq_nowait(postproc, args, sb, /*dlgt*/0);
978
1048
        lockdep_on();
979
1049
        if (unlikely(wkq_err)) {
980
1050
                AuErr("wkq %d\n", wkq_err);
981
 
                au_nwt_dec(&stosi(sb)->si_nowait);
 
1051
                au_nwt_dec(&au_sbi(sb)->si_nowait);
982
1052
        }
983
1053
}
984
1054
 
994
1064
 
995
1065
/* ---------------------------------------------------------------------- */
996
1066
 
 
1067
static void au_hin_destroy_cache(void)
 
1068
{
 
1069
        kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]);
 
1070
        au_cachep[AuCache_HINOTIFY] = NULL;
 
1071
}
 
1072
 
997
1073
int __init au_inotify_init(void)
998
1074
{
999
1075
        au_hin_nignore = 6;
1002
1078
        //AuDbg("au_hin_nignore %d\n", au_hin_nignore);
1003
1079
        AuDebugOn(au_hin_nignore != 12);
1004
1080
 
 
1081
        in_handle = ERR_PTR(-ENOMEM);
 
1082
        au_cachep[AuCache_HINOTIFY]
 
1083
                = AuCacheX(au_hinotify, sizeof(atomic_t) * au_hin_nignore);
 
1084
        if (unlikely(!au_cachep[AuCache_HINOTIFY]))
 
1085
                goto out;
 
1086
 
1005
1087
        in_handle = inotify_init(&aufs_inotify_ops);
1006
1088
        if (!IS_ERR(in_handle))
1007
1089
                return 0;
 
1090
 
 
1091
        au_hin_destroy_cache();
 
1092
 out:
1008
1093
        AuTraceErrPtr(in_handle);
1009
1094
        return PTR_ERR(in_handle);
1010
1095
}
1012
1097
void au_inotify_fin(void)
1013
1098
{
1014
1099
        inotify_destroy(in_handle);
 
1100
        if (au_cachep[AuCache_HINOTIFY])
 
1101
                au_hin_destroy_cache();
1015
1102
}