aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3')
-rw-r--r--fs/ext3/xattr.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 99857a400f4b..12f7dda1232c 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -475,8 +475,15 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode,
475 struct buffer_head *bh) 475 struct buffer_head *bh)
476{ 476{
477 struct mb_cache_entry *ce = NULL; 477 struct mb_cache_entry *ce = NULL;
478 int error = 0;
478 479
479 ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, bh->b_blocknr); 480 ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, bh->b_blocknr);
481 error = ext3_journal_get_write_access(handle, bh);
482 if (error)
483 goto out;
484
485 lock_buffer(bh);
486
480 if (BHDR(bh)->h_refcount == cpu_to_le32(1)) { 487 if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
481 ea_bdebug(bh, "refcount now=0; freeing"); 488 ea_bdebug(bh, "refcount now=0; freeing");
482 if (ce) 489 if (ce)
@@ -485,21 +492,20 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode,
485 get_bh(bh); 492 get_bh(bh);
486 ext3_forget(handle, 1, inode, bh, bh->b_blocknr); 493 ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
487 } else { 494 } else {
488 if (ext3_journal_get_write_access(handle, bh) == 0) { 495 BHDR(bh)->h_refcount = cpu_to_le32(
489 lock_buffer(bh);
490 BHDR(bh)->h_refcount = cpu_to_le32(
491 le32_to_cpu(BHDR(bh)->h_refcount) - 1); 496 le32_to_cpu(BHDR(bh)->h_refcount) - 1);
492 ext3_journal_dirty_metadata(handle, bh); 497 error = ext3_journal_dirty_metadata(handle, bh);
493 if (IS_SYNC(inode)) 498 handle->h_sync = 1;
494 handle->h_sync = 1; 499 DQUOT_FREE_BLOCK(inode, 1);
495 DQUOT_FREE_BLOCK(inode, 1); 500 ea_bdebug(bh, "refcount now=%d; releasing",
496 unlock_buffer(bh); 501 le32_to_cpu(BHDR(bh)->h_refcount));
497 ea_bdebug(bh, "refcount now=%d; releasing",
498 le32_to_cpu(BHDR(bh)->h_refcount));
499 }
500 if (ce) 502 if (ce)
501 mb_cache_entry_release(ce); 503 mb_cache_entry_release(ce);
502 } 504 }
505 unlock_buffer(bh);
506out:
507 ext3_std_error(inode->i_sb, error);
508 return;
503} 509}
504 510
505struct ext3_xattr_info { 511struct ext3_xattr_info {
@@ -675,7 +681,7 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
675 struct buffer_head *new_bh = NULL; 681 struct buffer_head *new_bh = NULL;
676 struct ext3_xattr_search *s = &bs->s; 682 struct ext3_xattr_search *s = &bs->s;
677 struct mb_cache_entry *ce = NULL; 683 struct mb_cache_entry *ce = NULL;
678 int error; 684 int error = 0;
679 685
680#define header(x) ((struct ext3_xattr_header *)(x)) 686#define header(x) ((struct ext3_xattr_header *)(x))
681 687
@@ -684,16 +690,17 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
684 if (s->base) { 690 if (s->base) {
685 ce = mb_cache_entry_get(ext3_xattr_cache, bs->bh->b_bdev, 691 ce = mb_cache_entry_get(ext3_xattr_cache, bs->bh->b_bdev,
686 bs->bh->b_blocknr); 692 bs->bh->b_blocknr);
693 error = ext3_journal_get_write_access(handle, bs->bh);
694 if (error)
695 goto cleanup;
696 lock_buffer(bs->bh);
697
687 if (header(s->base)->h_refcount == cpu_to_le32(1)) { 698 if (header(s->base)->h_refcount == cpu_to_le32(1)) {
688 if (ce) { 699 if (ce) {
689 mb_cache_entry_free(ce); 700 mb_cache_entry_free(ce);
690 ce = NULL; 701 ce = NULL;
691 } 702 }
692 ea_bdebug(bs->bh, "modifying in-place"); 703 ea_bdebug(bs->bh, "modifying in-place");
693 error = ext3_journal_get_write_access(handle, bs->bh);
694 if (error)
695 goto cleanup;
696 lock_buffer(bs->bh);
697 error = ext3_xattr_set_entry(i, s); 704 error = ext3_xattr_set_entry(i, s);
698 if (!error) { 705 if (!error) {
699 if (!IS_LAST_ENTRY(s->first)) 706 if (!IS_LAST_ENTRY(s->first))
@@ -713,6 +720,9 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
713 } else { 720 } else {
714 int offset = (char *)s->here - bs->bh->b_data; 721 int offset = (char *)s->here - bs->bh->b_data;
715 722
723 unlock_buffer(bs->bh);
724 journal_release_buffer(handle, bs->bh);
725
716 if (ce) { 726 if (ce) {
717 mb_cache_entry_release(ce); 727 mb_cache_entry_release(ce);
718 ce = NULL; 728 ce = NULL;