Btrfs: Make defrag check nodes against the progress key to prevent repeating work
authorChris Mason <chris.mason@oracle.com>
Tue, 6 Nov 2007 15:26:24 +0000 (10:26 -0500)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:03:57 +0000 (11:03 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ctree.c
fs/btrfs/tree-defrag.c

index eef9c92f86d5408397c98e4e373e57b86d7f0a08..ea9b4669934993bc4a42787355fdd82e5e976cda 100644 (file)
@@ -161,6 +161,31 @@ static int close_blocks(u64 blocknr, u64 other, u32 blocksize)
        return 0;
 }
 
+/*
+ * compare two keys in a memcmp fashion
+ */
+static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
+{
+       struct btrfs_key k1;
+
+       btrfs_disk_key_to_cpu(&k1, disk);
+
+       if (k1.objectid > k2->objectid)
+               return 1;
+       if (k1.objectid < k2->objectid)
+               return -1;
+       if (k1.type > k2->type)
+               return 1;
+       if (k1.type < k2->type)
+               return -1;
+       if (k1.offset > k2->offset)
+               return 1;
+       if (k1.offset < k2->offset)
+               return -1;
+       return 0;
+}
+
+
 int btrfs_realloc_node(struct btrfs_trans_handle *trans,
                       struct btrfs_root *root, struct extent_buffer *parent,
                       int start_slot, int cache_only, u64 *last_ret,
@@ -179,6 +204,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
        int parent_level;
        int uptodate;
        u32 blocksize;
+       int progress_passed = 0;
+       struct btrfs_disk_key disk_key;
 
        parent_level = btrfs_header_level(parent);
        if (cache_only && parent_level != 1)
@@ -213,6 +240,11 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
                                        &parent->map_start, &parent->map_len,
                                        KM_USER1);
                }
+               btrfs_node_key(parent, &disk_key, i);
+               if (!progress_passed && comp_keys(&disk_key, progress) < 0)
+                       continue;
+
+               progress_passed = 1;
                blocknr = btrfs_node_blockptr(parent, i);
                if (last_block == 0)
                        last_block = blocknr;
@@ -292,30 +324,6 @@ static inline unsigned int leaf_data_end(struct btrfs_root *root,
        return btrfs_item_offset_nr(leaf, nr - 1);
 }
 
-/*
- * compare two keys in a memcmp fashion
- */
-static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
-{
-       struct btrfs_key k1;
-
-       btrfs_disk_key_to_cpu(&k1, disk);
-
-       if (k1.objectid > k2->objectid)
-               return 1;
-       if (k1.objectid < k2->objectid)
-               return -1;
-       if (k1.type > k2->type)
-               return 1;
-       if (k1.type < k2->type)
-               return -1;
-       if (k1.offset > k2->offset)
-               return 1;
-       if (k1.offset < k2->offset)
-               return -1;
-       return 0;
-}
-
 static int check_node(struct btrfs_root *root, struct btrfs_path *path,
                      int level)
 {
index 65ef12351566e23a1b124998251bca016dcf5ec2..6ef1ba5f9c2fd1fadde34dba562780592d8978c9 100644 (file)
@@ -227,7 +227,8 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
                        break;
                if (wret < 0)
                        ret = wret;
-               ret = -EAGAIN;
+               else
+                       ret = -EAGAIN;
                break;
        }
        for (i = 0; i <= orig_level; i++) {