btrfs_drop_extents: make sure the item is getting smaller before truncate
authorChris Mason <chris.mason@oracle.com>
Fri, 30 Nov 2007 15:09:33 +0000 (10:09 -0500)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:03:58 +0000 (11:03 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/file.c

index 56b977ffe918746cd9210fcb2dcce02e1ac9fa54..b29b911dd825a97e70663e08af370bab91a3690a 100644 (file)
@@ -1037,7 +1037,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end);
 extern struct file_operations btrfs_file_operations;
 int btrfs_drop_extents(struct btrfs_trans_handle *trans,
                       struct btrfs_root *root, struct inode *inode,
-                      u64 start, u64 end, u64 inline_end, u64 *hint_block);
+                      u64 start, u64 end, u64 inline_limit, u64 *hint_block);
 /* tree-defrag.c */
 int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
                        struct btrfs_root *root, int cache_only);
index 3c00f967eccb713d4fcb4ad8ce7e59f6c021bc5d..55abdf997ca571ff2de621586085d1568cdcb17d 100644 (file)
@@ -45,6 +45,9 @@ static int cache_block_group(struct btrfs_root *root,
        u64 first_free;
        int found = 0;
 
+       if (!block_group)
+               return 0;
+
        root = root->fs_info->extent_root;
        free_space_cache = &root->fs_info->free_space_cache;
 
@@ -168,6 +171,11 @@ static u64 find_search_start(struct btrfs_root *root,
        u64 cache_miss = 0;
        int wrapped = 0;
 
+       if (!cache) {
+               cache = btrfs_lookup_block_group(root->fs_info, search_start);
+               if (!cache)
+                       return search_start;
+       }
 again:
        ret = cache_block_group(root, cache);
        if (ret)
index ba624ae16e61c7d896a05e4866e35d4e04306948..b0d637787264a16bc32cbd386749c69ebda1c93f 100644 (file)
@@ -377,23 +377,23 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
  */
 int btrfs_drop_extents(struct btrfs_trans_handle *trans,
                       struct btrfs_root *root, struct inode *inode,
-                      u64 start, u64 end, u64 inline_end, u64 *hint_byte)
+                      u64 start, u64 end, u64 inline_limit, u64 *hint_byte)
 {
-       int ret;
-       struct btrfs_key key;
+       u64 extent_end = 0;
+       u64 search_start = start;
        struct extent_buffer *leaf;
-       int slot;
        struct btrfs_file_extent_item *extent;
-       u64 extent_end = 0;
-       int keep;
-       struct btrfs_file_extent_item old;
        struct btrfs_path *path;
-       u64 search_start = start;
+       struct btrfs_key key;
+       struct btrfs_file_extent_item old;
+       int keep;
+       int slot;
        int bookend;
        int found_type;
        int found_extent;
        int found_inline;
        int recow;
+       int ret;
 
        btrfs_drop_extent_cache(inode, start, end - 1);
 
@@ -502,7 +502,7 @@ next_slot:
                        }
                        bookend = 1;
                        if (found_inline && start <= key.offset &&
-                           inline_end < extent_end)
+                           inline_limit < extent_end)
                                keep = 1;
                }
                /* truncate existing extent */
@@ -526,12 +526,12 @@ next_slot:
                                btrfs_set_file_extent_num_bytes(leaf, extent,
                                                                new_num);
                                btrfs_mark_buffer_dirty(leaf);
-                       } else if (end > extent_end &&
-                                  key.offset < inline_end &&
-                                  inline_end < extent_end) {
+                       } else if (key.offset < inline_limit &&
+                                  (end > extent_end) &&
+                                  (inline_limit < extent_end)) {
                                u32 new_size;
                                new_size = btrfs_file_extent_calc_inline_size(
-                                                  inline_end - key.offset);
+                                                  inline_limit - key.offset);
                                btrfs_truncate_item(trans, root, path,
                                                    new_size, 1);
                        }
@@ -575,10 +575,10 @@ next_slot:
                                continue;
                }
                if (bookend && found_inline && start <= key.offset &&
-                   inline_end < extent_end) {
+                   inline_limit < extent_end && key.offset <= inline_limit) {
                        u32 new_size;
                        new_size = btrfs_file_extent_calc_inline_size(
-                                                  extent_end - inline_end);
+                                                  extent_end - inline_limit);
                        btrfs_truncate_item(trans, root, path, new_size, 0);
                }
                /* create bookend, splitting the extent in two */