Commit e7253760 authored by Jan Kara's avatar Jan Kara

inotify: Do not drop mark reference under idr_lock

Dropping mark reference can result in mark being freed. Although it
should not happen in inotify_remove_from_idr() since caller should hold
another reference, just don't risk lock up just after WARN_ON
unnecessarily. Also fold do_inotify_remove_from_idr() into the single
callsite as that function really is just two lines of real code.
Reviewed-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
Reviewed-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 08991e83
...@@ -395,21 +395,6 @@ static struct inotify_inode_mark *inotify_idr_find(struct fsnotify_group *group, ...@@ -395,21 +395,6 @@ static struct inotify_inode_mark *inotify_idr_find(struct fsnotify_group *group,
return i_mark; return i_mark;
} }
static void do_inotify_remove_from_idr(struct fsnotify_group *group,
struct inotify_inode_mark *i_mark)
{
struct idr *idr = &group->inotify_data.idr;
spinlock_t *idr_lock = &group->inotify_data.idr_lock;
int wd = i_mark->wd;
assert_spin_locked(idr_lock);
idr_remove(idr, wd);
/* removed from the idr, drop that ref */
fsnotify_put_mark(&i_mark->fsn_mark);
}
/* /*
* Remove the mark from the idr (if present) and drop the reference * Remove the mark from the idr (if present) and drop the reference
* on the mark because it was in the idr. * on the mark because it was in the idr.
...@@ -417,6 +402,7 @@ static void do_inotify_remove_from_idr(struct fsnotify_group *group, ...@@ -417,6 +402,7 @@ static void do_inotify_remove_from_idr(struct fsnotify_group *group,
static void inotify_remove_from_idr(struct fsnotify_group *group, static void inotify_remove_from_idr(struct fsnotify_group *group,
struct inotify_inode_mark *i_mark) struct inotify_inode_mark *i_mark)
{ {
struct idr *idr = &group->inotify_data.idr;
spinlock_t *idr_lock = &group->inotify_data.idr_lock; spinlock_t *idr_lock = &group->inotify_data.idr_lock;
struct inotify_inode_mark *found_i_mark = NULL; struct inotify_inode_mark *found_i_mark = NULL;
int wd; int wd;
...@@ -468,13 +454,15 @@ static void inotify_remove_from_idr(struct fsnotify_group *group, ...@@ -468,13 +454,15 @@ static void inotify_remove_from_idr(struct fsnotify_group *group,
BUG(); BUG();
} }
do_inotify_remove_from_idr(group, i_mark); idr_remove(idr, wd);
/* Removed from the idr, drop that ref. */
fsnotify_put_mark(&i_mark->fsn_mark);
out: out:
i_mark->wd = -1;
spin_unlock(idr_lock);
/* match the ref taken by inotify_idr_find_locked() */ /* match the ref taken by inotify_idr_find_locked() */
if (found_i_mark) if (found_i_mark)
fsnotify_put_mark(&found_i_mark->fsn_mark); fsnotify_put_mark(&found_i_mark->fsn_mark);
i_mark->wd = -1;
spin_unlock(idr_lock);
} }
/* /*
......
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