diff options
author | Jeff Mahoney <jeffm@suse.com> | 2013-08-08 17:27:19 -0400 |
---|---|---|
committer | Jeff Mahoney <jeffm@suse.de> | 2013-08-08 17:27:19 -0400 |
commit | 4c05141df57f4ffc1a9a28f1925434924179bfe4 (patch) | |
tree | d210b251b6f46e50b27f4db4f15010f9b40aad45 /fs/reiserfs/xattr.c | |
parent | c095ba7224d8edc71dcef0d655911399a8bd4a3f (diff) |
reiserfs: locking, push write lock out of xattr code
The reiserfs xattr code doesn't need the write lock and sleeps all over
the place. We can simplify the locking by releasing it and reacquiring
after the xattr call.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Diffstat (limited to 'fs/reiserfs/xattr.c')
-rw-r--r-- | fs/reiserfs/xattr.c | 46 |
1 files changed, 17 insertions, 29 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index c69cdd749f09..8a9e2dcfe004 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -81,8 +81,7 @@ static int xattr_unlink(struct inode *dir, struct dentry *dentry) | |||
81 | int error; | 81 | int error; |
82 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 82 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
83 | 83 | ||
84 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, | 84 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); |
85 | I_MUTEX_CHILD, dir->i_sb); | ||
86 | error = dir->i_op->unlink(dir, dentry); | 85 | error = dir->i_op->unlink(dir, dentry); |
87 | mutex_unlock(&dentry->d_inode->i_mutex); | 86 | mutex_unlock(&dentry->d_inode->i_mutex); |
88 | 87 | ||
@@ -96,8 +95,7 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) | |||
96 | int error; | 95 | int error; |
97 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 96 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
98 | 97 | ||
99 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, | 98 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); |
100 | I_MUTEX_CHILD, dir->i_sb); | ||
101 | error = dir->i_op->rmdir(dir, dentry); | 99 | error = dir->i_op->rmdir(dir, dentry); |
102 | if (!error) | 100 | if (!error) |
103 | dentry->d_inode->i_flags |= S_DEAD; | 101 | dentry->d_inode->i_flags |= S_DEAD; |
@@ -232,22 +230,17 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
232 | if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) | 230 | if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) |
233 | return 0; | 231 | return 0; |
234 | 232 | ||
235 | reiserfs_write_unlock(inode->i_sb); | ||
236 | dir = open_xa_dir(inode, XATTR_REPLACE); | 233 | dir = open_xa_dir(inode, XATTR_REPLACE); |
237 | if (IS_ERR(dir)) { | 234 | if (IS_ERR(dir)) { |
238 | err = PTR_ERR(dir); | 235 | err = PTR_ERR(dir); |
239 | reiserfs_write_lock(inode->i_sb); | ||
240 | goto out; | 236 | goto out; |
241 | } else if (!dir->d_inode) { | 237 | } else if (!dir->d_inode) { |
242 | err = 0; | 238 | err = 0; |
243 | reiserfs_write_lock(inode->i_sb); | ||
244 | goto out_dir; | 239 | goto out_dir; |
245 | } | 240 | } |
246 | 241 | ||
247 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); | 242 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); |
248 | 243 | ||
249 | reiserfs_write_lock(inode->i_sb); | ||
250 | |||
251 | buf.xadir = dir; | 244 | buf.xadir = dir; |
252 | while (1) { | 245 | while (1) { |
253 | err = reiserfs_readdir_inode(dir->d_inode, &buf.ctx); | 246 | err = reiserfs_readdir_inode(dir->d_inode, &buf.ctx); |
@@ -281,14 +274,17 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
281 | int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 + | 274 | int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 + |
282 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); | 275 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); |
283 | struct reiserfs_transaction_handle th; | 276 | struct reiserfs_transaction_handle th; |
277 | reiserfs_write_lock(inode->i_sb); | ||
284 | err = journal_begin(&th, inode->i_sb, blocks); | 278 | err = journal_begin(&th, inode->i_sb, blocks); |
279 | reiserfs_write_unlock(inode->i_sb); | ||
285 | if (!err) { | 280 | if (!err) { |
286 | int jerror; | 281 | int jerror; |
287 | reiserfs_mutex_lock_nested_safe( | 282 | mutex_lock_nested(&dir->d_parent->d_inode->i_mutex, |
288 | &dir->d_parent->d_inode->i_mutex, | 283 | I_MUTEX_XATTR); |
289 | I_MUTEX_XATTR, inode->i_sb); | ||
290 | err = action(dir, data); | 284 | err = action(dir, data); |
285 | reiserfs_write_lock(inode->i_sb); | ||
291 | jerror = journal_end(&th, inode->i_sb, blocks); | 286 | jerror = journal_end(&th, inode->i_sb, blocks); |
287 | reiserfs_write_unlock(inode->i_sb); | ||
292 | mutex_unlock(&dir->d_parent->d_inode->i_mutex); | 288 | mutex_unlock(&dir->d_parent->d_inode->i_mutex); |
293 | err = jerror ?: err; | 289 | err = jerror ?: err; |
294 | } | 290 | } |
@@ -455,9 +451,7 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name) | |||
455 | } | 451 | } |
456 | 452 | ||
457 | if (dentry->d_inode) { | 453 | if (dentry->d_inode) { |
458 | reiserfs_write_lock(inode->i_sb); | ||
459 | err = xattr_unlink(xadir->d_inode, dentry); | 454 | err = xattr_unlink(xadir->d_inode, dentry); |
460 | reiserfs_write_unlock(inode->i_sb); | ||
461 | update_ctime(inode); | 455 | update_ctime(inode); |
462 | } | 456 | } |
463 | 457 | ||
@@ -491,24 +485,17 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
491 | if (get_inode_sd_version(inode) == STAT_DATA_V1) | 485 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
492 | return -EOPNOTSUPP; | 486 | return -EOPNOTSUPP; |
493 | 487 | ||
494 | reiserfs_write_unlock(inode->i_sb); | ||
495 | |||
496 | if (!buffer) { | 488 | if (!buffer) { |
497 | err = lookup_and_delete_xattr(inode, name); | 489 | err = lookup_and_delete_xattr(inode, name); |
498 | reiserfs_write_lock(inode->i_sb); | ||
499 | return err; | 490 | return err; |
500 | } | 491 | } |
501 | 492 | ||
502 | dentry = xattr_lookup(inode, name, flags); | 493 | dentry = xattr_lookup(inode, name, flags); |
503 | if (IS_ERR(dentry)) { | 494 | if (IS_ERR(dentry)) |
504 | reiserfs_write_lock(inode->i_sb); | ||
505 | return PTR_ERR(dentry); | 495 | return PTR_ERR(dentry); |
506 | } | ||
507 | 496 | ||
508 | down_write(&REISERFS_I(inode)->i_xattr_sem); | 497 | down_write(&REISERFS_I(inode)->i_xattr_sem); |
509 | 498 | ||
510 | reiserfs_write_lock(inode->i_sb); | ||
511 | |||
512 | xahash = xattr_hash(buffer, buffer_size); | 499 | xahash = xattr_hash(buffer, buffer_size); |
513 | while (buffer_pos < buffer_size || buffer_pos == 0) { | 500 | while (buffer_pos < buffer_size || buffer_pos == 0) { |
514 | size_t chunk; | 501 | size_t chunk; |
@@ -538,6 +525,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
538 | rxh->h_hash = cpu_to_le32(xahash); | 525 | rxh->h_hash = cpu_to_le32(xahash); |
539 | } | 526 | } |
540 | 527 | ||
528 | reiserfs_write_lock(inode->i_sb); | ||
541 | err = __reiserfs_write_begin(page, page_offset, chunk + skip); | 529 | err = __reiserfs_write_begin(page, page_offset, chunk + skip); |
542 | if (!err) { | 530 | if (!err) { |
543 | if (buffer) | 531 | if (buffer) |
@@ -546,6 +534,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
546 | page_offset + chunk + | 534 | page_offset + chunk + |
547 | skip); | 535 | skip); |
548 | } | 536 | } |
537 | reiserfs_write_unlock(inode->i_sb); | ||
549 | unlock_page(page); | 538 | unlock_page(page); |
550 | reiserfs_put_page(page); | 539 | reiserfs_put_page(page); |
551 | buffer_pos += chunk; | 540 | buffer_pos += chunk; |
@@ -563,10 +552,8 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
563 | .ia_valid = ATTR_SIZE | ATTR_CTIME, | 552 | .ia_valid = ATTR_SIZE | ATTR_CTIME, |
564 | }; | 553 | }; |
565 | 554 | ||
566 | reiserfs_write_unlock(inode->i_sb); | ||
567 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); | 555 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); |
568 | inode_dio_wait(dentry->d_inode); | 556 | inode_dio_wait(dentry->d_inode); |
569 | reiserfs_write_lock(inode->i_sb); | ||
570 | 557 | ||
571 | err = reiserfs_setattr(dentry, &newattrs); | 558 | err = reiserfs_setattr(dentry, &newattrs); |
572 | mutex_unlock(&dentry->d_inode->i_mutex); | 559 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -592,18 +579,19 @@ int reiserfs_xattr_set(struct inode *inode, const char *name, | |||
592 | 579 | ||
593 | reiserfs_write_lock(inode->i_sb); | 580 | reiserfs_write_lock(inode->i_sb); |
594 | error = journal_begin(&th, inode->i_sb, jbegin_count); | 581 | error = journal_begin(&th, inode->i_sb, jbegin_count); |
582 | reiserfs_write_unlock(inode->i_sb); | ||
595 | if (error) { | 583 | if (error) { |
596 | reiserfs_write_unlock(inode->i_sb); | ||
597 | return error; | 584 | return error; |
598 | } | 585 | } |
599 | 586 | ||
600 | error = reiserfs_xattr_set_handle(&th, inode, name, | 587 | error = reiserfs_xattr_set_handle(&th, inode, name, |
601 | buffer, buffer_size, flags); | 588 | buffer, buffer_size, flags); |
602 | 589 | ||
590 | reiserfs_write_lock(inode->i_sb); | ||
603 | error2 = journal_end(&th, inode->i_sb, jbegin_count); | 591 | error2 = journal_end(&th, inode->i_sb, jbegin_count); |
592 | reiserfs_write_unlock(inode->i_sb); | ||
604 | if (error == 0) | 593 | if (error == 0) |
605 | error = error2; | 594 | error = error2; |
606 | reiserfs_write_unlock(inode->i_sb); | ||
607 | 595 | ||
608 | return error; | 596 | return error; |
609 | } | 597 | } |
@@ -968,7 +956,7 @@ int reiserfs_lookup_privroot(struct super_block *s) | |||
968 | int err = 0; | 956 | int err = 0; |
969 | 957 | ||
970 | /* If we don't have the privroot located yet - go find it */ | 958 | /* If we don't have the privroot located yet - go find it */ |
971 | reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s); | 959 | mutex_lock(&s->s_root->d_inode->i_mutex); |
972 | dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, | 960 | dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, |
973 | strlen(PRIVROOT_NAME)); | 961 | strlen(PRIVROOT_NAME)); |
974 | if (!IS_ERR(dentry)) { | 962 | if (!IS_ERR(dentry)) { |
@@ -996,14 +984,14 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) | |||
996 | goto error; | 984 | goto error; |
997 | 985 | ||
998 | if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) { | 986 | if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) { |
999 | reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s); | 987 | mutex_lock(&s->s_root->d_inode->i_mutex); |
1000 | err = create_privroot(REISERFS_SB(s)->priv_root); | 988 | err = create_privroot(REISERFS_SB(s)->priv_root); |
1001 | mutex_unlock(&s->s_root->d_inode->i_mutex); | 989 | mutex_unlock(&s->s_root->d_inode->i_mutex); |
1002 | } | 990 | } |
1003 | 991 | ||
1004 | if (privroot->d_inode) { | 992 | if (privroot->d_inode) { |
1005 | s->s_xattr = reiserfs_xattr_handlers; | 993 | s->s_xattr = reiserfs_xattr_handlers; |
1006 | reiserfs_mutex_lock_safe(&privroot->d_inode->i_mutex, s); | 994 | mutex_lock(&privroot->d_inode->i_mutex); |
1007 | if (!REISERFS_SB(s)->xattr_root) { | 995 | if (!REISERFS_SB(s)->xattr_root) { |
1008 | struct dentry *dentry; | 996 | struct dentry *dentry; |
1009 | dentry = lookup_one_len(XAROOT_NAME, privroot, | 997 | dentry = lookup_one_len(XAROOT_NAME, privroot, |