diff options
-rw-r--r-- | fs/notify/dnotify/dnotify.c | 4 | ||||
-rw-r--r-- | fs/notify/inode_mark.c | 28 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 2 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 10 | ||||
-rw-r--r-- | include/linux/fsnotify_backend.h | 17 | ||||
-rw-r--r-- | kernel/audit_tree.c | 16 |
6 files changed, 43 insertions, 34 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 9eddafa4c7ba..fc3a9dc567c5 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -70,8 +70,8 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark_entry *entry) | |||
70 | if (old_mask == new_mask) | 70 | if (old_mask == new_mask) |
71 | return; | 71 | return; |
72 | 72 | ||
73 | if (entry->inode) | 73 | if (entry->i.inode) |
74 | fsnotify_recalc_inode_mask(entry->inode); | 74 | fsnotify_recalc_inode_mask(entry->i.inode); |
75 | } | 75 | } |
76 | 76 | ||
77 | /* | 77 | /* |
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index beffebb64627..6731408c49f7 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c | |||
@@ -117,7 +117,7 @@ static void fsnotify_recalc_inode_mask_locked(struct inode *inode) | |||
117 | 117 | ||
118 | assert_spin_locked(&inode->i_lock); | 118 | assert_spin_locked(&inode->i_lock); |
119 | 119 | ||
120 | hlist_for_each_entry(entry, pos, &inode->i_fsnotify_mark_entries, i_list) | 120 | hlist_for_each_entry(entry, pos, &inode->i_fsnotify_mark_entries, i.i_list) |
121 | new_mask |= entry->mask; | 121 | new_mask |= entry->mask; |
122 | inode->i_fsnotify_mask = new_mask; | 122 | inode->i_fsnotify_mask = new_mask; |
123 | } | 123 | } |
@@ -148,7 +148,7 @@ void fsnotify_destroy_mark_by_entry(struct fsnotify_mark_entry *entry) | |||
148 | spin_lock(&entry->lock); | 148 | spin_lock(&entry->lock); |
149 | 149 | ||
150 | group = entry->group; | 150 | group = entry->group; |
151 | inode = entry->inode; | 151 | inode = entry->i.inode; |
152 | 152 | ||
153 | BUG_ON(group && !inode); | 153 | BUG_ON(group && !inode); |
154 | BUG_ON(!group && inode); | 154 | BUG_ON(!group && inode); |
@@ -165,8 +165,8 @@ void fsnotify_destroy_mark_by_entry(struct fsnotify_mark_entry *entry) | |||
165 | spin_lock(&group->mark_lock); | 165 | spin_lock(&group->mark_lock); |
166 | spin_lock(&inode->i_lock); | 166 | spin_lock(&inode->i_lock); |
167 | 167 | ||
168 | hlist_del_init(&entry->i_list); | 168 | hlist_del_init(&entry->i.i_list); |
169 | entry->inode = NULL; | 169 | entry->i.inode = NULL; |
170 | 170 | ||
171 | list_del_init(&entry->g_list); | 171 | list_del_init(&entry->g_list); |
172 | entry->group = NULL; | 172 | entry->group = NULL; |
@@ -248,14 +248,14 @@ void fsnotify_clear_marks_by_inode(struct inode *inode) | |||
248 | LIST_HEAD(free_list); | 248 | LIST_HEAD(free_list); |
249 | 249 | ||
250 | spin_lock(&inode->i_lock); | 250 | spin_lock(&inode->i_lock); |
251 | hlist_for_each_entry_safe(entry, pos, n, &inode->i_fsnotify_mark_entries, i_list) { | 251 | hlist_for_each_entry_safe(entry, pos, n, &inode->i_fsnotify_mark_entries, i.i_list) { |
252 | list_add(&entry->free_i_list, &free_list); | 252 | list_add(&entry->i.free_i_list, &free_list); |
253 | hlist_del_init(&entry->i_list); | 253 | hlist_del_init(&entry->i.i_list); |
254 | fsnotify_get_mark(entry); | 254 | fsnotify_get_mark(entry); |
255 | } | 255 | } |
256 | spin_unlock(&inode->i_lock); | 256 | spin_unlock(&inode->i_lock); |
257 | 257 | ||
258 | list_for_each_entry_safe(entry, lentry, &free_list, free_i_list) { | 258 | list_for_each_entry_safe(entry, lentry, &free_list, i.free_i_list) { |
259 | fsnotify_destroy_mark_by_entry(entry); | 259 | fsnotify_destroy_mark_by_entry(entry); |
260 | fsnotify_put_mark(entry); | 260 | fsnotify_put_mark(entry); |
261 | } | 261 | } |
@@ -273,7 +273,7 @@ struct fsnotify_mark_entry *fsnotify_find_mark_entry(struct fsnotify_group *grou | |||
273 | 273 | ||
274 | assert_spin_locked(&inode->i_lock); | 274 | assert_spin_locked(&inode->i_lock); |
275 | 275 | ||
276 | hlist_for_each_entry(entry, pos, &inode->i_fsnotify_mark_entries, i_list) { | 276 | hlist_for_each_entry(entry, pos, &inode->i_fsnotify_mark_entries, i.i_list) { |
277 | if (entry->group == group) { | 277 | if (entry->group == group) { |
278 | fsnotify_get_mark(entry); | 278 | fsnotify_get_mark(entry); |
279 | return entry; | 279 | return entry; |
@@ -285,7 +285,7 @@ struct fsnotify_mark_entry *fsnotify_find_mark_entry(struct fsnotify_group *grou | |||
285 | void fsnotify_duplicate_mark(struct fsnotify_mark_entry *new, struct fsnotify_mark_entry *old) | 285 | void fsnotify_duplicate_mark(struct fsnotify_mark_entry *new, struct fsnotify_mark_entry *old) |
286 | { | 286 | { |
287 | assert_spin_locked(&old->lock); | 287 | assert_spin_locked(&old->lock); |
288 | new->inode = old->inode; | 288 | new->i.inode = old->i.inode; |
289 | new->group = old->group; | 289 | new->group = old->group; |
290 | new->mask = old->mask; | 290 | new->mask = old->mask; |
291 | new->free_mark = old->free_mark; | 291 | new->free_mark = old->free_mark; |
@@ -299,10 +299,10 @@ void fsnotify_init_mark(struct fsnotify_mark_entry *entry, | |||
299 | { | 299 | { |
300 | spin_lock_init(&entry->lock); | 300 | spin_lock_init(&entry->lock); |
301 | atomic_set(&entry->refcnt, 1); | 301 | atomic_set(&entry->refcnt, 1); |
302 | INIT_HLIST_NODE(&entry->i_list); | 302 | INIT_HLIST_NODE(&entry->i.i_list); |
303 | entry->group = NULL; | 303 | entry->group = NULL; |
304 | entry->mask = 0; | 304 | entry->mask = 0; |
305 | entry->inode = NULL; | 305 | entry->i.inode = NULL; |
306 | entry->free_mark = free_mark; | 306 | entry->free_mark = free_mark; |
307 | } | 307 | } |
308 | 308 | ||
@@ -350,9 +350,9 @@ int fsnotify_add_mark(struct fsnotify_mark_entry *entry, | |||
350 | lentry = fsnotify_find_mark_entry(group, inode); | 350 | lentry = fsnotify_find_mark_entry(group, inode); |
351 | if (!lentry) { | 351 | if (!lentry) { |
352 | entry->group = group; | 352 | entry->group = group; |
353 | entry->inode = inode; | 353 | entry->i.inode = inode; |
354 | 354 | ||
355 | hlist_add_head(&entry->i_list, &inode->i_fsnotify_mark_entries); | 355 | hlist_add_head(&entry->i.i_list, &inode->i_fsnotify_mark_entries); |
356 | list_add(&entry->g_list, &group->mark_entries); | 356 | list_add(&entry->g_list, &group->mark_entries); |
357 | 357 | ||
358 | fsnotify_get_mark(entry); /* for i_list and g_list */ | 358 | fsnotify_get_mark(entry); /* for i_list and g_list */ |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 8075ae708ed4..3edb51cfcfbe 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -193,7 +193,7 @@ static int idr_callback(int id, void *p, void *data) | |||
193 | */ | 193 | */ |
194 | if (entry) | 194 | if (entry) |
195 | printk(KERN_WARNING "entry->group=%p inode=%p wd=%d\n", | 195 | printk(KERN_WARNING "entry->group=%p inode=%p wd=%d\n", |
196 | entry->group, entry->inode, ientry->wd); | 196 | entry->group, entry->i.inode, ientry->wd); |
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index a48d68a68b25..4b1587f9df3b 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -445,7 +445,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, | |||
445 | if (wd == -1) { | 445 | if (wd == -1) { |
446 | WARN_ONCE(1, "%s: ientry=%p ientry->wd=%d ientry->group=%p" | 446 | WARN_ONCE(1, "%s: ientry=%p ientry->wd=%d ientry->group=%p" |
447 | " ientry->inode=%p\n", __func__, ientry, ientry->wd, | 447 | " ientry->inode=%p\n", __func__, ientry, ientry->wd, |
448 | ientry->fsn_entry.group, ientry->fsn_entry.inode); | 448 | ientry->fsn_entry.group, ientry->fsn_entry.i.inode); |
449 | goto out; | 449 | goto out; |
450 | } | 450 | } |
451 | 451 | ||
@@ -454,7 +454,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, | |||
454 | if (unlikely(!found_ientry)) { | 454 | if (unlikely(!found_ientry)) { |
455 | WARN_ONCE(1, "%s: ientry=%p ientry->wd=%d ientry->group=%p" | 455 | WARN_ONCE(1, "%s: ientry=%p ientry->wd=%d ientry->group=%p" |
456 | " ientry->inode=%p\n", __func__, ientry, ientry->wd, | 456 | " ientry->inode=%p\n", __func__, ientry, ientry->wd, |
457 | ientry->fsn_entry.group, ientry->fsn_entry.inode); | 457 | ientry->fsn_entry.group, ientry->fsn_entry.i.inode); |
458 | goto out; | 458 | goto out; |
459 | } | 459 | } |
460 | 460 | ||
@@ -468,9 +468,9 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, | |||
468 | "entry->inode=%p found_ientry=%p found_ientry->wd=%d " | 468 | "entry->inode=%p found_ientry=%p found_ientry->wd=%d " |
469 | "found_ientry->group=%p found_ientry->inode=%p\n", | 469 | "found_ientry->group=%p found_ientry->inode=%p\n", |
470 | __func__, ientry, ientry->wd, ientry->fsn_entry.group, | 470 | __func__, ientry, ientry->wd, ientry->fsn_entry.group, |
471 | ientry->fsn_entry.inode, found_ientry, found_ientry->wd, | 471 | ientry->fsn_entry.i.inode, found_ientry, found_ientry->wd, |
472 | found_ientry->fsn_entry.group, | 472 | found_ientry->fsn_entry.group, |
473 | found_ientry->fsn_entry.inode); | 473 | found_ientry->fsn_entry.i.inode); |
474 | goto out; | 474 | goto out; |
475 | } | 475 | } |
476 | 476 | ||
@@ -482,7 +482,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, | |||
482 | if (unlikely(atomic_read(&ientry->fsn_entry.refcnt) < 3)) { | 482 | if (unlikely(atomic_read(&ientry->fsn_entry.refcnt) < 3)) { |
483 | printk(KERN_ERR "%s: ientry=%p ientry->wd=%d ientry->group=%p" | 483 | printk(KERN_ERR "%s: ientry=%p ientry->wd=%d ientry->group=%p" |
484 | " ientry->inode=%p\n", __func__, ientry, ientry->wd, | 484 | " ientry->inode=%p\n", __func__, ientry, ientry->wd, |
485 | ientry->fsn_entry.group, ientry->fsn_entry.inode); | 485 | ientry->fsn_entry.group, ientry->fsn_entry.i.inode); |
486 | /* we can't really recover with bad ref cnting.. */ | 486 | /* we can't really recover with bad ref cnting.. */ |
487 | BUG(); | 487 | BUG(); |
488 | } | 488 | } |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index c2a04b7e4fca..dca7f2cbde90 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -227,6 +227,15 @@ struct fsnotify_event { | |||
227 | }; | 227 | }; |
228 | 228 | ||
229 | /* | 229 | /* |
230 | * Inode specific fields in an fsnotify_mark_entry | ||
231 | */ | ||
232 | struct fsnotify_inode_mark { | ||
233 | struct inode *inode; /* inode this entry is associated with */ | ||
234 | struct hlist_node i_list; /* list of mark_entries by inode->i_fsnotify_mark_entries */ | ||
235 | struct list_head free_i_list; /* tmp list used when freeing this mark */ | ||
236 | }; | ||
237 | |||
238 | /* | ||
230 | * a mark is simply an entry attached to an in core inode which allows an | 239 | * a mark is simply an entry attached to an in core inode which allows an |
231 | * fsnotify listener to indicate they are either no longer interested in events | 240 | * fsnotify listener to indicate they are either no longer interested in events |
232 | * of a type matching mask or only interested in those events. | 241 | * of a type matching mask or only interested in those events. |
@@ -241,12 +250,12 @@ struct fsnotify_mark_entry { | |||
241 | /* we hold ref for each i_list and g_list. also one ref for each 'thing' | 250 | /* we hold ref for each i_list and g_list. also one ref for each 'thing' |
242 | * in kernel that found and may be using this mark. */ | 251 | * in kernel that found and may be using this mark. */ |
243 | atomic_t refcnt; /* active things looking at this mark */ | 252 | atomic_t refcnt; /* active things looking at this mark */ |
244 | struct inode *inode; /* inode this entry is associated with */ | ||
245 | struct fsnotify_group *group; /* group this mark entry is for */ | 253 | struct fsnotify_group *group; /* group this mark entry is for */ |
246 | struct hlist_node i_list; /* list of mark_entries by inode->i_fsnotify_mark_entries */ | ||
247 | struct list_head g_list; /* list of mark_entries by group->i_fsnotify_mark_entries */ | 254 | struct list_head g_list; /* list of mark_entries by group->i_fsnotify_mark_entries */ |
248 | spinlock_t lock; /* protect group, inode, and killme */ | 255 | spinlock_t lock; /* protect group and inode */ |
249 | struct list_head free_i_list; /* tmp list used when freeing this mark */ | 256 | union { |
257 | struct fsnotify_inode_mark i; | ||
258 | }; | ||
250 | struct list_head free_g_list; /* tmp list used when freeing this mark */ | 259 | struct list_head free_g_list; /* tmp list used when freeing this mark */ |
251 | void (*free_mark)(struct fsnotify_mark_entry *entry); /* called on final put+free */ | 260 | void (*free_mark)(struct fsnotify_mark_entry *entry); /* called on final put+free */ |
252 | }; | 261 | }; |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index ecf0bf260d09..c21b05d25224 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
@@ -179,9 +179,9 @@ static void insert_hash(struct audit_chunk *chunk) | |||
179 | struct fsnotify_mark_entry *entry = &chunk->mark; | 179 | struct fsnotify_mark_entry *entry = &chunk->mark; |
180 | struct list_head *list; | 180 | struct list_head *list; |
181 | 181 | ||
182 | if (!entry->inode) | 182 | if (!entry->i.inode) |
183 | return; | 183 | return; |
184 | list = chunk_hash(entry->inode); | 184 | list = chunk_hash(entry->i.inode); |
185 | list_add_rcu(&chunk->hash, list); | 185 | list_add_rcu(&chunk->hash, list); |
186 | } | 186 | } |
187 | 187 | ||
@@ -193,7 +193,7 @@ struct audit_chunk *audit_tree_lookup(const struct inode *inode) | |||
193 | 193 | ||
194 | list_for_each_entry_rcu(p, list, hash) { | 194 | list_for_each_entry_rcu(p, list, hash) { |
195 | /* mark.inode may have gone NULL, but who cares? */ | 195 | /* mark.inode may have gone NULL, but who cares? */ |
196 | if (p->mark.inode == inode) { | 196 | if (p->mark.i.inode == inode) { |
197 | atomic_long_inc(&p->refs); | 197 | atomic_long_inc(&p->refs); |
198 | return p; | 198 | return p; |
199 | } | 199 | } |
@@ -233,7 +233,7 @@ static void untag_chunk(struct node *p) | |||
233 | spin_unlock(&hash_lock); | 233 | spin_unlock(&hash_lock); |
234 | 234 | ||
235 | spin_lock(&entry->lock); | 235 | spin_lock(&entry->lock); |
236 | if (chunk->dead || !entry->inode) { | 236 | if (chunk->dead || !entry->i.inode) { |
237 | spin_unlock(&entry->lock); | 237 | spin_unlock(&entry->lock); |
238 | goto out; | 238 | goto out; |
239 | } | 239 | } |
@@ -259,7 +259,7 @@ static void untag_chunk(struct node *p) | |||
259 | if (!new) | 259 | if (!new) |
260 | goto Fallback; | 260 | goto Fallback; |
261 | fsnotify_duplicate_mark(&new->mark, entry); | 261 | fsnotify_duplicate_mark(&new->mark, entry); |
262 | if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.inode, 1)) { | 262 | if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, 1)) { |
263 | free_chunk(new); | 263 | free_chunk(new); |
264 | goto Fallback; | 264 | goto Fallback; |
265 | } | 265 | } |
@@ -388,7 +388,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
388 | chunk_entry = &chunk->mark; | 388 | chunk_entry = &chunk->mark; |
389 | 389 | ||
390 | spin_lock(&old_entry->lock); | 390 | spin_lock(&old_entry->lock); |
391 | if (!old_entry->inode) { | 391 | if (!old_entry->i.inode) { |
392 | /* old_entry is being shot, lets just lie */ | 392 | /* old_entry is being shot, lets just lie */ |
393 | spin_unlock(&old_entry->lock); | 393 | spin_unlock(&old_entry->lock); |
394 | fsnotify_put_mark(old_entry); | 394 | fsnotify_put_mark(old_entry); |
@@ -397,7 +397,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
397 | } | 397 | } |
398 | 398 | ||
399 | fsnotify_duplicate_mark(chunk_entry, old_entry); | 399 | fsnotify_duplicate_mark(chunk_entry, old_entry); |
400 | if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->inode, 1)) { | 400 | if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, 1)) { |
401 | spin_unlock(&old_entry->lock); | 401 | spin_unlock(&old_entry->lock); |
402 | free_chunk(chunk); | 402 | free_chunk(chunk); |
403 | fsnotify_put_mark(old_entry); | 403 | fsnotify_put_mark(old_entry); |
@@ -605,7 +605,7 @@ void audit_trim_trees(void) | |||
605 | list_for_each_entry(node, &tree->chunks, list) { | 605 | list_for_each_entry(node, &tree->chunks, list) { |
606 | struct audit_chunk *chunk = find_chunk(node); | 606 | struct audit_chunk *chunk = find_chunk(node); |
607 | /* this could be NULL if the watch is dieing else where... */ | 607 | /* this could be NULL if the watch is dieing else where... */ |
608 | struct inode *inode = chunk->mark.inode; | 608 | struct inode *inode = chunk->mark.i.inode; |
609 | node->index |= 1U<<31; | 609 | node->index |= 1U<<31; |
610 | if (iterate_mounts(compare_root, inode, root_mnt)) | 610 | if (iterate_mounts(compare_root, inode, root_mnt)) |
611 | node->index &= ~(1U<<31); | 611 | node->index &= ~(1U<<31); |