inotify: do not BUG on idr entries at inotify destruction
If an inotify watch is left in the idr when an fsnotify group is destroyed this will lead to a BUG. This is not a dangerous situation and really indicates a programming bug and leak of memory. This patch changes it to use a WARN and a printk rather than killing people's boxes. Signed-off-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
Родитель
52cef7555a
Коммит
cf4374267f
|
@ -105,16 +105,45 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode
|
|||
return send;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is NEVER supposed to be called. Inotify marks should either have been
|
||||
* removed from the idr when the watch was removed or in the
|
||||
* fsnotify_destroy_mark_by_group() call when the inotify instance was being
|
||||
* torn down. This is only called if the idr is about to be freed but there
|
||||
* are still marks in it.
|
||||
*/
|
||||
static int idr_callback(int id, void *p, void *data)
|
||||
{
|
||||
BUG();
|
||||
struct fsnotify_mark_entry *entry;
|
||||
struct inotify_inode_mark_entry *ientry;
|
||||
static bool warned = false;
|
||||
|
||||
if (warned)
|
||||
return 0;
|
||||
|
||||
warned = false;
|
||||
entry = p;
|
||||
ientry = container_of(entry, struct inotify_inode_mark_entry, fsn_entry);
|
||||
|
||||
WARN(1, "inotify closing but id=%d for entry=%p in group=%p still in "
|
||||
"idr. Probably leaking memory\n", id, p, data);
|
||||
|
||||
/*
|
||||
* I'm taking the liberty of assuming that the mark in question is a
|
||||
* valid address and I'm dereferencing it. This might help to figure
|
||||
* out why we got here and the panic is no worse than the original
|
||||
* BUG() that was here.
|
||||
*/
|
||||
if (entry)
|
||||
printk(KERN_WARNING "entry->group=%p inode=%p wd=%d\n",
|
||||
entry->group, entry->inode, ientry->wd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void inotify_free_group_priv(struct fsnotify_group *group)
|
||||
{
|
||||
/* ideally the idr is empty and we won't hit the BUG in teh callback */
|
||||
idr_for_each(&group->inotify_data.idr, idr_callback, NULL);
|
||||
idr_for_each(&group->inotify_data.idr, idr_callback, group);
|
||||
idr_remove_all(&group->inotify_data.idr);
|
||||
idr_destroy(&group->inotify_data.idr);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче