fanotify: Move locking inside get_one_event()
get_one_event() has a single caller and that just locks notification_lock around the call. Move locking inside get_one_event() as that will make using ->response field for permission event state easier. Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
af6a511306
commit
8c5544666c
@ -65,35 +65,32 @@ static int fanotify_event_info_len(struct fanotify_event *event)
|
|||||||
* Get an fsnotify notification event if one exists and is small
|
* Get an fsnotify notification event if one exists and is small
|
||||||
* enough to fit in "count". Return an error pointer if the count
|
* enough to fit in "count". Return an error pointer if the count
|
||||||
* is not large enough.
|
* is not large enough.
|
||||||
*
|
|
||||||
* Called with the group->notification_lock held.
|
|
||||||
*/
|
*/
|
||||||
static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
|
static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
|
||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
size_t event_size = FAN_EVENT_METADATA_LEN;
|
size_t event_size = FAN_EVENT_METADATA_LEN;
|
||||||
struct fanotify_event *event;
|
struct fsnotify_event *fsn_event = NULL;
|
||||||
|
|
||||||
assert_spin_locked(&group->notification_lock);
|
|
||||||
|
|
||||||
pr_debug("%s: group=%p count=%zd\n", __func__, group, count);
|
pr_debug("%s: group=%p count=%zd\n", __func__, group, count);
|
||||||
|
|
||||||
|
spin_lock(&group->notification_lock);
|
||||||
if (fsnotify_notify_queue_is_empty(group))
|
if (fsnotify_notify_queue_is_empty(group))
|
||||||
return NULL;
|
goto out;
|
||||||
|
|
||||||
if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
|
if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
|
||||||
event = FANOTIFY_E(fsnotify_peek_first_event(group));
|
event_size += fanotify_event_info_len(
|
||||||
event_size += fanotify_event_info_len(event);
|
FANOTIFY_E(fsnotify_peek_first_event(group)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_size > count)
|
if (event_size > count) {
|
||||||
return ERR_PTR(-EINVAL);
|
fsn_event = ERR_PTR(-EINVAL);
|
||||||
|
goto out;
|
||||||
/*
|
}
|
||||||
* Held the notification_lock the whole time, so this is the
|
fsn_event = fsnotify_remove_first_event(group);
|
||||||
* same event we peeked above
|
out:
|
||||||
*/
|
spin_unlock(&group->notification_lock);
|
||||||
return fsnotify_remove_first_event(group);
|
return fsn_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_fd(struct fsnotify_group *group,
|
static int create_fd(struct fsnotify_group *group,
|
||||||
@ -316,10 +313,7 @@ static ssize_t fanotify_read(struct file *file, char __user *buf,
|
|||||||
|
|
||||||
add_wait_queue(&group->notification_waitq, &wait);
|
add_wait_queue(&group->notification_waitq, &wait);
|
||||||
while (1) {
|
while (1) {
|
||||||
spin_lock(&group->notification_lock);
|
|
||||||
kevent = get_one_event(group, count);
|
kevent = get_one_event(group, count);
|
||||||
spin_unlock(&group->notification_lock);
|
|
||||||
|
|
||||||
if (IS_ERR(kevent)) {
|
if (IS_ERR(kevent)) {
|
||||||
ret = PTR_ERR(kevent);
|
ret = PTR_ERR(kevent);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user