diff options
| author | Frederic Weisbecker <fweisbec@gmail.com> | 2010-01-04 20:14:30 -0500 |
|---|---|---|
| committer | Frederic Weisbecker <fweisbec@gmail.com> | 2010-01-05 02:00:50 -0500 |
| commit | 4f3be1b5a98587b86cae05aa5d129dd0b3fff466 (patch) | |
| tree | f4d9acd840357ccdd6d5e667132996c050d0a9fa | |
| parent | 108d3943c021f0b66e860ba98ded40b82b677bd7 (diff) | |
reiserfs: Relax lock on xattr removing
When we remove an xattr, we call lookup_and_delete_xattr()
that takes some private xattr inodes mutexes. But we hold
the reiserfs lock at this time, which leads to dependency
inversions.
We can safely call lookup_and_delete_xattr() without the
reiserfs lock, where xattr inodes lookups only need the
xattr inodes mutexes.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Christian Kujau <lists@nerdbynature.de>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | fs/reiserfs/xattr.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 75d3706734ec..4899d789ba67 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -451,7 +451,9 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name) | |||
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | if (dentry->d_inode) { | 453 | if (dentry->d_inode) { |
| 454 | reiserfs_write_lock(inode->i_sb); | ||
| 454 | err = xattr_unlink(xadir->d_inode, dentry); | 455 | err = xattr_unlink(xadir->d_inode, dentry); |
| 456 | reiserfs_write_unlock(inode->i_sb); | ||
| 455 | update_ctime(inode); | 457 | update_ctime(inode); |
| 456 | } | 458 | } |
| 457 | 459 | ||
| @@ -485,10 +487,14 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
| 485 | if (get_inode_sd_version(inode) == STAT_DATA_V1) | 487 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
| 486 | return -EOPNOTSUPP; | 488 | return -EOPNOTSUPP; |
| 487 | 489 | ||
| 488 | if (!buffer) | ||
| 489 | return lookup_and_delete_xattr(inode, name); | ||
| 490 | |||
| 491 | reiserfs_write_unlock(inode->i_sb); | 490 | reiserfs_write_unlock(inode->i_sb); |
| 491 | |||
| 492 | if (!buffer) { | ||
| 493 | err = lookup_and_delete_xattr(inode, name); | ||
| 494 | reiserfs_write_lock(inode->i_sb); | ||
| 495 | return err; | ||
| 496 | } | ||
| 497 | |||
| 492 | dentry = xattr_lookup(inode, name, flags); | 498 | dentry = xattr_lookup(inode, name, flags); |
| 493 | if (IS_ERR(dentry)) { | 499 | if (IS_ERR(dentry)) { |
| 494 | reiserfs_write_lock(inode->i_sb); | 500 | reiserfs_write_lock(inode->i_sb); |
