aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
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 /fs/sysfs
parentsysfs: windfarm: init sysfs attributes (diff)
downloadlinux-dev-f8d4f618fed5a4978afada52166bc2efaf7656d1.tar.xz
linux-dev-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>
Diffstat (limited to 'fs/sysfs')
-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 6a06a1d1ea7b..0d09f6c6efab 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;
}