Skip to contentSkip to conversation

Btrfs: fix btrfsck error 400 when truncating a compressed file extent

PATCH Superseded Miao Xie 2 participants 3 messages Jan 5, 2012 – Jan 9, 2012 Btrfs file system

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Miao Xie

author
#0 lore raw

PATCH 1/3 Btrfs: fix btrfsck error 400 when truncating a compressed file extent

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.

---
 fs/btrfs/inode.c |    8 +-------
 1 files changed, 1 insertions(+), 7 deletions(-)
fs/btrfs/inode.c +1 -7
index 13b0542..85e2312 100644
@@ -3009,7 +3009,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
 	int pending_del_nr = 0;
 	int pending_del_slot = 0;
 	int extent_type = -1;
-	int encoding;
 	int ret;
 	int err = 0;
 	u64 ino = btrfs_ino(inode);
@@ -3059,7 +3058,6 @@ search_again:
 		leaf = path->nodes[0];
 		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
 		found_type = btrfs_key_type(&found_key);
-		encoding = 0;
 
 		if (found_key.objectid != ino)
 			break;
@@ -3072,10 +3070,6 @@ search_again:
 			fi = btrfs_item_ptr(leaf, path->slots[0],
 					    struct btrfs_file_extent_item);
 			extent_type = btrfs_file_extent_type(leaf, fi);
-			encoding = btrfs_file_extent_compression(leaf, fi);
-			encoding |= btrfs_file_extent_encryption(leaf, fi);
-			encoding |= btrfs_file_extent_other_encoding(leaf, fi);
-
 			if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
 				item_end +=
 				    btrfs_file_extent_num_bytes(leaf, fi);
@@ -3103,7 +3097,7 @@ search_again:
 		if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
 			u64 num_dec;
 			extent_start = btrfs_file_extent_disk_bytenr(leaf, fi);
-			if (!del_item && !encoding) {
+			if (!del_item) {
 				u64 orig_num_bytes =
 					btrfs_file_extent_num_bytes(leaf, fi);
 				extent_num_bytes = new_size -
Signature · 1 line
1.7.6.4
#1 lore raw

2012/1/5 Miao Xie <[email protected]>:

Quoted 7 lines

Reproduce steps:
=A0# mkfs.btrfs /dev/sdb5
=A0# mount /dev/sdb5 -o compress=3Dlzo /mnt
=A0# dd if=3D/dev/zero of=3D/mnt/tmpfile bs=3D128K count=3D1 =A0# sync
=A0# truncate -s 64K /mnt/tmpfile
=A0root 5 inode 257 errors 400

Is this patch set intended to address the general case of btrfsck inode 400 errors, or is it intended for this specific case.

I've been picking up btrfsck inode 400 errors all over the place recently on unclean shutdowns, and I was wondering if this patch set might address the issue of unclean shutdowns, or if there is a more general COW regression out there (or if I'm just extremely unlucky). --
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" = in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#2 lore raw
Quoted 9 lines · Mitch Harder

2012/1/5 Miao Xie <[email protected]>:

Quoted 7 lines

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
Quoted 7 lines

Is this patch set intended to address the general case of btrfsck inode 400 errors, or is it intended for this specific case.

I've been picking up btrfsck inode 400 errors all over the place recently on unclean shutdowns, and I was wondering if this patch set might address the issue of unclean shutdowns, or if there is a more general COW regression out there (or if I'm just extremely unlucky).

The purpose of this patch set is to fix the bug of the left orphan items which is caused by the truncation, not the general case of btrfsck 400 errors.

Thanks
Miao