diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext3/xattr.c | 42 | ||||
-rw-r--r-- | fs/ext4/xattr.c | 41 |
2 files changed, 51 insertions, 32 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); | ||
506 | out: | ||
507 | ext3_std_error(inode->i_sb, error); | ||
508 | return; | ||
503 | } | 509 | } |
504 | 510 | ||
505 | struct ext3_xattr_info { | 511 | struct 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; |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index dc969c357aa1..e832e96095b3 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -475,8 +475,14 @@ ext4_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(ext4_xattr_cache, bh->b_bdev, bh->b_blocknr); | 480 | ce = mb_cache_entry_get(ext4_xattr_cache, bh->b_bdev, bh->b_blocknr); |
481 | error = ext4_journal_get_write_access(handle, bh); | ||
482 | if (error) | ||
483 | goto out; | ||
484 | |||
485 | lock_buffer(bh); | ||
480 | if (BHDR(bh)->h_refcount == cpu_to_le32(1)) { | 486 | if (BHDR(bh)->h_refcount == cpu_to_le32(1)) { |
481 | ea_bdebug(bh, "refcount now=0; freeing"); | 487 | ea_bdebug(bh, "refcount now=0; freeing"); |
482 | if (ce) | 488 | if (ce) |
@@ -485,21 +491,21 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode, | |||
485 | get_bh(bh); | 491 | get_bh(bh); |
486 | ext4_forget(handle, 1, inode, bh, bh->b_blocknr); | 492 | ext4_forget(handle, 1, inode, bh, bh->b_blocknr); |
487 | } else { | 493 | } else { |
488 | if (ext4_journal_get_write_access(handle, bh) == 0) { | 494 | 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); | 495 | le32_to_cpu(BHDR(bh)->h_refcount) - 1); |
492 | ext4_journal_dirty_metadata(handle, bh); | 496 | error = ext4_journal_dirty_metadata(handle, bh); |
493 | if (IS_SYNC(inode)) | 497 | if (IS_SYNC(inode)) |
494 | handle->h_sync = 1; | 498 | handle->h_sync = 1; |
495 | DQUOT_FREE_BLOCK(inode, 1); | 499 | DQUOT_FREE_BLOCK(inode, 1); |
496 | unlock_buffer(bh); | 500 | ea_bdebug(bh, "refcount now=%d; releasing", |
497 | ea_bdebug(bh, "refcount now=%d; releasing", | 501 | le32_to_cpu(BHDR(bh)->h_refcount)); |
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); | ||
506 | out: | ||
507 | ext4_std_error(inode->i_sb, error); | ||
508 | return; | ||
503 | } | 509 | } |
504 | 510 | ||
505 | struct ext4_xattr_info { | 511 | struct ext4_xattr_info { |
@@ -675,7 +681,7 @@ ext4_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 ext4_xattr_search *s = &bs->s; | 682 | struct ext4_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 ext4_xattr_header *)(x)) | 686 | #define header(x) ((struct ext4_xattr_header *)(x)) |
681 | 687 | ||
@@ -684,16 +690,17 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, | |||
684 | if (s->base) { | 690 | if (s->base) { |
685 | ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, | 691 | ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, |
686 | bs->bh->b_blocknr); | 692 | bs->bh->b_blocknr); |
693 | error = ext4_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 = ext4_journal_get_write_access(handle, bs->bh); | ||
694 | if (error) | ||
695 | goto cleanup; | ||
696 | lock_buffer(bs->bh); | ||
697 | error = ext4_xattr_set_entry(i, s); | 704 | error = ext4_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,8 @@ ext4_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 | jbd2_journal_release_buffer(handle, bs->bh); | ||
716 | if (ce) { | 725 | if (ce) { |
717 | mb_cache_entry_release(ce); | 726 | mb_cache_entry_release(ce); |
718 | ce = NULL; | 727 | ce = NULL; |