aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-11-06 10:26:24 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:57 -0400
commit081e95736d9118a96e9f6dcc5cec02dc75c9e1cb (patch)
tree41c1b692a0ba44223cadae5d78bc3446f963dca1 /fs/btrfs/ctree.c
parentc549228ff63498025bf0b065c5a5909a06f21647 (diff)
Btrfs: Make defrag check nodes against the progress key to prevent repeating work
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index eef9c92f86d5..ea9b46699349 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -161,6 +161,31 @@ static int close_blocks(u64 blocknr, u64 other, u32 blocksize)
161 return 0; 161 return 0;
162} 162}
163 163
164/*
165 * compare two keys in a memcmp fashion
166 */
167static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
168{
169 struct btrfs_key k1;
170
171 btrfs_disk_key_to_cpu(&k1, disk);
172
173 if (k1.objectid > k2->objectid)
174 return 1;
175 if (k1.objectid < k2->objectid)
176 return -1;
177 if (k1.type > k2->type)
178 return 1;
179 if (k1.type < k2->type)
180 return -1;
181 if (k1.offset > k2->offset)
182 return 1;
183 if (k1.offset < k2->offset)
184 return -1;
185 return 0;
186}
187
188
164int btrfs_realloc_node(struct btrfs_trans_handle *trans, 189int btrfs_realloc_node(struct btrfs_trans_handle *trans,
165 struct btrfs_root *root, struct extent_buffer *parent, 190 struct btrfs_root *root, struct extent_buffer *parent,
166 int start_slot, int cache_only, u64 *last_ret, 191 int start_slot, int cache_only, u64 *last_ret,
@@ -179,6 +204,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
179 int parent_level; 204 int parent_level;
180 int uptodate; 205 int uptodate;
181 u32 blocksize; 206 u32 blocksize;
207 int progress_passed = 0;
208 struct btrfs_disk_key disk_key;
182 209
183 parent_level = btrfs_header_level(parent); 210 parent_level = btrfs_header_level(parent);
184 if (cache_only && parent_level != 1) 211 if (cache_only && parent_level != 1)
@@ -213,6 +240,11 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
213 &parent->map_start, &parent->map_len, 240 &parent->map_start, &parent->map_len,
214 KM_USER1); 241 KM_USER1);
215 } 242 }
243 btrfs_node_key(parent, &disk_key, i);
244 if (!progress_passed && comp_keys(&disk_key, progress) < 0)
245 continue;
246
247 progress_passed = 1;
216 blocknr = btrfs_node_blockptr(parent, i); 248 blocknr = btrfs_node_blockptr(parent, i);
217 if (last_block == 0) 249 if (last_block == 0)
218 last_block = blocknr; 250 last_block = blocknr;
@@ -292,30 +324,6 @@ static inline unsigned int leaf_data_end(struct btrfs_root *root,
292 return btrfs_item_offset_nr(leaf, nr - 1); 324 return btrfs_item_offset_nr(leaf, nr - 1);
293} 325}
294 326
295/*
296 * compare two keys in a memcmp fashion
297 */
298static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
299{
300 struct btrfs_key k1;
301
302 btrfs_disk_key_to_cpu(&k1, disk);
303
304 if (k1.objectid > k2->objectid)
305 return 1;
306 if (k1.objectid < k2->objectid)
307 return -1;
308 if (k1.type > k2->type)
309 return 1;
310 if (k1.type < k2->type)
311 return -1;
312 if (k1.offset > k2->offset)
313 return 1;
314 if (k1.offset < k2->offset)
315 return -1;
316 return 0;
317}
318
319static int check_node(struct btrfs_root *root, struct btrfs_path *path, 327static int check_node(struct btrfs_root *root, struct btrfs_path *path,
320 int level) 328 int level)
321{ 329{