diff options
author | Jan Kara <jack@suse.cz> | 2014-12-12 19:58:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-13 15:42:53 -0500 |
commit | 0809ab69a2782afac8c4d7f3d35cd123050aab9a (patch) | |
tree | 373ed29c67e9ffd46a53d04e6fc68f4d96b6ba2d | |
parent | 820c12d5d6c0890bc93dd63893924a13041fdc35 (diff) |
fsnotify: unify inode and mount marks handling
There's a lot of common code in inode and mount marks handling. Factor it
out to a common helper function.
Signed-off-by: Jan Kara <jack@suse.cz>
Cc: Eric Paris <eparis@redhat.com>
Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/notify/dnotify/dnotify.c | 4 | ||||
-rw-r--r-- | fs/notify/fdinfo.c | 6 | ||||
-rw-r--r-- | fs/notify/fsnotify.c | 4 | ||||
-rw-r--r-- | fs/notify/fsnotify.h | 12 | ||||
-rw-r--r-- | fs/notify/inode_mark.c | 113 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 2 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 10 | ||||
-rw-r--r-- | fs/notify/mark.c | 89 | ||||
-rw-r--r-- | fs/notify/vfsmount_mark.c | 109 | ||||
-rw-r--r-- | include/linux/fsnotify_backend.h | 24 | ||||
-rw-r--r-- | kernel/audit_tree.c | 16 |
11 files changed, 160 insertions, 229 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index caaaf9dfe353..44523f4a6084 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -69,8 +69,8 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) | |||
69 | if (old_mask == new_mask) | 69 | if (old_mask == new_mask) |
70 | return; | 70 | return; |
71 | 71 | ||
72 | if (fsn_mark->i.inode) | 72 | if (fsn_mark->inode) |
73 | fsnotify_recalc_inode_mask(fsn_mark->i.inode); | 73 | fsnotify_recalc_inode_mask(fsn_mark->inode); |
74 | } | 74 | } |
75 | 75 | ||
76 | /* | 76 | /* |
diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c index 6ffd220eb14d..58b7cdb63da9 100644 --- a/fs/notify/fdinfo.c +++ b/fs/notify/fdinfo.c | |||
@@ -80,7 +80,7 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) | |||
80 | return; | 80 | return; |
81 | 81 | ||
82 | inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark); | 82 | inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark); |
83 | inode = igrab(mark->i.inode); | 83 | inode = igrab(mark->inode); |
84 | if (inode) { | 84 | if (inode) { |
85 | seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:%x ", | 85 | seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:%x ", |
86 | inode_mark->wd, inode->i_ino, inode->i_sb->s_dev, | 86 | inode_mark->wd, inode->i_ino, inode->i_sb->s_dev, |
@@ -112,7 +112,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) | |||
112 | mflags |= FAN_MARK_IGNORED_SURV_MODIFY; | 112 | mflags |= FAN_MARK_IGNORED_SURV_MODIFY; |
113 | 113 | ||
114 | if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { | 114 | if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { |
115 | inode = igrab(mark->i.inode); | 115 | inode = igrab(mark->inode); |
116 | if (!inode) | 116 | if (!inode) |
117 | return; | 117 | return; |
118 | seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ", | 118 | seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ", |
@@ -122,7 +122,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) | |||
122 | seq_putc(m, '\n'); | 122 | seq_putc(m, '\n'); |
123 | iput(inode); | 123 | iput(inode); |
124 | } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) { | 124 | } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) { |
125 | struct mount *mnt = real_mount(mark->m.mnt); | 125 | struct mount *mnt = real_mount(mark->mnt); |
126 | 126 | ||
127 | seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n", | 127 | seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n", |
128 | mnt->mnt_id, mflags, mark->mask, mark->ignored_mask); | 128 | mnt->mnt_id, mflags, mark->mask, mark->ignored_mask); |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 41e39102743a..dd3fb0b17be7 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -242,13 +242,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | |||
242 | 242 | ||
243 | if (inode_node) { | 243 | if (inode_node) { |
244 | inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), | 244 | inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), |
245 | struct fsnotify_mark, i.i_list); | 245 | struct fsnotify_mark, obj_list); |
246 | inode_group = inode_mark->group; | 246 | inode_group = inode_mark->group; |
247 | } | 247 | } |
248 | 248 | ||
249 | if (vfsmount_node) { | 249 | if (vfsmount_node) { |
250 | vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu), | 250 | vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu), |
251 | struct fsnotify_mark, m.m_list); | 251 | struct fsnotify_mark, obj_list); |
252 | vfsmount_group = vfsmount_mark->group; | 252 | vfsmount_group = vfsmount_mark->group; |
253 | } | 253 | } |
254 | 254 | ||
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h index 3b68b0ae0a97..13a00be516d2 100644 --- a/fs/notify/fsnotify.h +++ b/fs/notify/fsnotify.h | |||
@@ -12,12 +12,19 @@ extern void fsnotify_flush_notify(struct fsnotify_group *group); | |||
12 | /* protects reads of inode and vfsmount marks list */ | 12 | /* protects reads of inode and vfsmount marks list */ |
13 | extern struct srcu_struct fsnotify_mark_srcu; | 13 | extern struct srcu_struct fsnotify_mark_srcu; |
14 | 14 | ||
15 | /* Calculate mask of events for a list of marks */ | ||
16 | extern u32 fsnotify_recalc_mask(struct hlist_head *head); | ||
17 | |||
15 | /* compare two groups for sorting of marks lists */ | 18 | /* compare two groups for sorting of marks lists */ |
16 | extern int fsnotify_compare_groups(struct fsnotify_group *a, | 19 | extern int fsnotify_compare_groups(struct fsnotify_group *a, |
17 | struct fsnotify_group *b); | 20 | struct fsnotify_group *b); |
18 | 21 | ||
19 | extern void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *fsn_mark, | 22 | extern void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *fsn_mark, |
20 | __u32 mask); | 23 | __u32 mask); |
24 | /* Add mark to a proper place in mark list */ | ||
25 | extern int fsnotify_add_mark_list(struct hlist_head *head, | ||
26 | struct fsnotify_mark *mark, | ||
27 | int allow_dups); | ||
21 | /* add a mark to an inode */ | 28 | /* add a mark to an inode */ |
22 | extern int fsnotify_add_inode_mark(struct fsnotify_mark *mark, | 29 | extern int fsnotify_add_inode_mark(struct fsnotify_mark *mark, |
23 | struct fsnotify_group *group, struct inode *inode, | 30 | struct fsnotify_group *group, struct inode *inode, |
@@ -31,6 +38,11 @@ extern int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark, | |||
31 | extern void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark); | 38 | extern void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark); |
32 | /* inode specific destruction of a mark */ | 39 | /* inode specific destruction of a mark */ |
33 | extern void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark); | 40 | extern void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark); |
41 | /* Destroy all marks in the given list */ | ||
42 | extern void fsnotify_destroy_marks(struct list_head *to_free); | ||
43 | /* Find mark belonging to given group in the list of marks */ | ||
44 | extern struct fsnotify_mark *fsnotify_find_mark(struct hlist_head *head, | ||
45 | struct fsnotify_group *group); | ||
34 | /* run the list of all marks associated with inode and flag them to be freed */ | 46 | /* run the list of all marks associated with inode and flag them to be freed */ |
35 | extern void fsnotify_clear_marks_by_inode(struct inode *inode); | 47 | extern void fsnotify_clear_marks_by_inode(struct inode *inode); |
36 | /* run the list of all marks associated with vfsmount and flag them to be freed */ | 48 | /* run the list of all marks associated with vfsmount and flag them to be freed */ |
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index dfbf5447eea4..3daf513ee99e 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c | |||
@@ -31,28 +31,13 @@ | |||
31 | #include "../internal.h" | 31 | #include "../internal.h" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Recalculate the mask of events relevant to a given inode locked. | ||
35 | */ | ||
36 | static void fsnotify_recalc_inode_mask_locked(struct inode *inode) | ||
37 | { | ||
38 | struct fsnotify_mark *mark; | ||
39 | __u32 new_mask = 0; | ||
40 | |||
41 | assert_spin_locked(&inode->i_lock); | ||
42 | |||
43 | hlist_for_each_entry(mark, &inode->i_fsnotify_marks, i.i_list) | ||
44 | new_mask |= mark->mask; | ||
45 | inode->i_fsnotify_mask = new_mask; | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * Recalculate the inode->i_fsnotify_mask, or the mask of all FS_* event types | 34 | * Recalculate the inode->i_fsnotify_mask, or the mask of all FS_* event types |
50 | * any notifier is interested in hearing for this inode. | 35 | * any notifier is interested in hearing for this inode. |
51 | */ | 36 | */ |
52 | void fsnotify_recalc_inode_mask(struct inode *inode) | 37 | void fsnotify_recalc_inode_mask(struct inode *inode) |
53 | { | 38 | { |
54 | spin_lock(&inode->i_lock); | 39 | spin_lock(&inode->i_lock); |
55 | fsnotify_recalc_inode_mask_locked(inode); | 40 | inode->i_fsnotify_mask = fsnotify_recalc_mask(&inode->i_fsnotify_marks); |
56 | spin_unlock(&inode->i_lock); | 41 | spin_unlock(&inode->i_lock); |
57 | 42 | ||
58 | __fsnotify_update_child_dentry_flags(inode); | 43 | __fsnotify_update_child_dentry_flags(inode); |
@@ -60,23 +45,22 @@ void fsnotify_recalc_inode_mask(struct inode *inode) | |||
60 | 45 | ||
61 | void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark) | 46 | void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark) |
62 | { | 47 | { |
63 | struct inode *inode = mark->i.inode; | 48 | struct inode *inode = mark->inode; |
64 | 49 | ||
65 | BUG_ON(!mutex_is_locked(&mark->group->mark_mutex)); | 50 | BUG_ON(!mutex_is_locked(&mark->group->mark_mutex)); |
66 | assert_spin_locked(&mark->lock); | 51 | assert_spin_locked(&mark->lock); |
67 | 52 | ||
68 | spin_lock(&inode->i_lock); | 53 | spin_lock(&inode->i_lock); |
69 | 54 | ||
70 | hlist_del_init_rcu(&mark->i.i_list); | 55 | hlist_del_init_rcu(&mark->obj_list); |
71 | mark->i.inode = NULL; | 56 | mark->inode = NULL; |
72 | 57 | ||
73 | /* | 58 | /* |
74 | * this mark is now off the inode->i_fsnotify_marks list and we | 59 | * this mark is now off the inode->i_fsnotify_marks list and we |
75 | * hold the inode->i_lock, so this is the perfect time to update the | 60 | * hold the inode->i_lock, so this is the perfect time to update the |
76 | * inode->i_fsnotify_mask | 61 | * inode->i_fsnotify_mask |
77 | */ | 62 | */ |
78 | fsnotify_recalc_inode_mask_locked(inode); | 63 | inode->i_fsnotify_mask = fsnotify_recalc_mask(&inode->i_fsnotify_marks); |
79 | |||
80 | spin_unlock(&inode->i_lock); | 64 | spin_unlock(&inode->i_lock); |
81 | } | 65 | } |
82 | 66 | ||
@@ -85,30 +69,19 @@ void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark) | |||
85 | */ | 69 | */ |
86 | void fsnotify_clear_marks_by_inode(struct inode *inode) | 70 | void fsnotify_clear_marks_by_inode(struct inode *inode) |
87 | { | 71 | { |
88 | struct fsnotify_mark *mark, *lmark; | 72 | struct fsnotify_mark *mark; |
89 | struct hlist_node *n; | 73 | struct hlist_node *n; |
90 | LIST_HEAD(free_list); | 74 | LIST_HEAD(free_list); |
91 | 75 | ||
92 | spin_lock(&inode->i_lock); | 76 | spin_lock(&inode->i_lock); |
93 | hlist_for_each_entry_safe(mark, n, &inode->i_fsnotify_marks, i.i_list) { | 77 | hlist_for_each_entry_safe(mark, n, &inode->i_fsnotify_marks, obj_list) { |
94 | list_add(&mark->i.free_i_list, &free_list); | 78 | list_add(&mark->free_list, &free_list); |
95 | hlist_del_init_rcu(&mark->i.i_list); | 79 | hlist_del_init_rcu(&mark->obj_list); |
96 | fsnotify_get_mark(mark); | 80 | fsnotify_get_mark(mark); |
97 | } | 81 | } |
98 | spin_unlock(&inode->i_lock); | 82 | spin_unlock(&inode->i_lock); |
99 | 83 | ||
100 | list_for_each_entry_safe(mark, lmark, &free_list, i.free_i_list) { | 84 | fsnotify_destroy_marks(&free_list); |
101 | struct fsnotify_group *group; | ||
102 | |||
103 | spin_lock(&mark->lock); | ||
104 | fsnotify_get_group(mark->group); | ||
105 | group = mark->group; | ||
106 | spin_unlock(&mark->lock); | ||
107 | |||
108 | fsnotify_destroy_mark(mark, group); | ||
109 | fsnotify_put_mark(mark); | ||
110 | fsnotify_put_group(group); | ||
111 | } | ||
112 | } | 85 | } |
113 | 86 | ||
114 | /* | 87 | /* |
@@ -123,34 +96,13 @@ void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group) | |||
123 | * given a group and inode, find the mark associated with that combination. | 96 | * given a group and inode, find the mark associated with that combination. |
124 | * if found take a reference to that mark and return it, else return NULL | 97 | * if found take a reference to that mark and return it, else return NULL |
125 | */ | 98 | */ |
126 | static struct fsnotify_mark *fsnotify_find_inode_mark_locked( | ||
127 | struct fsnotify_group *group, | ||
128 | struct inode *inode) | ||
129 | { | ||
130 | struct fsnotify_mark *mark; | ||
131 | |||
132 | assert_spin_locked(&inode->i_lock); | ||
133 | |||
134 | hlist_for_each_entry(mark, &inode->i_fsnotify_marks, i.i_list) { | ||
135 | if (mark->group == group) { | ||
136 | fsnotify_get_mark(mark); | ||
137 | return mark; | ||
138 | } | ||
139 | } | ||
140 | return NULL; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * given a group and inode, find the mark associated with that combination. | ||
145 | * if found take a reference to that mark and return it, else return NULL | ||
146 | */ | ||
147 | struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, | 99 | struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, |
148 | struct inode *inode) | 100 | struct inode *inode) |
149 | { | 101 | { |
150 | struct fsnotify_mark *mark; | 102 | struct fsnotify_mark *mark; |
151 | 103 | ||
152 | spin_lock(&inode->i_lock); | 104 | spin_lock(&inode->i_lock); |
153 | mark = fsnotify_find_inode_mark_locked(group, inode); | 105 | mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group); |
154 | spin_unlock(&inode->i_lock); | 106 | spin_unlock(&inode->i_lock); |
155 | 107 | ||
156 | return mark; | 108 | return mark; |
@@ -168,10 +120,10 @@ void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *mark, | |||
168 | assert_spin_locked(&mark->lock); | 120 | assert_spin_locked(&mark->lock); |
169 | 121 | ||
170 | if (mask && | 122 | if (mask && |
171 | mark->i.inode && | 123 | mark->inode && |
172 | !(mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) { | 124 | !(mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) { |
173 | mark->flags |= FSNOTIFY_MARK_FLAG_OBJECT_PINNED; | 125 | mark->flags |= FSNOTIFY_MARK_FLAG_OBJECT_PINNED; |
174 | inode = igrab(mark->i.inode); | 126 | inode = igrab(mark->inode); |
175 | /* | 127 | /* |
176 | * we shouldn't be able to get here if the inode wasn't | 128 | * we shouldn't be able to get here if the inode wasn't |
177 | * already safely held in memory. But bug in case it | 129 | * already safely held in memory. But bug in case it |
@@ -192,9 +144,7 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark, | |||
192 | struct fsnotify_group *group, struct inode *inode, | 144 | struct fsnotify_group *group, struct inode *inode, |
193 | int allow_dups) | 145 | int allow_dups) |
194 | { | 146 | { |
195 | struct fsnotify_mark *lmark, *last = NULL; | 147 | int ret; |
196 | int ret = 0; | ||
197 | int cmp; | ||
198 | 148 | ||
199 | mark->flags |= FSNOTIFY_MARK_FLAG_INODE; | 149 | mark->flags |= FSNOTIFY_MARK_FLAG_INODE; |
200 | 150 | ||
@@ -202,37 +152,10 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark, | |||
202 | assert_spin_locked(&mark->lock); | 152 | assert_spin_locked(&mark->lock); |
203 | 153 | ||
204 | spin_lock(&inode->i_lock); | 154 | spin_lock(&inode->i_lock); |
205 | 155 | mark->inode = inode; | |
206 | mark->i.inode = inode; | 156 | ret = fsnotify_add_mark_list(&inode->i_fsnotify_marks, mark, |
207 | 157 | allow_dups); | |
208 | /* is mark the first mark? */ | 158 | inode->i_fsnotify_mask = fsnotify_recalc_mask(&inode->i_fsnotify_marks); |
209 | if (hlist_empty(&inode->i_fsnotify_marks)) { | ||
210 | hlist_add_head_rcu(&mark->i.i_list, &inode->i_fsnotify_marks); | ||
211 | goto out; | ||
212 | } | ||
213 | |||
214 | /* should mark be in the middle of the current list? */ | ||
215 | hlist_for_each_entry(lmark, &inode->i_fsnotify_marks, i.i_list) { | ||
216 | last = lmark; | ||
217 | |||
218 | if ((lmark->group == group) && !allow_dups) { | ||
219 | ret = -EEXIST; | ||
220 | goto out; | ||
221 | } | ||
222 | |||
223 | cmp = fsnotify_compare_groups(lmark->group, mark->group); | ||
224 | if (cmp < 0) | ||
225 | continue; | ||
226 | |||
227 | hlist_add_before_rcu(&mark->i.i_list, &lmark->i.i_list); | ||
228 | goto out; | ||
229 | } | ||
230 | |||
231 | BUG_ON(last == NULL); | ||
232 | /* mark should be the last entry. last is the current last entry */ | ||
233 | hlist_add_behind_rcu(&mark->i.i_list, &last->i.i_list); | ||
234 | out: | ||
235 | fsnotify_recalc_inode_mask_locked(inode); | ||
236 | spin_unlock(&inode->i_lock); | 159 | spin_unlock(&inode->i_lock); |
237 | 160 | ||
238 | return ret; | 161 | return ret; |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 7d888d77d59a..2cd900c2c737 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -156,7 +156,7 @@ static int idr_callback(int id, void *p, void *data) | |||
156 | */ | 156 | */ |
157 | if (fsn_mark) | 157 | if (fsn_mark) |
158 | printk(KERN_WARNING "fsn_mark->group=%p inode=%p wd=%d\n", | 158 | printk(KERN_WARNING "fsn_mark->group=%p inode=%p wd=%d\n", |
159 | fsn_mark->group, fsn_mark->i.inode, i_mark->wd); | 159 | fsn_mark->group, fsn_mark->inode, i_mark->wd); |
160 | return 0; | 160 | return 0; |
161 | } | 161 | } |
162 | 162 | ||
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 283aa312d745..450648697433 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -433,7 +433,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, | |||
433 | if (wd == -1) { | 433 | if (wd == -1) { |
434 | WARN_ONCE(1, "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" | 434 | WARN_ONCE(1, "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" |
435 | " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, | 435 | " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, |
436 | i_mark->fsn_mark.group, i_mark->fsn_mark.i.inode); | 436 | i_mark->fsn_mark.group, i_mark->fsn_mark.inode); |
437 | goto out; | 437 | goto out; |
438 | } | 438 | } |
439 | 439 | ||
@@ -442,7 +442,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, | |||
442 | if (unlikely(!found_i_mark)) { | 442 | if (unlikely(!found_i_mark)) { |
443 | WARN_ONCE(1, "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" | 443 | WARN_ONCE(1, "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" |
444 | " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, | 444 | " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, |
445 | i_mark->fsn_mark.group, i_mark->fsn_mark.i.inode); | 445 | i_mark->fsn_mark.group, i_mark->fsn_mark.inode); |
446 | goto out; | 446 | goto out; |
447 | } | 447 | } |
448 | 448 | ||
@@ -456,9 +456,9 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, | |||
456 | "mark->inode=%p found_i_mark=%p found_i_mark->wd=%d " | 456 | "mark->inode=%p found_i_mark=%p found_i_mark->wd=%d " |
457 | "found_i_mark->group=%p found_i_mark->inode=%p\n", | 457 | "found_i_mark->group=%p found_i_mark->inode=%p\n", |
458 | __func__, i_mark, i_mark->wd, i_mark->fsn_mark.group, | 458 | __func__, i_mark, i_mark->wd, i_mark->fsn_mark.group, |
459 | i_mark->fsn_mark.i.inode, found_i_mark, found_i_mark->wd, | 459 | i_mark->fsn_mark.inode, found_i_mark, found_i_mark->wd, |
460 | found_i_mark->fsn_mark.group, | 460 | found_i_mark->fsn_mark.group, |
461 | found_i_mark->fsn_mark.i.inode); | 461 | found_i_mark->fsn_mark.inode); |
462 | goto out; | 462 | goto out; |
463 | } | 463 | } |
464 | 464 | ||
@@ -470,7 +470,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, | |||
470 | if (unlikely(atomic_read(&i_mark->fsn_mark.refcnt) < 3)) { | 470 | if (unlikely(atomic_read(&i_mark->fsn_mark.refcnt) < 3)) { |
471 | printk(KERN_ERR "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" | 471 | printk(KERN_ERR "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" |
472 | " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, | 472 | " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, |
473 | i_mark->fsn_mark.group, i_mark->fsn_mark.i.inode); | 473 | i_mark->fsn_mark.group, i_mark->fsn_mark.inode); |
474 | /* we can't really recover with bad ref cnting.. */ | 474 | /* we can't really recover with bad ref cnting.. */ |
475 | BUG(); | 475 | BUG(); |
476 | } | 476 | } |
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 34c38fabf514..3942d5c9eb8d 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c | |||
@@ -110,6 +110,17 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | 112 | ||
113 | /* Calculate mask of events for a list of marks */ | ||
114 | u32 fsnotify_recalc_mask(struct hlist_head *head) | ||
115 | { | ||
116 | u32 new_mask = 0; | ||
117 | struct fsnotify_mark *mark; | ||
118 | |||
119 | hlist_for_each_entry(mark, head, obj_list) | ||
120 | new_mask |= mark->mask; | ||
121 | return new_mask; | ||
122 | } | ||
123 | |||
113 | /* | 124 | /* |
114 | * Any time a mark is getting freed we end up here. | 125 | * Any time a mark is getting freed we end up here. |
115 | * The caller had better be holding a reference to this mark so we don't actually | 126 | * The caller had better be holding a reference to this mark so we don't actually |
@@ -133,7 +144,7 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark, | |||
133 | mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; | 144 | mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; |
134 | 145 | ||
135 | if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { | 146 | if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { |
136 | inode = mark->i.inode; | 147 | inode = mark->inode; |
137 | fsnotify_destroy_inode_mark(mark); | 148 | fsnotify_destroy_inode_mark(mark); |
138 | } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) | 149 | } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) |
139 | fsnotify_destroy_vfsmount_mark(mark); | 150 | fsnotify_destroy_vfsmount_mark(mark); |
@@ -192,6 +203,27 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, | |||
192 | mutex_unlock(&group->mark_mutex); | 203 | mutex_unlock(&group->mark_mutex); |
193 | } | 204 | } |
194 | 205 | ||
206 | /* | ||
207 | * Destroy all marks in the given list. The marks must be already detached from | ||
208 | * the original inode / vfsmount. | ||
209 | */ | ||
210 | void fsnotify_destroy_marks(struct list_head *to_free) | ||
211 | { | ||
212 | struct fsnotify_mark *mark, *lmark; | ||
213 | struct fsnotify_group *group; | ||
214 | |||
215 | list_for_each_entry_safe(mark, lmark, to_free, free_list) { | ||
216 | spin_lock(&mark->lock); | ||
217 | fsnotify_get_group(mark->group); | ||
218 | group = mark->group; | ||
219 | spin_unlock(&mark->lock); | ||
220 | |||
221 | fsnotify_destroy_mark(mark, group); | ||
222 | fsnotify_put_mark(mark); | ||
223 | fsnotify_put_group(group); | ||
224 | } | ||
225 | } | ||
226 | |||
195 | void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) | 227 | void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) |
196 | { | 228 | { |
197 | assert_spin_locked(&mark->lock); | 229 | assert_spin_locked(&mark->lock); |
@@ -245,6 +277,39 @@ int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b) | |||
245 | return -1; | 277 | return -1; |
246 | } | 278 | } |
247 | 279 | ||
280 | /* Add mark into proper place in given list of marks */ | ||
281 | int fsnotify_add_mark_list(struct hlist_head *head, struct fsnotify_mark *mark, | ||
282 | int allow_dups) | ||
283 | { | ||
284 | struct fsnotify_mark *lmark, *last = NULL; | ||
285 | int cmp; | ||
286 | |||
287 | /* is mark the first mark? */ | ||
288 | if (hlist_empty(head)) { | ||
289 | hlist_add_head_rcu(&mark->obj_list, head); | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /* should mark be in the middle of the current list? */ | ||
294 | hlist_for_each_entry(lmark, head, obj_list) { | ||
295 | last = lmark; | ||
296 | |||
297 | if ((lmark->group == mark->group) && !allow_dups) | ||
298 | return -EEXIST; | ||
299 | |||
300 | cmp = fsnotify_compare_groups(lmark->group, mark->group); | ||
301 | if (cmp >= 0) { | ||
302 | hlist_add_before_rcu(&mark->obj_list, &lmark->obj_list); | ||
303 | return 0; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | BUG_ON(last == NULL); | ||
308 | /* mark should be the last entry. last is the current last entry */ | ||
309 | hlist_add_behind_rcu(&mark->obj_list, &last->obj_list); | ||
310 | return 0; | ||
311 | } | ||
312 | |||
248 | /* | 313 | /* |
249 | * Attach an initialized mark to a given group and fs object. | 314 | * Attach an initialized mark to a given group and fs object. |
250 | * These marks may be used for the fsnotify backend to determine which | 315 | * These marks may be used for the fsnotify backend to determine which |
@@ -323,6 +388,24 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, | |||
323 | } | 388 | } |
324 | 389 | ||
325 | /* | 390 | /* |
391 | * Given a list of marks, find the mark associated with given group. If found | ||
392 | * take a reference to that mark and return it, else return NULL. | ||
393 | */ | ||
394 | struct fsnotify_mark *fsnotify_find_mark(struct hlist_head *head, | ||
395 | struct fsnotify_group *group) | ||
396 | { | ||
397 | struct fsnotify_mark *mark; | ||
398 | |||
399 | hlist_for_each_entry(mark, head, obj_list) { | ||
400 | if (mark->group == group) { | ||
401 | fsnotify_get_mark(mark); | ||
402 | return mark; | ||
403 | } | ||
404 | } | ||
405 | return NULL; | ||
406 | } | ||
407 | |||
408 | /* | ||
326 | * clear any marks in a group in which mark->flags & flags is true | 409 | * clear any marks in a group in which mark->flags & flags is true |
327 | */ | 410 | */ |
328 | void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, | 411 | void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, |
@@ -352,8 +435,8 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group) | |||
352 | void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old) | 435 | void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old) |
353 | { | 436 | { |
354 | assert_spin_locked(&old->lock); | 437 | assert_spin_locked(&old->lock); |
355 | new->i.inode = old->i.inode; | 438 | new->inode = old->inode; |
356 | new->m.mnt = old->m.mnt; | 439 | new->mnt = old->mnt; |
357 | if (old->group) | 440 | if (old->group) |
358 | fsnotify_get_group(old->group); | 441 | fsnotify_get_group(old->group); |
359 | new->group = old->group; | 442 | new->group = old->group; |
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c index faefa72a11eb..326b148e623c 100644 --- a/fs/notify/vfsmount_mark.c +++ b/fs/notify/vfsmount_mark.c | |||
@@ -32,31 +32,20 @@ | |||
32 | 32 | ||
33 | void fsnotify_clear_marks_by_mount(struct vfsmount *mnt) | 33 | void fsnotify_clear_marks_by_mount(struct vfsmount *mnt) |
34 | { | 34 | { |
35 | struct fsnotify_mark *mark, *lmark; | 35 | struct fsnotify_mark *mark; |
36 | struct hlist_node *n; | 36 | struct hlist_node *n; |
37 | struct mount *m = real_mount(mnt); | 37 | struct mount *m = real_mount(mnt); |
38 | LIST_HEAD(free_list); | 38 | LIST_HEAD(free_list); |
39 | 39 | ||
40 | spin_lock(&mnt->mnt_root->d_lock); | 40 | spin_lock(&mnt->mnt_root->d_lock); |
41 | hlist_for_each_entry_safe(mark, n, &m->mnt_fsnotify_marks, m.m_list) { | 41 | hlist_for_each_entry_safe(mark, n, &m->mnt_fsnotify_marks, obj_list) { |
42 | list_add(&mark->m.free_m_list, &free_list); | 42 | list_add(&mark->free_list, &free_list); |
43 | hlist_del_init_rcu(&mark->m.m_list); | 43 | hlist_del_init_rcu(&mark->obj_list); |
44 | fsnotify_get_mark(mark); | 44 | fsnotify_get_mark(mark); |
45 | } | 45 | } |
46 | spin_unlock(&mnt->mnt_root->d_lock); | 46 | spin_unlock(&mnt->mnt_root->d_lock); |
47 | 47 | ||
48 | list_for_each_entry_safe(mark, lmark, &free_list, m.free_m_list) { | 48 | fsnotify_destroy_marks(&free_list); |
49 | struct fsnotify_group *group; | ||
50 | |||
51 | spin_lock(&mark->lock); | ||
52 | fsnotify_get_group(mark->group); | ||
53 | group = mark->group; | ||
54 | spin_unlock(&mark->lock); | ||
55 | |||
56 | fsnotify_destroy_mark(mark, group); | ||
57 | fsnotify_put_mark(mark); | ||
58 | fsnotify_put_group(group); | ||
59 | } | ||
60 | } | 49 | } |
61 | 50 | ||
62 | void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group) | 51 | void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group) |
@@ -65,66 +54,35 @@ void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group) | |||
65 | } | 54 | } |
66 | 55 | ||
67 | /* | 56 | /* |
68 | * Recalculate the mask of events relevant to a given vfsmount locked. | ||
69 | */ | ||
70 | static void fsnotify_recalc_vfsmount_mask_locked(struct vfsmount *mnt) | ||
71 | { | ||
72 | struct mount *m = real_mount(mnt); | ||
73 | struct fsnotify_mark *mark; | ||
74 | __u32 new_mask = 0; | ||
75 | |||
76 | assert_spin_locked(&mnt->mnt_root->d_lock); | ||
77 | |||
78 | hlist_for_each_entry(mark, &m->mnt_fsnotify_marks, m.m_list) | ||
79 | new_mask |= mark->mask; | ||
80 | m->mnt_fsnotify_mask = new_mask; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Recalculate the mnt->mnt_fsnotify_mask, or the mask of all FS_* event types | 57 | * Recalculate the mnt->mnt_fsnotify_mask, or the mask of all FS_* event types |
85 | * any notifier is interested in hearing for this mount point | 58 | * any notifier is interested in hearing for this mount point |
86 | */ | 59 | */ |
87 | void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt) | 60 | void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt) |
88 | { | 61 | { |
62 | struct mount *m = real_mount(mnt); | ||
63 | |||
89 | spin_lock(&mnt->mnt_root->d_lock); | 64 | spin_lock(&mnt->mnt_root->d_lock); |
90 | fsnotify_recalc_vfsmount_mask_locked(mnt); | 65 | m->mnt_fsnotify_mask = fsnotify_recalc_mask(&m->mnt_fsnotify_marks); |
91 | spin_unlock(&mnt->mnt_root->d_lock); | 66 | spin_unlock(&mnt->mnt_root->d_lock); |
92 | } | 67 | } |
93 | 68 | ||
94 | void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark) | 69 | void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark) |
95 | { | 70 | { |
96 | struct vfsmount *mnt = mark->m.mnt; | 71 | struct vfsmount *mnt = mark->mnt; |
72 | struct mount *m = real_mount(mnt); | ||
97 | 73 | ||
98 | BUG_ON(!mutex_is_locked(&mark->group->mark_mutex)); | 74 | BUG_ON(!mutex_is_locked(&mark->group->mark_mutex)); |
99 | assert_spin_locked(&mark->lock); | 75 | assert_spin_locked(&mark->lock); |
100 | 76 | ||
101 | spin_lock(&mnt->mnt_root->d_lock); | 77 | spin_lock(&mnt->mnt_root->d_lock); |
102 | 78 | ||
103 | hlist_del_init_rcu(&mark->m.m_list); | 79 | hlist_del_init_rcu(&mark->obj_list); |
104 | mark->m.mnt = NULL; | 80 | mark->mnt = NULL; |
105 | |||
106 | fsnotify_recalc_vfsmount_mask_locked(mnt); | ||
107 | 81 | ||
82 | m->mnt_fsnotify_mask = fsnotify_recalc_mask(&m->mnt_fsnotify_marks); | ||
108 | spin_unlock(&mnt->mnt_root->d_lock); | 83 | spin_unlock(&mnt->mnt_root->d_lock); |
109 | } | 84 | } |
110 | 85 | ||
111 | static struct fsnotify_mark *fsnotify_find_vfsmount_mark_locked(struct fsnotify_group *group, | ||
112 | struct vfsmount *mnt) | ||
113 | { | ||
114 | struct mount *m = real_mount(mnt); | ||
115 | struct fsnotify_mark *mark; | ||
116 | |||
117 | assert_spin_locked(&mnt->mnt_root->d_lock); | ||
118 | |||
119 | hlist_for_each_entry(mark, &m->mnt_fsnotify_marks, m.m_list) { | ||
120 | if (mark->group == group) { | ||
121 | fsnotify_get_mark(mark); | ||
122 | return mark; | ||
123 | } | ||
124 | } | ||
125 | return NULL; | ||
126 | } | ||
127 | |||
128 | /* | 86 | /* |
129 | * given a group and vfsmount, find the mark associated with that combination. | 87 | * given a group and vfsmount, find the mark associated with that combination. |
130 | * if found take a reference to that mark and return it, else return NULL | 88 | * if found take a reference to that mark and return it, else return NULL |
@@ -132,10 +90,11 @@ static struct fsnotify_mark *fsnotify_find_vfsmount_mark_locked(struct fsnotify_ | |||
132 | struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, | 90 | struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, |
133 | struct vfsmount *mnt) | 91 | struct vfsmount *mnt) |
134 | { | 92 | { |
93 | struct mount *m = real_mount(mnt); | ||
135 | struct fsnotify_mark *mark; | 94 | struct fsnotify_mark *mark; |
136 | 95 | ||
137 | spin_lock(&mnt->mnt_root->d_lock); | 96 | spin_lock(&mnt->mnt_root->d_lock); |
138 | mark = fsnotify_find_vfsmount_mark_locked(group, mnt); | 97 | mark = fsnotify_find_mark(&m->mnt_fsnotify_marks, group); |
139 | spin_unlock(&mnt->mnt_root->d_lock); | 98 | spin_unlock(&mnt->mnt_root->d_lock); |
140 | 99 | ||
141 | return mark; | 100 | return mark; |
@@ -151,9 +110,7 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark, | |||
151 | int allow_dups) | 110 | int allow_dups) |
152 | { | 111 | { |
153 | struct mount *m = real_mount(mnt); | 112 | struct mount *m = real_mount(mnt); |
154 | struct fsnotify_mark *lmark, *last = NULL; | 113 | int ret; |
155 | int ret = 0; | ||
156 | int cmp; | ||
157 | 114 | ||
158 | mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT; | 115 | mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT; |
159 | 116 | ||
@@ -161,37 +118,9 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark, | |||
161 | assert_spin_locked(&mark->lock); | 118 | assert_spin_locked(&mark->lock); |
162 | 119 | ||
163 | spin_lock(&mnt->mnt_root->d_lock); | 120 | spin_lock(&mnt->mnt_root->d_lock); |
164 | 121 | mark->mnt = mnt; | |
165 | mark->m.mnt = mnt; | 122 | ret = fsnotify_add_mark_list(&m->mnt_fsnotify_marks, mark, allow_dups); |
166 | 123 | m->mnt_fsnotify_mask = fsnotify_recalc_mask(&m->mnt_fsnotify_marks); | |
167 | /* is mark the first mark? */ | ||
168 | if (hlist_empty(&m->mnt_fsnotify_marks)) { | ||
169 | hlist_add_head_rcu(&mark->m.m_list, &m->mnt_fsnotify_marks); | ||
170 | goto out; | ||
171 | } | ||
172 | |||
173 | /* should mark be in the middle of the current list? */ | ||
174 | hlist_for_each_entry(lmark, &m->mnt_fsnotify_marks, m.m_list) { | ||
175 | last = lmark; | ||
176 | |||
177 | if ((lmark->group == group) && !allow_dups) { | ||
178 | ret = -EEXIST; | ||
179 | goto out; | ||
180 | } | ||
181 | |||
182 | cmp = fsnotify_compare_groups(lmark->group, mark->group); | ||
183 | if (cmp < 0) | ||
184 | continue; | ||
185 | |||
186 | hlist_add_before_rcu(&mark->m.m_list, &lmark->m.m_list); | ||
187 | goto out; | ||
188 | } | ||
189 | |||
190 | BUG_ON(last == NULL); | ||
191 | /* mark should be the last entry. last is the current last entry */ | ||
192 | hlist_add_behind_rcu(&mark->m.m_list, &last->m.m_list); | ||
193 | out: | ||
194 | fsnotify_recalc_vfsmount_mask_locked(mnt); | ||
195 | spin_unlock(&mnt->mnt_root->d_lock); | 124 | spin_unlock(&mnt->mnt_root->d_lock); |
196 | 125 | ||
197 | return ret; | 126 | return ret; |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index ca060d7c4fa6..442847a02b8f 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -197,24 +197,6 @@ struct fsnotify_group { | |||
197 | #define FSNOTIFY_EVENT_INODE 2 | 197 | #define FSNOTIFY_EVENT_INODE 2 |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * Inode specific fields in an fsnotify_mark | ||
201 | */ | ||
202 | struct fsnotify_inode_mark { | ||
203 | struct inode *inode; /* inode this mark is associated with */ | ||
204 | struct hlist_node i_list; /* list of marks by inode->i_fsnotify_marks */ | ||
205 | struct list_head free_i_list; /* tmp list used when freeing this mark */ | ||
206 | }; | ||
207 | |||
208 | /* | ||
209 | * Mount point specific fields in an fsnotify_mark | ||
210 | */ | ||
211 | struct fsnotify_vfsmount_mark { | ||
212 | struct vfsmount *mnt; /* vfsmount this mark is associated with */ | ||
213 | struct hlist_node m_list; /* list of marks by inode->i_fsnotify_marks */ | ||
214 | struct list_head free_m_list; /* tmp list used when freeing this mark */ | ||
215 | }; | ||
216 | |||
217 | /* | ||
218 | * a mark is simply an object attached to an in core inode which allows an | 200 | * a mark is simply an object attached to an in core inode which allows an |
219 | * fsnotify listener to indicate they are either no longer interested in events | 201 | * fsnotify listener to indicate they are either no longer interested in events |
220 | * of a type matching mask or only interested in those events. | 202 | * of a type matching mask or only interested in those events. |
@@ -232,9 +214,11 @@ struct fsnotify_mark { | |||
232 | struct fsnotify_group *group; /* group this mark is for */ | 214 | struct fsnotify_group *group; /* group this mark is for */ |
233 | struct list_head g_list; /* list of marks by group->i_fsnotify_marks */ | 215 | struct list_head g_list; /* list of marks by group->i_fsnotify_marks */ |
234 | spinlock_t lock; /* protect group and inode */ | 216 | spinlock_t lock; /* protect group and inode */ |
217 | struct hlist_node obj_list; /* list of marks for inode / vfsmount */ | ||
218 | struct list_head free_list; /* tmp list used when freeing this mark */ | ||
235 | union { | 219 | union { |
236 | struct fsnotify_inode_mark i; | 220 | struct inode *inode; /* inode this mark is associated with */ |
237 | struct fsnotify_vfsmount_mark m; | 221 | struct vfsmount *mnt; /* vfsmount this mark is associated with */ |
238 | }; | 222 | }; |
239 | __u32 ignored_mask; /* events types to ignore */ | 223 | __u32 ignored_mask; /* events types to ignore */ |
240 | #define FSNOTIFY_MARK_FLAG_INODE 0x01 | 224 | #define FSNOTIFY_MARK_FLAG_INODE 0x01 |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 80f29e015570..2e0c97427b33 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
@@ -174,9 +174,9 @@ static void insert_hash(struct audit_chunk *chunk) | |||
174 | struct fsnotify_mark *entry = &chunk->mark; | 174 | struct fsnotify_mark *entry = &chunk->mark; |
175 | struct list_head *list; | 175 | struct list_head *list; |
176 | 176 | ||
177 | if (!entry->i.inode) | 177 | if (!entry->inode) |
178 | return; | 178 | return; |
179 | list = chunk_hash(entry->i.inode); | 179 | list = chunk_hash(entry->inode); |
180 | list_add_rcu(&chunk->hash, list); | 180 | list_add_rcu(&chunk->hash, list); |
181 | } | 181 | } |
182 | 182 | ||
@@ -188,7 +188,7 @@ struct audit_chunk *audit_tree_lookup(const struct inode *inode) | |||
188 | 188 | ||
189 | list_for_each_entry_rcu(p, list, hash) { | 189 | list_for_each_entry_rcu(p, list, hash) { |
190 | /* mark.inode may have gone NULL, but who cares? */ | 190 | /* mark.inode may have gone NULL, but who cares? */ |
191 | if (p->mark.i.inode == inode) { | 191 | if (p->mark.inode == inode) { |
192 | atomic_long_inc(&p->refs); | 192 | atomic_long_inc(&p->refs); |
193 | return p; | 193 | return p; |
194 | } | 194 | } |
@@ -231,7 +231,7 @@ static void untag_chunk(struct node *p) | |||
231 | new = alloc_chunk(size); | 231 | new = alloc_chunk(size); |
232 | 232 | ||
233 | spin_lock(&entry->lock); | 233 | spin_lock(&entry->lock); |
234 | if (chunk->dead || !entry->i.inode) { | 234 | if (chunk->dead || !entry->inode) { |
235 | spin_unlock(&entry->lock); | 235 | spin_unlock(&entry->lock); |
236 | if (new) | 236 | if (new) |
237 | free_chunk(new); | 237 | free_chunk(new); |
@@ -258,7 +258,7 @@ static void untag_chunk(struct node *p) | |||
258 | goto Fallback; | 258 | goto Fallback; |
259 | 259 | ||
260 | fsnotify_duplicate_mark(&new->mark, entry); | 260 | fsnotify_duplicate_mark(&new->mark, entry); |
261 | if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) { | 261 | if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.inode, NULL, 1)) { |
262 | fsnotify_put_mark(&new->mark); | 262 | fsnotify_put_mark(&new->mark); |
263 | goto Fallback; | 263 | goto Fallback; |
264 | } | 264 | } |
@@ -386,7 +386,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
386 | chunk_entry = &chunk->mark; | 386 | chunk_entry = &chunk->mark; |
387 | 387 | ||
388 | spin_lock(&old_entry->lock); | 388 | spin_lock(&old_entry->lock); |
389 | if (!old_entry->i.inode) { | 389 | if (!old_entry->inode) { |
390 | /* old_entry is being shot, lets just lie */ | 390 | /* old_entry is being shot, lets just lie */ |
391 | spin_unlock(&old_entry->lock); | 391 | spin_unlock(&old_entry->lock); |
392 | fsnotify_put_mark(old_entry); | 392 | fsnotify_put_mark(old_entry); |
@@ -395,7 +395,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
395 | } | 395 | } |
396 | 396 | ||
397 | fsnotify_duplicate_mark(chunk_entry, old_entry); | 397 | fsnotify_duplicate_mark(chunk_entry, old_entry); |
398 | if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, NULL, 1)) { | 398 | if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->inode, NULL, 1)) { |
399 | spin_unlock(&old_entry->lock); | 399 | spin_unlock(&old_entry->lock); |
400 | fsnotify_put_mark(chunk_entry); | 400 | fsnotify_put_mark(chunk_entry); |
401 | fsnotify_put_mark(old_entry); | 401 | fsnotify_put_mark(old_entry); |
@@ -611,7 +611,7 @@ void audit_trim_trees(void) | |||
611 | list_for_each_entry(node, &tree->chunks, list) { | 611 | list_for_each_entry(node, &tree->chunks, list) { |
612 | struct audit_chunk *chunk = find_chunk(node); | 612 | struct audit_chunk *chunk = find_chunk(node); |
613 | /* this could be NULL if the watch is dying else where... */ | 613 | /* this could be NULL if the watch is dying else where... */ |
614 | struct inode *inode = chunk->mark.i.inode; | 614 | struct inode *inode = chunk->mark.inode; |
615 | node->index |= 1U<<31; | 615 | node->index |= 1U<<31; |
616 | if (iterate_mounts(compare_root, inode, root_mnt)) | 616 | if (iterate_mounts(compare_root, inode, root_mnt)) |
617 | node->index &= ~(1U<<31); | 617 | node->index &= ~(1U<<31); |