aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-24 11:57:52 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commit3eaa2885276fd6dac7b076a793932428b7168e74 (patch)
treeb06382bec68bf1755597a74ac8225f3bcddda5e5 /fs/btrfs/ordered-data.c
parent64f26f745084872b916cd1bef6054e21b15c5784 (diff)
Btrfs: Fix the defragmention code and the block relocation code for data=ordered
Before setting an extent to delalloc, the code needs to wait for pending ordered extents. Also, the relocation code needs to wait for ordered IO before scanning the block group again. This is because the extents are not removed until the IO for the new extents is finished Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index e42fd233e04c..676e4bd65c52 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -167,20 +167,28 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
167 entry->file_offset = file_offset; 167 entry->file_offset = file_offset;
168 entry->start = start; 168 entry->start = start;
169 entry->len = len; 169 entry->len = len;
170 entry->inode = inode;
171
170 /* one ref for the tree */ 172 /* one ref for the tree */
171 atomic_set(&entry->refs, 1); 173 atomic_set(&entry->refs, 1);
172 init_waitqueue_head(&entry->wait); 174 init_waitqueue_head(&entry->wait);
173 INIT_LIST_HEAD(&entry->list); 175 INIT_LIST_HEAD(&entry->list);
176 INIT_LIST_HEAD(&entry->root_extent_list);
174 177
175 node = tree_insert(&tree->tree, file_offset, 178 node = tree_insert(&tree->tree, file_offset,
176 &entry->rb_node); 179 &entry->rb_node);
177 if (node) { 180 if (node) {
178 entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); 181 printk("warning dup entry from add_ordered_extent\n");
179 atomic_inc(&entry->refs); 182 BUG();
180 } 183 }
181 set_extent_ordered(&BTRFS_I(inode)->io_tree, file_offset, 184 set_extent_ordered(&BTRFS_I(inode)->io_tree, file_offset,
182 entry_end(entry) - 1, GFP_NOFS); 185 entry_end(entry) - 1, GFP_NOFS);
183 186
187 spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
188 list_add_tail(&entry->root_extent_list,
189 &BTRFS_I(inode)->root->fs_info->ordered_extents);
190 spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
191
184 mutex_unlock(&tree->mutex); 192 mutex_unlock(&tree->mutex);
185 BUG_ON(node); 193 BUG_ON(node);
186 return 0; 194 return 0;
@@ -285,11 +293,55 @@ int btrfs_remove_ordered_extent(struct inode *inode,
285 rb_erase(node, &tree->tree); 293 rb_erase(node, &tree->tree);
286 tree->last = NULL; 294 tree->last = NULL;
287 set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); 295 set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags);
296
297 spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
298 list_del_init(&entry->root_extent_list);
299 spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
300
288 mutex_unlock(&tree->mutex); 301 mutex_unlock(&tree->mutex);
289 wake_up(&entry->wait); 302 wake_up(&entry->wait);
290 return 0; 303 return 0;
291} 304}
292 305
306int btrfs_wait_ordered_extents(struct btrfs_root *root)
307{
308 struct list_head splice;
309 struct list_head *cur;
310 struct btrfs_ordered_extent *ordered;
311 struct inode *inode;
312
313 INIT_LIST_HEAD(&splice);
314
315 spin_lock(&root->fs_info->ordered_extent_lock);
316 list_splice_init(&root->fs_info->ordered_extents, &splice);
317 while(!list_empty(&splice)) {
318 cur = splice.next;
319 ordered = list_entry(cur, struct btrfs_ordered_extent,
320 root_extent_list);
321 list_del_init(&ordered->root_extent_list);
322 atomic_inc(&ordered->refs);
323 inode = ordered->inode;
324
325 /*
326 * the inode can't go away until all the pages are gone
327 * and the pages won't go away while there is still
328 * an ordered extent and the ordered extent won't go
329 * away until it is off this list. So, we can safely
330 * increment i_count here and call iput later
331 */
332 atomic_inc(&inode->i_count);
333 spin_unlock(&root->fs_info->ordered_extent_lock);
334
335 btrfs_start_ordered_extent(inode, ordered, 1);
336 btrfs_put_ordered_extent(ordered);
337 iput(inode);
338
339 spin_lock(&root->fs_info->ordered_extent_lock);
340 }
341 spin_unlock(&root->fs_info->ordered_extent_lock);
342 return 0;
343}
344
293/* 345/*
294 * Used to start IO or wait for a given ordered extent to finish. 346 * Used to start IO or wait for a given ordered extent to finish.
295 * 347 *