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 | } |