aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
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 *