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)

_______________________________________________
Btrfs-devel mailing list
[email protected]
http://oss.oracle.com/mailman/listinfo/btrfs-devel

Reply via email to