aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2013-02-18 12:12:07 -0500
committerTheodore Ts'o <tytso@mit.edu>2013-02-18 12:12:07 -0500
commit1231b3a1eb5740192aeebf5344dd6d6da000febf (patch)
tree733c93fe690972f65322107e7c4841707242c3e9 /fs/ext4
parent74cd15cd02708c7188581f279f33a98b2ae8d322 (diff)
ext4: fix xattr block allocation/release with bigalloc
Currently when new xattr block is created or released we we would call dquot_free_block() or dquot_alloc_block() respectively, among the else decrementing or incrementing the number of blocks assigned to the inode by one block. This however does not work for bigalloc file system because we always allocate/free the whole cluster so we have to count with that in dquot_free_block() and dquot_alloc_block() as well. Use the clusters-to-blocks conversion EXT4_C2B() when passing number of blocks to the dquot_alloc/free functions to fix the problem. The problem has been revealed by xfstests #117 (and possibly others). Signed-off-by: Lukas Czerner <lczerner@redhat.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Reviewed-by: Eric Sandeen <sandeen@redhat.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/xattr.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index cc31da027596..3a120b277240 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -549,7 +549,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
549 error = ext4_handle_dirty_xattr_block(handle, inode, bh); 549 error = ext4_handle_dirty_xattr_block(handle, inode, bh);
550 if (IS_SYNC(inode)) 550 if (IS_SYNC(inode))
551 ext4_handle_sync(handle); 551 ext4_handle_sync(handle);
552 dquot_free_block(inode, 1); 552 dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
553 ea_bdebug(bh, "refcount now=%d; releasing", 553 ea_bdebug(bh, "refcount now=%d; releasing",
554 le32_to_cpu(BHDR(bh)->h_refcount)); 554 le32_to_cpu(BHDR(bh)->h_refcount));
555 } 555 }
@@ -832,7 +832,8 @@ inserted:
832 else { 832 else {
833 /* The old block is released after updating 833 /* The old block is released after updating
834 the inode. */ 834 the inode. */
835 error = dquot_alloc_block(inode, 1); 835 error = dquot_alloc_block(inode,
836 EXT4_C2B(EXT4_SB(sb), 1));
836 if (error) 837 if (error)
837 goto cleanup; 838 goto cleanup;
838 error = ext4_journal_get_write_access(handle, 839 error = ext4_journal_get_write_access(handle,
@@ -929,7 +930,7 @@ cleanup:
929 return error; 930 return error;
930 931
931cleanup_dquot: 932cleanup_dquot:
932 dquot_free_block(inode, 1); 933 dquot_free_block(inode, EXT4_C2B(EXT4_SB(sb), 1));
933 goto cleanup; 934 goto cleanup;
934 935
935bad_block: 936bad_block: