[PATCH 3/3][BUGFIX] configfs: Fix deadlock with racing rmdir() and rename()

Previous thread: [PATCH 2/3][BUGFIX] configfs: Make configfs_new_dirent() return error code instead of NULL by Louis Rilling on Thursday, June 12, 2008 - 6:31 am. (1 message)

Next thread: Re: WARNING : section mismatch while compiling 2.6.25.6 by vibi sreenivasan on Thursday, June 12, 2008 - 7:07 am. (3 messages)
From: Louis Rilling
Date: Thursday, June 12, 2008 - 6:31 am

This patch fixes the deadlock between racing sys_rename() and configfs_rmdir().

The idea is to avoid locking i_mutexes of default groups in
configfs_detach_prep(), and rely instead on the new configfs_dirent_lock to
protect against configfs_dirent's linkage mutations. To ensure that an mkdir()
racing with rmdir() will not create new items in a to-be-removed default group,
we make configfs_new_dirent() check for the CONFIGFS_USET_DROPPING flag right
before linking the new dirent, and return error if the flag is set. This makes
racing mkdir()/symlink()/dir_open() fail in places where errors could already
happen, resp. in (attach_item()|attach_group())/create_link()/new_dirent().

configfs_depend() remains safe since it locks all the path from configfs root,
and is thus mutually exclusive with rmdir().

An advantage of this is that now detach_groups() unconditionnaly takes the
default groups i_mutex, which makes it more consistent with populate_groups().

Signed-off-by: Louis Rilling <Louis.Rilling@kerlabs.com>
---
 fs/configfs/dir.c |   44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

Index: b/fs/configfs/dir.c
===================================================================
--- a/fs/configfs/dir.c	2008-06-12 13:45:18.000000000 +0200
+++ b/fs/configfs/dir.c	2008-06-12 13:50:10.000000000 +0200
@@ -38,6 +38,9 @@
 DECLARE_RWSEM(configfs_rename_sem);
 /*
  * Protects configfs_dirent traversals against linkage mutations
+ * Protects setting of CONFIGFS_USET_DROPPING: checking the flag
+ * unlocked is not reliable unless in detach_groups called from
+ * rmdir/unregister and from configfs_attach_group
  * Can be used as an alternative to taking the concerned i_mutex
  */
 DEFINE_SPINLOCK(configfs_dirent_lock);
@@ -86,6 +89,11 @@ static struct configfs_dirent *configfs_
 	INIT_LIST_HEAD(&sd->s_links);
 	INIT_LIST_HEAD(&sd->s_children);
 	spin_lock(&configfs_dirent_lock);
+	if (parent_sd->s_type & CONFIGFS_USET_DROPPING) ...
Previous thread: [PATCH 2/3][BUGFIX] configfs: Make configfs_new_dirent() return error code instead of NULL by Louis Rilling on Thursday, June 12, 2008 - 6:31 am. (1 message)

Next thread: Re: WARNING : section mismatch while compiling 2.6.25.6 by vibi sreenivasan on Thursday, June 12, 2008 - 7:07 am. (3 messages)