diff options
| author | Andrew Morton <akpm@osdl.org> | 2003-07-06 05:41:12 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-07-06 05:41:12 -0700 |
| commit | 6abc05cce8b06b9c986fb2bbd83e6fa9888ab1be (patch) | |
| tree | da41f4772ecbdecc4e1ca9396478398c3ce159cf /include/linux/ext3_fs_i.h | |
| parent | 430cab6d8dc4b79ad691c1d50d7ef217777e2593 (diff) | |
[PATCH] xattr: fine-grained locking
From: Andreas Gruenbacher <agruen@suse.de>
This patch removes the dependency on i_sem in the getxattr and
listxattr iops of ext2 and ext3. In addition, the global ext[23]_xattr
semaphores go away. Instead of i_sem and the global semaphore, mutual
exclusion is now ensured by per-inode xattr semaphores, and by locking
the buffers before modifying them. The detailed locking strategy is
described in comments in fs/ext[23]/xattr.c.
Due to this change it is no longer necessary to take i_sem in
ext[23]_permission() for retrieving acls, so the
ext[23]_permission_locked() functions go away.
Additionally, the patch fixes a race condition in ext[23]_permission:
Accessing inode->i_acl was protected by the BKL in 2.4; in 2.5 there no
longer is such protection. Instead, inode->i_acl (and inode->i_default_acl)
are now accessed under inode->i_lock. (This could be replaced by RCU in
the future.)
In the ext3 extended attribute code, an new uglines results from locking
at the buffer head level: The buffer lock must be held between testing
if an xattr block can be modified and the actual modification to prevent
races from happening. Before a block can be modified,
ext3_journal_get_write_access() must be called. But this requies an unlocked
buffer, so I call ext3_journal_get_write_access() before locking the
buffer. If it turns out that the buffer cannot be modified,
journal_release_buffer() is called. Calling ext3_journal_get_write_access
after the test but while the buffer is still locked would be much better.
Diffstat (limited to 'include/linux/ext3_fs_i.h')
| -rw-r--r-- | include/linux/ext3_fs_i.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h index 1a6a6c5922f7..1181cfae7142 100644 --- a/include/linux/ext3_fs_i.h +++ b/include/linux/ext3_fs_i.h @@ -62,6 +62,16 @@ struct ext3_inode_info { __u32 i_prealloc_count; #endif __u32 i_dir_start_lookup; +#ifdef CONFIG_EXT3_FS_XATTR + /* + * Extended attributes can be read independently of the main file + * data. Taking i_sem even when reading would cause contention + * between readers of EAs and writers of regular file data, so + * instead we synchronize on xattr_sem when reading or changing + * EAs. + */ + struct rw_semaphore xattr_sem; +#endif #ifdef CONFIG_EXT3_FS_POSIX_ACL struct posix_acl *i_acl; struct posix_acl *i_default_acl; |
