Patch "fsnotify: clean up fsnotify_prepare/finish_user_wait()" has been added to the 4.14-stable tree
This is a note to let you know that I've just added the patch titled
fsnotify: clean up fsnotify_prepare/finish_user_wait()
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
fsnotify-clean-up-fsnotify_prepare-finish_user_wait.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
24c20305c7fc8959836211cb8c50aab93ae0e54fMon Sep 17 00:00:00 2001
From: Miklos Szeredi <[email protected]>
Date: Mon, 30 Oct 2017 21:14:55 +0100
Subject: fsnotify: clean up fsnotify_prepare/finish_user_wait()
From: Miklos Szeredi <[email protected]>
commit 24c20305c7fc8959836211cb8c50aab93ae0e54f upstream.
This patch doesn't actually fix any bug, just paves the way for fixing mark and group pinning.
--- fs/notify/mark.c | 98 +++++++++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 49 deletions(-)
fs/notify/mark.c +49 -49
@@ -109,16 +109,6 @@ void fsnotify_get_mark(struct fsnotify_matomic_inc (&mark->refcnt); } -/* -* Get mark reference when we found the mark via lockless traversal of object -* list. Mark can be already removed from the list by now and on its way to be -* destroyed once SRCU period ends. -*/ -static bool fsnotify_get_mark_safe (struct fsnotify_mark *mark) -{ -return atomic_inc_not_zero (&mark->refcnt); -} -static void __fsnotify_recalc_mask (struct fsnotify_mark_connector *conn) {u32 new_mask =0 ;
@@ -256,32 +246,63 @@ void fsnotify_put_mark(struct fsnotify_m FSNOTIFY_REAPER_DELAY); } -bool fsnotify_prepare_user_wait (struct fsnotify_iter_info *iter_info) +/* +* Get mark reference when we found the mark via lockless traversal of object +* list. Mark can be already removed from the list by now and on its way to be +* destroyed once SRCU period ends. +* +* Also pin the group so it doesn't disappear under us. +*/ +static bool fsnotify_get_mark_safe (struct fsnotify_mark *mark) {struct fsnotify_group *group; -if (WARN_ON_ONCE (!iter_info->inode_mark && !iter_info->vfsmount_mark)) -return false; - -if (iter_info->inode_mark) - group = iter_info->inode_mark->group; -else - group = iter_info->vfsmount_mark->group; +if (!mark) +return true; + group = mark->group;/* * Since acquisition of mark reference is an atomic op as well, we can * be sure this inc is seen before any effect of refcount increment. */ atomic_inc (&group->user_waits); +if (atomic_inc_not_zero (&mark->refcnt)) +return true; + +if (atomic_dec_and_test (&group->user_waits) && group->shutdown) +wake_up (&group->notification_waitq); + +return false; +} + +/* +* Puts marks and wakes up group destruction if necessary. +* +* Pairs with fsnotify_get_mark_safe() +*/ +static void fsnotify_put_mark_wake (struct fsnotify_mark *mark) +{ +if (mark) { +struct fsnotify_group *group = mark->group; -if (iter_info->inode_mark) { -/* This can fail if mark is being removed */ -if (!fsnotify_get_mark_safe (iter_info->inode_mark)) - goto out_wait; - } -if (iter_info->vfsmount_mark) { -if (!fsnotify_get_mark_safe (iter_info->vfsmount_mark)) - goto out_inode; +fsnotify_put_mark (mark); +/* +* We abuse notification_waitq on group shutdown for waiting for +* all marks pinned when waiting for userspace. +*/ +if (atomic_dec_and_test (&group->user_waits) && group->shutdown) +wake_up (&group->notification_waitq); + } +} + +bool fsnotify_prepare_user_wait (struct fsnotify_iter_info *iter_info) +{ +/* This can fail if mark is being removed */ +if (!fsnotify_get_mark_safe (iter_info->inode_mark)) +return false; +if (!fsnotify_get_mark_safe (iter_info->vfsmount_mark)) { +fsnotify_put_mark_wake (iter_info->inode_mark); +return false; }/*
@@ -292,34 +313,13 @@ bool fsnotify_prepare_user_wait(struct fsrcu_read_unlock (&fsnotify_mark_srcu, iter_info->srcu_idx);return true; -out_inode: -if (iter_info->inode_mark) -fsnotify_put_mark (iter_info->inode_mark); -out_wait: -if (atomic_dec_and_test (&group->user_waits) && group->shutdown) -wake_up (&group->notification_waitq); -return false; }void fsnotify_finish_user_wait (struct fsnotify_iter_info *iter_info) { -struct fsnotify_group *group =NULL ; - iter_info->srcu_idx =srcu_read_lock (&fsnotify_mark_srcu); -if (iter_info->inode_mark) { - group = iter_info->inode_mark->group; -fsnotify_put_mark (iter_info->inode_mark); - } -if (iter_info->vfsmount_mark) { - group = iter_info->vfsmount_mark->group; -fsnotify_put_mark (iter_info->vfsmount_mark); - } -/* -* We abuse notification_waitq on group shutdown for waiting for all -* marks pinned when waiting for userspace. -*/ -if (atomic_dec_and_test (&group->user_waits) && group->shutdown) -wake_up (&group->notification_waitq); +fsnotify_put_mark_wake (iter_info->inode_mark); +fsnotify_put_mark_wake (iter_info->vfsmount_mark); }/*
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/fsnotify-clean-up-fsnotify_prepare-finish_user_wait.patch queue-4.14/fsnotify-fix-pinning-group-in-fsnotify_prepare_user_wait.patch queue-4.14/fanotify-fix-fsnotify_prepare_user_wait-failure.patch queue-4.14/fsnotify-pin-both-inode-and-vfsmount-mark.patch queue-4.14/ovl-put-upperdentry-if-ovl_check_origin-fails.patch