diff options
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r-- | fs/btrfs/ordered-data.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index b16450b840e7..138a7d7e9c90 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -424,27 +424,48 @@ out: | |||
424 | } | 424 | } |
425 | 425 | ||
426 | /* Needs to either be called under a log transaction or the log_mutex */ | 426 | /* Needs to either be called under a log transaction or the log_mutex */ |
427 | void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode) | 427 | void btrfs_get_logged_extents(struct inode *inode, |
428 | struct list_head *logged_list) | ||
428 | { | 429 | { |
429 | struct btrfs_ordered_inode_tree *tree; | 430 | struct btrfs_ordered_inode_tree *tree; |
430 | struct btrfs_ordered_extent *ordered; | 431 | struct btrfs_ordered_extent *ordered; |
431 | struct rb_node *n; | 432 | struct rb_node *n; |
432 | int index = log->log_transid % 2; | ||
433 | 433 | ||
434 | tree = &BTRFS_I(inode)->ordered_tree; | 434 | tree = &BTRFS_I(inode)->ordered_tree; |
435 | spin_lock_irq(&tree->lock); | 435 | spin_lock_irq(&tree->lock); |
436 | for (n = rb_first(&tree->tree); n; n = rb_next(n)) { | 436 | for (n = rb_first(&tree->tree); n; n = rb_next(n)) { |
437 | ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node); | 437 | ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node); |
438 | spin_lock(&log->log_extents_lock[index]); | 438 | if (!list_empty(&ordered->log_list)) |
439 | if (list_empty(&ordered->log_list)) { | 439 | continue; |
440 | list_add_tail(&ordered->log_list, &log->logged_list[index]); | 440 | list_add_tail(&ordered->log_list, logged_list); |
441 | atomic_inc(&ordered->refs); | 441 | atomic_inc(&ordered->refs); |
442 | } | ||
443 | spin_unlock(&log->log_extents_lock[index]); | ||
444 | } | 442 | } |
445 | spin_unlock_irq(&tree->lock); | 443 | spin_unlock_irq(&tree->lock); |
446 | } | 444 | } |
447 | 445 | ||
446 | void btrfs_put_logged_extents(struct list_head *logged_list) | ||
447 | { | ||
448 | struct btrfs_ordered_extent *ordered; | ||
449 | |||
450 | while (!list_empty(logged_list)) { | ||
451 | ordered = list_first_entry(logged_list, | ||
452 | struct btrfs_ordered_extent, | ||
453 | log_list); | ||
454 | list_del_init(&ordered->log_list); | ||
455 | btrfs_put_ordered_extent(ordered); | ||
456 | } | ||
457 | } | ||
458 | |||
459 | void btrfs_submit_logged_extents(struct list_head *logged_list, | ||
460 | struct btrfs_root *log) | ||
461 | { | ||
462 | int index = log->log_transid % 2; | ||
463 | |||
464 | spin_lock_irq(&log->log_extents_lock[index]); | ||
465 | list_splice_tail(logged_list, &log->logged_list[index]); | ||
466 | spin_unlock_irq(&log->log_extents_lock[index]); | ||
467 | } | ||
468 | |||
448 | void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid) | 469 | void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid) |
449 | { | 470 | { |
450 | struct btrfs_ordered_extent *ordered; | 471 | struct btrfs_ordered_extent *ordered; |