aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-01-12 19:10:12 -0500
committerChris Mason <chris.mason@oracle.com>2012-01-16 15:28:54 -0500
commitf70a9a6b94af86fca069a7552ab672c31b457786 (patch)
tree0a62930b2540e11b877a1ead4050c55638bbd874 /fs
parent7ad85bb76a61801362701b77c5cee5aa09f35369 (diff)
Btrfs: fix btrfsck error 400 when truncating a compressed
Reproduce steps: # mkfs.btrfs /dev/sdb5 # mount /dev/sdb5 -o compress=lzo /mnt # dd if=/dev/zero of=/mnt/tmpfile bs=128K count=1 # sync # truncate -s 64K /mnt/tmpfile root 5 inode 257 errors 400 This is because of the wrong if condition, which is used to check if we should subtract the bytes of the dropped range from i_blocks/i_bytes of i-node or not. When we truncate a compressed extent, btrfs substracts the bytes of the whole extent, it's wrong. We should substract the real size that we truncate, no matter it is a compressed extent or not. Fix it. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/inode.c8
1 files changed, 1 insertions, 7 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5f8ba210c0aa..946a7f1b3295 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3009,7 +3009,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
3009 int pending_del_nr = 0; 3009 int pending_del_nr = 0;
3010 int pending_del_slot = 0; 3010 int pending_del_slot = 0;
3011 int extent_type = -1; 3011 int extent_type = -1;
3012 int encoding;
3013 int ret; 3012 int ret;
3014 int err = 0; 3013 int err = 0;
3015 u64 ino = btrfs_ino(inode); 3014 u64 ino = btrfs_ino(inode);
@@ -3059,7 +3058,6 @@ search_again:
3059 leaf = path->nodes[0]; 3058 leaf = path->nodes[0];
3060 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 3059 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
3061 found_type = btrfs_key_type(&found_key); 3060 found_type = btrfs_key_type(&found_key);
3062 encoding = 0;
3063 3061
3064 if (found_key.objectid != ino) 3062 if (found_key.objectid != ino)
3065 break; 3063 break;
@@ -3072,10 +3070,6 @@ search_again:
3072 fi = btrfs_item_ptr(leaf, path->slots[0], 3070 fi = btrfs_item_ptr(leaf, path->slots[0],
3073 struct btrfs_file_extent_item); 3071 struct btrfs_file_extent_item);
3074 extent_type = btrfs_file_extent_type(leaf, fi); 3072 extent_type = btrfs_file_extent_type(leaf, fi);
3075 encoding = btrfs_file_extent_compression(leaf, fi);
3076 encoding |= btrfs_file_extent_encryption(leaf, fi);
3077 encoding |= btrfs_file_extent_other_encoding(leaf, fi);
3078
3079 if (extent_type != BTRFS_FILE_EXTENT_INLINE) { 3073 if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
3080 item_end += 3074 item_end +=
3081 btrfs_file_extent_num_bytes(leaf, fi); 3075 btrfs_file_extent_num_bytes(leaf, fi);
@@ -3103,7 +3097,7 @@ search_again:
3103 if (extent_type != BTRFS_FILE_EXTENT_INLINE) { 3097 if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
3104 u64 num_dec; 3098 u64 num_dec;
3105 extent_start = btrfs_file_extent_disk_bytenr(leaf, fi); 3099 extent_start = btrfs_file_extent_disk_bytenr(leaf, fi);
3106 if (!del_item && !encoding) { 3100 if (!del_item) {
3107 u64 orig_num_bytes = 3101 u64 orig_num_bytes =
3108 btrfs_file_extent_num_bytes(leaf, fi); 3102 btrfs_file_extent_num_bytes(leaf, fi);
3109 extent_num_bytes = new_size - 3103 extent_num_bytes = new_size -