Commit cf437426 authored by Eric Paris's avatar Eric Paris

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: default avatarEric Paris <eparis@redhat.com>
parent 52cef755
...@@ -105,16 +105,45 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode ...@@ -105,16 +105,45 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode
return send; 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) 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; return 0;
} }
static void inotify_free_group_priv(struct fsnotify_group *group) 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 */ /* 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_remove_all(&group->inotify_data.idr);
idr_destroy(&group->inotify_data.idr); idr_destroy(&group->inotify_data.idr);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment