aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/xattr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-01-02 14:17:05 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-01-02 14:17:05 -0500
commit45d28b097280a78893ce25a5d0db41e6a2717853 (patch)
tree0c2049700c5fca3fc9d73d2f347fab21e84765f8 /fs/reiserfs/xattr.c
parent4207a152bc242effd0b8231143aa5b9f7a1593a9 (diff)
parent835d5247d98f46e35d007dcfa6215e526ca33360 (diff)
Merge branch 'reiserfs/kill-bkl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing
* 'reiserfs/kill-bkl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing: reiserfs: Safely acquire i_mutex from xattr_rmdir reiserfs: Safely acquire i_mutex from reiserfs_for_each_xattr reiserfs: Fix journal mutex <-> inode mutex lock inversion reiserfs: Fix unwanted recursive reiserfs lock in reiserfs_unlink() reiserfs: Relax lock before open xattr dir in reiserfs_xattr_set_handle() reiserfs: Relax reiserfs lock while freeing the journal reiserfs: Fix reiserfs lock <-> i_mutex dependency inversion on xattr reiserfs: Warn on lock relax if taken recursively reiserfs: Fix reiserfs lock <-> i_xattr_sem dependency inversion reiserfs: Fix remaining in-reclaim-fs <-> reclaim-fs-on locking inversion reiserfs: Fix reiserfs lock <-> inode mutex dependency inversion reiserfs: Fix reiserfs lock and journal lock inversion dependency reiserfs: Fix possible recursive lock
Diffstat (limited to 'fs/reiserfs/xattr.c')
-rw-r--r--fs/reiserfs/xattr.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 8c7033a8b67e..c3b004ee627b 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -83,7 +83,8 @@ static int xattr_unlink(struct inode *dir, struct dentry *dentry)
83 BUG_ON(!mutex_is_locked(&dir->i_mutex)); 83 BUG_ON(!mutex_is_locked(&dir->i_mutex));
84 vfs_dq_init(dir); 84 vfs_dq_init(dir);
85 85
86 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); 86 reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex,
87 I_MUTEX_CHILD, dir->i_sb);
87 error = dir->i_op->unlink(dir, dentry); 88 error = dir->i_op->unlink(dir, dentry);
88 mutex_unlock(&dentry->d_inode->i_mutex); 89 mutex_unlock(&dentry->d_inode->i_mutex);
89 90
@@ -98,7 +99,8 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry)
98 BUG_ON(!mutex_is_locked(&dir->i_mutex)); 99 BUG_ON(!mutex_is_locked(&dir->i_mutex));
99 vfs_dq_init(dir); 100 vfs_dq_init(dir);
100 101
101 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); 102 reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex,
103 I_MUTEX_CHILD, dir->i_sb);
102 dentry_unhash(dentry); 104 dentry_unhash(dentry);
103 error = dir->i_op->rmdir(dir, dentry); 105 error = dir->i_op->rmdir(dir, dentry);
104 if (!error) 106 if (!error)
@@ -235,16 +237,22 @@ static int reiserfs_for_each_xattr(struct inode *inode,
235 if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) 237 if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1)
236 return 0; 238 return 0;
237 239
240 reiserfs_write_unlock(inode->i_sb);
238 dir = open_xa_dir(inode, XATTR_REPLACE); 241 dir = open_xa_dir(inode, XATTR_REPLACE);
239 if (IS_ERR(dir)) { 242 if (IS_ERR(dir)) {
240 err = PTR_ERR(dir); 243 err = PTR_ERR(dir);
244 reiserfs_write_lock(inode->i_sb);
241 goto out; 245 goto out;
242 } else if (!dir->d_inode) { 246 } else if (!dir->d_inode) {
243 err = 0; 247 err = 0;
248 reiserfs_write_lock(inode->i_sb);
244 goto out_dir; 249 goto out_dir;
245 } 250 }
246 251
247 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); 252 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR);
253
254 reiserfs_write_lock(inode->i_sb);
255
248 buf.xadir = dir; 256 buf.xadir = dir;
249 err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); 257 err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos);
250 while ((err == 0 || err == -ENOSPC) && buf.count) { 258 while ((err == 0 || err == -ENOSPC) && buf.count) {
@@ -283,8 +291,9 @@ static int reiserfs_for_each_xattr(struct inode *inode,
283 err = journal_begin(&th, inode->i_sb, blocks); 291 err = journal_begin(&th, inode->i_sb, blocks);
284 if (!err) { 292 if (!err) {
285 int jerror; 293 int jerror;
286 mutex_lock_nested(&dir->d_parent->d_inode->i_mutex, 294 reiserfs_mutex_lock_nested_safe(
287 I_MUTEX_XATTR); 295 &dir->d_parent->d_inode->i_mutex,
296 I_MUTEX_XATTR, inode->i_sb);
288 err = action(dir, data); 297 err = action(dir, data);
289 jerror = journal_end(&th, inode->i_sb, blocks); 298 jerror = journal_end(&th, inode->i_sb, blocks);
290 mutex_unlock(&dir->d_parent->d_inode->i_mutex); 299 mutex_unlock(&dir->d_parent->d_inode->i_mutex);
@@ -480,11 +489,16 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
480 if (!buffer) 489 if (!buffer)
481 return lookup_and_delete_xattr(inode, name); 490 return lookup_and_delete_xattr(inode, name);
482 491
492 reiserfs_write_unlock(inode->i_sb);
483 dentry = xattr_lookup(inode, name, flags); 493 dentry = xattr_lookup(inode, name, flags);
484 if (IS_ERR(dentry)) 494 if (IS_ERR(dentry)) {
495 reiserfs_write_lock(inode->i_sb);
485 return PTR_ERR(dentry); 496 return PTR_ERR(dentry);
497 }
486 498
487 down_write(&REISERFS_I(inode)->i_xattr_sem); 499 down_read(&REISERFS_I(inode)->i_xattr_sem);
500
501 reiserfs_write_lock(inode->i_sb);
488 502
489 xahash = xattr_hash(buffer, buffer_size); 503 xahash = xattr_hash(buffer, buffer_size);
490 while (buffer_pos < buffer_size || buffer_pos == 0) { 504 while (buffer_pos < buffer_size || buffer_pos == 0) {