summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@aristanetworks.com>2010-02-12 19:22:23 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-07 17:04:52 -0800
commitf8d4f618fed5a4978afada52166bc2efaf7656d1 (patch)
tree3247344bc9e2cb39261336f25f345740b22622d0
parentb35c74dab64f4c212f36d868419108556c9cf3e2 (diff)
downloadlinux-3.10-f8d4f618fed5a4978afada52166bc2efaf7656d1.tar.gz
linux-3.10-f8d4f618fed5a4978afada52166bc2efaf7656d1.tar.bz2
linux-3.10-f8d4f618fed5a4978afada52166bc2efaf7656d1.zip
sysfs: Serialize updates to the vfs inode
The vfs depends upon filesystem methods to update the vfs inode. Sysfs adds to the normal number of places where the vfs inode is updated by also updatng the vfs inode in sysfs_refresh_inode. Typically the inode mutex is used to serialize updates to the vfs inode, but grabbing the inode mutex in sysfs_permission and sysfs_getattr causes deadlocks, because sometimes the vfs calls those operations with the inode mutex held. Therefore sysfs can not use the inode mutex to serial updates to the vfs inode. The sysfs_mutex is acquired in all of the routines where sysfs updates the vfs inode, and with a small change we can consistently protext sysfs vfs inode updates with the sysfs_mutex. To protect the sysfs vfs inode updates with the sysfs_mutex simply requires extending the scope of sysfs_mutex in sysfs_setattr over inode_setattr, and over inode_change_ok (so we have an unchanging inode when we perform the check). Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--fs/sysfs/inode.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 6a06a1d1ea7..0d09f6c6efa 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -111,20 +111,20 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
if (!sd)
return -EINVAL;
+ mutex_lock(&sysfs_mutex);
error = inode_change_ok(inode, iattr);
if (error)
- return error;
+ goto out;
iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
error = inode_setattr(inode, iattr);
if (error)
- return error;
+ goto out;
- mutex_lock(&sysfs_mutex);
error = sysfs_sd_setattr(sd, iattr);
+out:
mutex_unlock(&sysfs_mutex);
-
return error;
}