aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/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/ext3/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/ext3/xattr.c')
-rw-r--r--fs/ext3/xattr.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 0db74f94229681..b89f8be46f0f7d 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -199,11 +199,16 @@ ext3_getxattr(struct dentry *dentry, const char *name,
{
struct ext3_xattr_handler *handler;
struct inode *inode = dentry->d_inode;
+ ssize_t error;
handler = ext3_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;
}
/*
@@ -214,7 +219,13 @@ ext3_getxattr(struct dentry *dentry, const char *name,
ssize_t
ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
- return ext3_xattr_list(dentry->d_inode, buffer, size);
+ ssize_t error;
+
+ down(&dentry->d_inode->i_sem);
+ error = ext3_xattr_list(dentry->d_inode, buffer, size);
+ up(&dentry->d_inode->i_sem);
+
+ return error;
}
/*