LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] inotify: fix race when adding a new watch
@ 2011-02-11 15:04 Lino Sanfilippo
  0 siblings, 0 replies; only message in thread
From: Lino Sanfilippo @ 2011-02-11 15:04 UTC (permalink / raw)
  To: eparis; +Cc: linux-kernel, linux-fsdevel


In inotify_new_watch() the number of watches for a group is compared against
the max number of allowed watches and increased afterwards.
The check and incrementation is not done atomically, so it is possible for
multiple concurrent threads to pass the check and increment the number of
marks above the allowed max.
This patch uses a groups mark_lock to ensure that both check and incrementation
are done atomic.
With this lock held it is also not longer necessary to check for an already existing 
mark after inotify_new_watch() has returned, since mark lookup and addition are also
synchronized now.

Signed-off-by: Lino Sanfilippo <LinoSanfilppo@gmx.de>
---
This patch depends on the the patch series
"fsnotify: use a groups mark_mutex to synchronize access to its mark list" sent 
earlier this day.

 fs/notify/inotify/inotify_user.c |   13 ++++---------
 1 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 1637820..8e8b236 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -656,7 +656,8 @@ static int inotify_new_watch(struct fsnotify_group *group,
 		goto out_err;
 
 	/* we are on the idr, now get on the inode */
-	ret = fsnotify_add_mark(&tmp_i_mark->fsn_mark, group, inode, NULL, 0);
+	ret = fsnotify_add_mark_locked(&tmp_i_mark->fsn_mark, group, inode,
+				       NULL, 0);
 	if (ret) {
 		/* we failed to get on the inode, get off the idr */
 		inotify_remove_from_idr(group, tmp_i_mark);
@@ -680,19 +681,13 @@ static int inotify_update_watch(struct fsnotify_group *group, struct inode *inod
 {
 	int ret = 0;
 
-retry:
+	mutex_lock(&group->mark_mutex);
 	/* try to update and existing watch with the new arg */
 	ret = inotify_update_existing_watch(group, inode, arg);
 	/* no mark present, try to add a new one */
 	if (ret == -ENOENT)
 		ret = inotify_new_watch(group, inode, arg);
-	/*
-	 * inotify_new_watch could race with another thread which did an
-	 * inotify_new_watch between the update_existing and the add watch
-	 * here, go back and try to update an existing mark again.
-	 */
-	if (ret == -EEXIST)
-		goto retry;
+	mutex_unlock(&group->mark_mutex);
 
 	return ret;
 }
-- 
1.5.6.5


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-02-11 15:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-11 15:04 [PATCH] inotify: fix race when adding a new watch Lino Sanfilippo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).