diff options
Diffstat (limited to 'fs/btrfs/ordered-data.c')
| -rw-r--r-- | fs/btrfs/ordered-data.c | 41 | 
1 files changed, 23 insertions, 18 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 5c2a9e78a949..a8ffecd0b491 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c  | |||
| @@ -174,7 +174,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
| 174 | if (!entry) | 174 | if (!entry) | 
| 175 | return -ENOMEM; | 175 | return -ENOMEM; | 
| 176 | 176 | ||
| 177 | mutex_lock(&tree->mutex); | ||
| 178 | entry->file_offset = file_offset; | 177 | entry->file_offset = file_offset; | 
| 179 | entry->start = start; | 178 | entry->start = start; | 
| 180 | entry->len = len; | 179 | entry->len = len; | 
| @@ -190,16 +189,17 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
| 190 | INIT_LIST_HEAD(&entry->list); | 189 | INIT_LIST_HEAD(&entry->list); | 
| 191 | INIT_LIST_HEAD(&entry->root_extent_list); | 190 | INIT_LIST_HEAD(&entry->root_extent_list); | 
| 192 | 191 | ||
| 192 | spin_lock(&tree->lock); | ||
| 193 | node = tree_insert(&tree->tree, file_offset, | 193 | node = tree_insert(&tree->tree, file_offset, | 
| 194 | &entry->rb_node); | 194 | &entry->rb_node); | 
| 195 | BUG_ON(node); | 195 | BUG_ON(node); | 
| 196 | spin_unlock(&tree->lock); | ||
| 196 | 197 | ||
| 197 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 198 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 
| 198 | list_add_tail(&entry->root_extent_list, | 199 | list_add_tail(&entry->root_extent_list, | 
| 199 | &BTRFS_I(inode)->root->fs_info->ordered_extents); | 200 | &BTRFS_I(inode)->root->fs_info->ordered_extents); | 
| 200 | spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 201 | spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 
| 201 | 202 | ||
| 202 | mutex_unlock(&tree->mutex); | ||
| 203 | BUG_ON(node); | 203 | BUG_ON(node); | 
| 204 | return 0; | 204 | return 0; | 
| 205 | } | 205 | } | 
| @@ -216,9 +216,9 @@ int btrfs_add_ordered_sum(struct inode *inode, | |||
| 216 | struct btrfs_ordered_inode_tree *tree; | 216 | struct btrfs_ordered_inode_tree *tree; | 
| 217 | 217 | ||
| 218 | tree = &BTRFS_I(inode)->ordered_tree; | 218 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 219 | mutex_lock(&tree->mutex); | 219 | spin_lock(&tree->lock); | 
| 220 | list_add_tail(&sum->list, &entry->list); | 220 | list_add_tail(&sum->list, &entry->list); | 
| 221 | mutex_unlock(&tree->mutex); | 221 | spin_unlock(&tree->lock); | 
| 222 | return 0; | 222 | return 0; | 
| 223 | } | 223 | } | 
| 224 | 224 | ||
| @@ -232,15 +232,16 @@ int btrfs_add_ordered_sum(struct inode *inode, | |||
| 232 | * to make sure this function only returns 1 once for a given ordered extent. | 232 | * to make sure this function only returns 1 once for a given ordered extent. | 
| 233 | */ | 233 | */ | 
| 234 | int btrfs_dec_test_ordered_pending(struct inode *inode, | 234 | int btrfs_dec_test_ordered_pending(struct inode *inode, | 
| 235 | struct btrfs_ordered_extent **cached, | ||
| 235 | u64 file_offset, u64 io_size) | 236 | u64 file_offset, u64 io_size) | 
| 236 | { | 237 | { | 
| 237 | struct btrfs_ordered_inode_tree *tree; | 238 | struct btrfs_ordered_inode_tree *tree; | 
| 238 | struct rb_node *node; | 239 | struct rb_node *node; | 
| 239 | struct btrfs_ordered_extent *entry; | 240 | struct btrfs_ordered_extent *entry = NULL; | 
| 240 | int ret; | 241 | int ret; | 
| 241 | 242 | ||
| 242 | tree = &BTRFS_I(inode)->ordered_tree; | 243 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 243 | mutex_lock(&tree->mutex); | 244 | spin_lock(&tree->lock); | 
| 244 | node = tree_search(tree, file_offset); | 245 | node = tree_search(tree, file_offset); | 
| 245 | if (!node) { | 246 | if (!node) { | 
| 246 | ret = 1; | 247 | ret = 1; | 
| @@ -264,7 +265,11 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, | |||
| 264 | else | 265 | else | 
| 265 | ret = 1; | 266 | ret = 1; | 
| 266 | out: | 267 | out: | 
| 267 | mutex_unlock(&tree->mutex); | 268 | if (!ret && cached && entry) { | 
| 269 | *cached = entry; | ||
| 270 | atomic_inc(&entry->refs); | ||
| 271 | } | ||
| 272 | spin_unlock(&tree->lock); | ||
| 268 | return ret == 0; | 273 | return ret == 0; | 
| 269 | } | 274 | } | 
| 270 | 275 | ||
| @@ -291,7 +296,7 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) | |||
| 291 | 296 | ||
| 292 | /* | 297 | /* | 
| 293 | * remove an ordered extent from the tree. No references are dropped | 298 | * remove an ordered extent from the tree. No references are dropped | 
| 294 | * and you must wake_up entry->wait. You must hold the tree mutex | 299 | * and you must wake_up entry->wait. You must hold the tree lock | 
| 295 | * while you call this function. | 300 | * while you call this function. | 
| 296 | */ | 301 | */ | 
| 297 | static int __btrfs_remove_ordered_extent(struct inode *inode, | 302 | static int __btrfs_remove_ordered_extent(struct inode *inode, | 
| @@ -340,9 +345,9 @@ int btrfs_remove_ordered_extent(struct inode *inode, | |||
| 340 | int ret; | 345 | int ret; | 
| 341 | 346 | ||
| 342 | tree = &BTRFS_I(inode)->ordered_tree; | 347 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 343 | mutex_lock(&tree->mutex); | 348 | spin_lock(&tree->lock); | 
| 344 | ret = __btrfs_remove_ordered_extent(inode, entry); | 349 | ret = __btrfs_remove_ordered_extent(inode, entry); | 
| 345 | mutex_unlock(&tree->mutex); | 350 | spin_unlock(&tree->lock); | 
| 346 | wake_up(&entry->wait); | 351 | wake_up(&entry->wait); | 
| 347 | 352 | ||
| 348 | return ret; | 353 | return ret; | 
| @@ -567,7 +572,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, | |||
| 567 | struct btrfs_ordered_extent *entry = NULL; | 572 | struct btrfs_ordered_extent *entry = NULL; | 
| 568 | 573 | ||
| 569 | tree = &BTRFS_I(inode)->ordered_tree; | 574 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 570 | mutex_lock(&tree->mutex); | 575 | spin_lock(&tree->lock); | 
| 571 | node = tree_search(tree, file_offset); | 576 | node = tree_search(tree, file_offset); | 
| 572 | if (!node) | 577 | if (!node) | 
| 573 | goto out; | 578 | goto out; | 
| @@ -578,7 +583,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, | |||
| 578 | if (entry) | 583 | if (entry) | 
| 579 | atomic_inc(&entry->refs); | 584 | atomic_inc(&entry->refs); | 
| 580 | out: | 585 | out: | 
| 581 | mutex_unlock(&tree->mutex); | 586 | spin_unlock(&tree->lock); | 
| 582 | return entry; | 587 | return entry; | 
| 583 | } | 588 | } | 
| 584 | 589 | ||
| @@ -594,7 +599,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset) | |||
| 594 | struct btrfs_ordered_extent *entry = NULL; | 599 | struct btrfs_ordered_extent *entry = NULL; | 
| 595 | 600 | ||
| 596 | tree = &BTRFS_I(inode)->ordered_tree; | 601 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 597 | mutex_lock(&tree->mutex); | 602 | spin_lock(&tree->lock); | 
| 598 | node = tree_search(tree, file_offset); | 603 | node = tree_search(tree, file_offset); | 
| 599 | if (!node) | 604 | if (!node) | 
| 600 | goto out; | 605 | goto out; | 
| @@ -602,7 +607,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset) | |||
| 602 | entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); | 607 | entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); | 
| 603 | atomic_inc(&entry->refs); | 608 | atomic_inc(&entry->refs); | 
| 604 | out: | 609 | out: | 
| 605 | mutex_unlock(&tree->mutex); | 610 | spin_unlock(&tree->lock); | 
| 606 | return entry; | 611 | return entry; | 
| 607 | } | 612 | } | 
| 608 | 613 | ||
| @@ -629,7 +634,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, | |||
| 629 | else | 634 | else | 
| 630 | offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); | 635 | offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); | 
| 631 | 636 | ||
| 632 | mutex_lock(&tree->mutex); | 637 | spin_lock(&tree->lock); | 
| 633 | disk_i_size = BTRFS_I(inode)->disk_i_size; | 638 | disk_i_size = BTRFS_I(inode)->disk_i_size; | 
| 634 | 639 | ||
| 635 | /* truncate file */ | 640 | /* truncate file */ | 
| @@ -735,7 +740,7 @@ out: | |||
| 735 | */ | 740 | */ | 
| 736 | if (ordered) | 741 | if (ordered) | 
| 737 | __btrfs_remove_ordered_extent(inode, ordered); | 742 | __btrfs_remove_ordered_extent(inode, ordered); | 
| 738 | mutex_unlock(&tree->mutex); | 743 | spin_unlock(&tree->lock); | 
| 739 | if (ordered) | 744 | if (ordered) | 
| 740 | wake_up(&ordered->wait); | 745 | wake_up(&ordered->wait); | 
| 741 | return ret; | 746 | return ret; | 
| @@ -762,7 +767,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | |||
| 762 | if (!ordered) | 767 | if (!ordered) | 
| 763 | return 1; | 768 | return 1; | 
| 764 | 769 | ||
| 765 | mutex_lock(&tree->mutex); | 770 | spin_lock(&tree->lock); | 
| 766 | list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { | 771 | list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { | 
| 767 | if (disk_bytenr >= ordered_sum->bytenr) { | 772 | if (disk_bytenr >= ordered_sum->bytenr) { | 
| 768 | num_sectors = ordered_sum->len / sectorsize; | 773 | num_sectors = ordered_sum->len / sectorsize; | 
| @@ -777,7 +782,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | |||
| 777 | } | 782 | } | 
| 778 | } | 783 | } | 
| 779 | out: | 784 | out: | 
| 780 | mutex_unlock(&tree->mutex); | 785 | spin_unlock(&tree->lock); | 
| 781 | btrfs_put_ordered_extent(ordered); | 786 | btrfs_put_ordered_extent(ordered); | 
| 782 | return ret; | 787 | return ret; | 
| 783 | } | 788 | } | 
