[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