[btrfs-devel][patch]truncate inline data in btrfs_truncate_in_trans
Yan Zheng
yanzheng at 21cn.com
Tue Sep 25 05:59:57 PDT 2007
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)
More information about the Btrfs-devel
mailing list