diff options
| -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; |
