Yan Zheng
2007-Sep-25 06:00 UTC
[btrfs-devel][patch]truncate inline data in btrfs_truncate_in_trans
Hello, I made a mistake in previous reply. Inline data are convert into extent after a file is truncated , so there is no need to check inode->i_size in btrfs_get_extent when encounter inline data. The remaining advantage of truncating inline data is that inline data doesn't leak on crash. I don't know whether it's still worth a change. If it's worth it, here is the patch. Thanks YZ diff -r 29b8cc7794ac inode.c --- a/inode.c Thu Sep 20 14:14:42 2007 -0400 +++ b/inode.c Tue Sep 25 16:03:35 2007 +0800 @@ -520,6 +520,7 @@ static int btrfs_truncate_in_trans(struc u64 extent_start = 0; u64 extent_num_blocks = 0; u64 item_end = 0; + int extent_type; int found_extent; int del_item; @@ -534,6 +535,7 @@ static int btrfs_truncate_in_trans(struc while(1) { btrfs_init_path(path); fi = NULL; + extent_type = -1; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret < 0) { goto error; @@ -559,10 +561,14 @@ static int btrfs_truncate_in_trans(struc fi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], struct btrfs_file_extent_item); - if (btrfs_file_extent_type(fi) !- BTRFS_FILE_EXTENT_INLINE) { + extent_type = btrfs_file_extent_type(fi); + if (extent_type == BTRFS_FILE_EXTENT_REG) { item_end += btrfs_file_extent_num_blocks(fi) << inode->i_blkbits; + } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { + struct btrfs_item *item + leaf->items + path->slots[0]; + item_end += btrfs_file_extent_inline_len(item); } } if (found_type == BTRFS_CSUM_ITEM_KEY) { @@ -589,10 +595,11 @@ static int btrfs_truncate_in_trans(struc del_item = 0; found_extent = 0; + if (found_type != BTRFS_EXTENT_DATA_KEY) + goto delete; + /* FIXME, shrink the extent if the ref count is only 1 */ - if (found_type == BTRFS_EXTENT_DATA_KEY && - btrfs_file_extent_type(fi) !- BTRFS_FILE_EXTENT_INLINE) { + if (extent_type == BTRFS_FILE_EXTENT_REG) { u64 num_dec; extent_start = btrfs_file_extent_disk_blocknr(fi); if (!del_item) { @@ -620,7 +627,15 @@ static int btrfs_truncate_in_trans(struc inode->i_blocks -= num_dec; } } - } + } else if (extent_type == BTRFS_FILE_EXTENT_INLINE && + !del_item) { + u32 newsize = inode->i_size - + btrfs_disk_key_offset(found_key); + newsize = btrfs_file_extent_calc_inline_size(newsize); + ret = btrfs_truncate_item(trans, root, path, newsize); + BUG_ON(ret); + } +delete: if (del_item) { ret = btrfs_del_item(trans, root, path); if (ret)
Chris Mason
2007-Sep-25 16:22 UTC
[btrfs-devel][patch]truncate inline data in btrfs_truncate_in_trans
On Tue, 2007-09-25 at 20:59 +0800, Yan Zheng wrote:> Hello, > > I made a mistake in previous reply. Inline data are convert into > extent after a file is truncated , so there is no need to check > inode->i_size in btrfs_get_extent when encounter inline data. The > remaining advantage of truncating inline data is that inline data > doesn't leak on crash. I don't know whether it's still worth a change. > If it's worth it, here is the patch. >Thanks! I'll put this in the queue after my large blocksize work is done. -chris