aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/xattr.c
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2003-07-06 05:41:05 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-07-06 05:41:05 -0700
commit430cab6d8dc4b79ad691c1d50d7ef217777e2593 (patch)
tree2444215ccf5e8a930b03f1a85d1b06c888aff0bc /fs/ext2/xattr.c
parenta39afa31c59075459f1b0f89d9e6e3446d0ff6a2 (diff)
downloadhistory-430cab6d8dc4b79ad691c1d50d7ef217777e2593.tar.gz
[PATCH] xattrr: preparation for fine-grained locking
From: Andreas Gruenbacher <agruen@suse.de> Andrew Morton found that there is lock contention between extended attribute operations (like reading ACLs, which `ls -l' needs to do) and other operations on the same files. This is due to the fact that all extended attribute syscalls take inode->i_sem before calling into the filesystem code. To fix this problem, this patch no longer takes inode->i_sem in the getxattr and listxattr syscalls, and moves the lock taking code into the file systems. (Another patch improves the locking strategy in ext2 and ext3.)
Diffstat (limited to 'fs/ext2/xattr.c')
-rw-r--r--fs/ext2/xattr.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index 2dc9c65452a27a..aa29871da68e34 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -204,11 +204,16 @@ ext2_getxattr(struct dentry *dentry, const char *name,
{
struct ext2_xattr_handler *handler;
struct inode *inode = dentry->d_inode;
+ ssize_t error;
handler = ext2_xattr_resolve_name(&name);
if (!handler)
return -EOPNOTSUPP;
- return handler->get(inode, name, buffer, size);
+ down(&inode->i_sem);
+ error = handler->get(inode, name, buffer, size);
+ up(&inode->i_sem);
+
+ return error;
}
/*
@@ -219,7 +224,13 @@ ext2_getxattr(struct dentry *dentry, const char *name,
ssize_t
ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
- return ext2_xattr_list(dentry->d_inode, buffer, size);
+ ssize_t error;
+
+ down(&dentry->d_inode->i_sem);
+ error = ext2_xattr_list(dentry->d_inode, buffer, size);
+ up(&dentry->d_inode->i_sem);
+
+ return error;
}
/*