diff options
| author | Patrick McHardy <kaber@trash.net> | 2010-04-20 10:02:01 -0400 | 
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2010-04-20 10:02:01 -0400 | 
| commit | 62910554656cdcd6b6f84a5154c4155aae4ca231 (patch) | |
| tree | dcf14004f6fd2ef7154362ff948bfeba0f3ea92d /fs/btrfs/ordered-data.c | |
| parent | 22265a5c3c103cf8c50be62e6c90d045eb649e6d (diff) | |
| parent | ab9304717f7624c41927f442e6b6d418b2d8b3e4 (diff) | |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
	Documentation/feature-removal-schedule.txt
	net/ipv6/netfilter/ip6t_REJECT.c
	net/netfilter/xt_limit.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
| -rw-r--r-- | fs/btrfs/ordered-data.c | 48 | 
1 files changed, 27 insertions, 21 deletions
| diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 5c2a9e78a949..a127c0ebb2dc 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. | 
| 17 | */ | 17 | */ | 
| 18 | 18 | ||
| 19 | #include <linux/gfp.h> | ||
| 20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> | 
| 21 | #include <linux/blkdev.h> | 20 | #include <linux/blkdev.h> | 
| 22 | #include <linux/writeback.h> | 21 | #include <linux/writeback.h> | 
| @@ -174,7 +173,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
| 174 | if (!entry) | 173 | if (!entry) | 
| 175 | return -ENOMEM; | 174 | return -ENOMEM; | 
| 176 | 175 | ||
| 177 | mutex_lock(&tree->mutex); | ||
| 178 | entry->file_offset = file_offset; | 176 | entry->file_offset = file_offset; | 
| 179 | entry->start = start; | 177 | entry->start = start; | 
| 180 | entry->len = len; | 178 | entry->len = len; | 
| @@ -190,16 +188,17 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
| 190 | INIT_LIST_HEAD(&entry->list); | 188 | INIT_LIST_HEAD(&entry->list); | 
| 191 | INIT_LIST_HEAD(&entry->root_extent_list); | 189 | INIT_LIST_HEAD(&entry->root_extent_list); | 
| 192 | 190 | ||
| 191 | spin_lock(&tree->lock); | ||
| 193 | node = tree_insert(&tree->tree, file_offset, | 192 | node = tree_insert(&tree->tree, file_offset, | 
| 194 | &entry->rb_node); | 193 | &entry->rb_node); | 
| 195 | BUG_ON(node); | 194 | BUG_ON(node); | 
| 195 | spin_unlock(&tree->lock); | ||
| 196 | 196 | ||
| 197 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 197 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 
| 198 | list_add_tail(&entry->root_extent_list, | 198 | list_add_tail(&entry->root_extent_list, | 
| 199 | &BTRFS_I(inode)->root->fs_info->ordered_extents); | 199 | &BTRFS_I(inode)->root->fs_info->ordered_extents); | 
| 200 | spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 200 | spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 
| 201 | 201 | ||
| 202 | mutex_unlock(&tree->mutex); | ||
| 203 | BUG_ON(node); | 202 | BUG_ON(node); | 
| 204 | return 0; | 203 | return 0; | 
| 205 | } | 204 | } | 
| @@ -216,9 +215,9 @@ int btrfs_add_ordered_sum(struct inode *inode, | |||
| 216 | struct btrfs_ordered_inode_tree *tree; | 215 | struct btrfs_ordered_inode_tree *tree; | 
| 217 | 216 | ||
| 218 | tree = &BTRFS_I(inode)->ordered_tree; | 217 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 219 | mutex_lock(&tree->mutex); | 218 | spin_lock(&tree->lock); | 
| 220 | list_add_tail(&sum->list, &entry->list); | 219 | list_add_tail(&sum->list, &entry->list); | 
| 221 | mutex_unlock(&tree->mutex); | 220 | spin_unlock(&tree->lock); | 
| 222 | return 0; | 221 | return 0; | 
| 223 | } | 222 | } | 
| 224 | 223 | ||
| @@ -232,15 +231,16 @@ int btrfs_add_ordered_sum(struct inode *inode, | |||
| 232 | * to make sure this function only returns 1 once for a given ordered extent. | 231 | * to make sure this function only returns 1 once for a given ordered extent. | 
| 233 | */ | 232 | */ | 
| 234 | int btrfs_dec_test_ordered_pending(struct inode *inode, | 233 | int btrfs_dec_test_ordered_pending(struct inode *inode, | 
| 234 | struct btrfs_ordered_extent **cached, | ||
| 235 | u64 file_offset, u64 io_size) | 235 | u64 file_offset, u64 io_size) | 
| 236 | { | 236 | { | 
| 237 | struct btrfs_ordered_inode_tree *tree; | 237 | struct btrfs_ordered_inode_tree *tree; | 
| 238 | struct rb_node *node; | 238 | struct rb_node *node; | 
| 239 | struct btrfs_ordered_extent *entry; | 239 | struct btrfs_ordered_extent *entry = NULL; | 
| 240 | int ret; | 240 | int ret; | 
| 241 | 241 | ||
| 242 | tree = &BTRFS_I(inode)->ordered_tree; | 242 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 243 | mutex_lock(&tree->mutex); | 243 | spin_lock(&tree->lock); | 
| 244 | node = tree_search(tree, file_offset); | 244 | node = tree_search(tree, file_offset); | 
| 245 | if (!node) { | 245 | if (!node) { | 
| 246 | ret = 1; | 246 | ret = 1; | 
| @@ -264,7 +264,11 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, | |||
| 264 | else | 264 | else | 
| 265 | ret = 1; | 265 | ret = 1; | 
| 266 | out: | 266 | out: | 
| 267 | mutex_unlock(&tree->mutex); | 267 | if (!ret && cached && entry) { | 
| 268 | *cached = entry; | ||
| 269 | atomic_inc(&entry->refs); | ||
| 270 | } | ||
| 271 | spin_unlock(&tree->lock); | ||
| 268 | return ret == 0; | 272 | return ret == 0; | 
| 269 | } | 273 | } | 
| 270 | 274 | ||
| @@ -291,13 +295,14 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) | |||
| 291 | 295 | ||
| 292 | /* | 296 | /* | 
| 293 | * remove an ordered extent from the tree. No references are dropped | 297 | * 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 | 298 | * and you must wake_up entry->wait. You must hold the tree lock | 
| 295 | * while you call this function. | 299 | * while you call this function. | 
| 296 | */ | 300 | */ | 
| 297 | static int __btrfs_remove_ordered_extent(struct inode *inode, | 301 | static int __btrfs_remove_ordered_extent(struct inode *inode, | 
| 298 | struct btrfs_ordered_extent *entry) | 302 | struct btrfs_ordered_extent *entry) | 
| 299 | { | 303 | { | 
| 300 | struct btrfs_ordered_inode_tree *tree; | 304 | struct btrfs_ordered_inode_tree *tree; | 
| 305 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 301 | struct rb_node *node; | 306 | struct rb_node *node; | 
| 302 | 307 | ||
| 303 | tree = &BTRFS_I(inode)->ordered_tree; | 308 | tree = &BTRFS_I(inode)->ordered_tree; | 
| @@ -307,12 +312,13 @@ static int __btrfs_remove_ordered_extent(struct inode *inode, | |||
| 307 | set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); | 312 | set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); | 
| 308 | 313 | ||
| 309 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 314 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 
| 315 | WARN_ON(!BTRFS_I(inode)->outstanding_extents); | ||
| 310 | BTRFS_I(inode)->outstanding_extents--; | 316 | BTRFS_I(inode)->outstanding_extents--; | 
| 311 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 317 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 
| 312 | btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root, | 318 | btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root, | 
| 313 | inode, 1); | 319 | inode, 1); | 
| 314 | 320 | ||
| 315 | spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 321 | spin_lock(&root->fs_info->ordered_extent_lock); | 
| 316 | list_del_init(&entry->root_extent_list); | 322 | list_del_init(&entry->root_extent_list); | 
| 317 | 323 | ||
| 318 | /* | 324 | /* | 
| @@ -324,7 +330,7 @@ static int __btrfs_remove_ordered_extent(struct inode *inode, | |||
| 324 | !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) { | 330 | !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) { | 
| 325 | list_del_init(&BTRFS_I(inode)->ordered_operations); | 331 | list_del_init(&BTRFS_I(inode)->ordered_operations); | 
| 326 | } | 332 | } | 
| 327 | spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); | 333 | spin_unlock(&root->fs_info->ordered_extent_lock); | 
| 328 | 334 | ||
| 329 | return 0; | 335 | return 0; | 
| 330 | } | 336 | } | 
| @@ -340,9 +346,9 @@ int btrfs_remove_ordered_extent(struct inode *inode, | |||
| 340 | int ret; | 346 | int ret; | 
| 341 | 347 | ||
| 342 | tree = &BTRFS_I(inode)->ordered_tree; | 348 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 343 | mutex_lock(&tree->mutex); | 349 | spin_lock(&tree->lock); | 
| 344 | ret = __btrfs_remove_ordered_extent(inode, entry); | 350 | ret = __btrfs_remove_ordered_extent(inode, entry); | 
| 345 | mutex_unlock(&tree->mutex); | 351 | spin_unlock(&tree->lock); | 
| 346 | wake_up(&entry->wait); | 352 | wake_up(&entry->wait); | 
| 347 | 353 | ||
| 348 | return ret; | 354 | return ret; | 
| @@ -567,7 +573,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, | |||
| 567 | struct btrfs_ordered_extent *entry = NULL; | 573 | struct btrfs_ordered_extent *entry = NULL; | 
| 568 | 574 | ||
| 569 | tree = &BTRFS_I(inode)->ordered_tree; | 575 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 570 | mutex_lock(&tree->mutex); | 576 | spin_lock(&tree->lock); | 
| 571 | node = tree_search(tree, file_offset); | 577 | node = tree_search(tree, file_offset); | 
| 572 | if (!node) | 578 | if (!node) | 
| 573 | goto out; | 579 | goto out; | 
| @@ -578,7 +584,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, | |||
| 578 | if (entry) | 584 | if (entry) | 
| 579 | atomic_inc(&entry->refs); | 585 | atomic_inc(&entry->refs); | 
| 580 | out: | 586 | out: | 
| 581 | mutex_unlock(&tree->mutex); | 587 | spin_unlock(&tree->lock); | 
| 582 | return entry; | 588 | return entry; | 
| 583 | } | 589 | } | 
| 584 | 590 | ||
| @@ -594,7 +600,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset) | |||
| 594 | struct btrfs_ordered_extent *entry = NULL; | 600 | struct btrfs_ordered_extent *entry = NULL; | 
| 595 | 601 | ||
| 596 | tree = &BTRFS_I(inode)->ordered_tree; | 602 | tree = &BTRFS_I(inode)->ordered_tree; | 
| 597 | mutex_lock(&tree->mutex); | 603 | spin_lock(&tree->lock); | 
| 598 | node = tree_search(tree, file_offset); | 604 | node = tree_search(tree, file_offset); | 
| 599 | if (!node) | 605 | if (!node) | 
| 600 | goto out; | 606 | goto out; | 
| @@ -602,7 +608,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset) | |||
| 602 | entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); | 608 | entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); | 
| 603 | atomic_inc(&entry->refs); | 609 | atomic_inc(&entry->refs); | 
| 604 | out: | 610 | out: | 
| 605 | mutex_unlock(&tree->mutex); | 611 | spin_unlock(&tree->lock); | 
| 606 | return entry; | 612 | return entry; | 
| 607 | } | 613 | } | 
| 608 | 614 | ||
| @@ -629,7 +635,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, | |||
| 629 | else | 635 | else | 
| 630 | offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); | 636 | offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); | 
| 631 | 637 | ||
| 632 | mutex_lock(&tree->mutex); | 638 | spin_lock(&tree->lock); | 
| 633 | disk_i_size = BTRFS_I(inode)->disk_i_size; | 639 | disk_i_size = BTRFS_I(inode)->disk_i_size; | 
| 634 | 640 | ||
| 635 | /* truncate file */ | 641 | /* truncate file */ | 
| @@ -735,7 +741,7 @@ out: | |||
| 735 | */ | 741 | */ | 
| 736 | if (ordered) | 742 | if (ordered) | 
| 737 | __btrfs_remove_ordered_extent(inode, ordered); | 743 | __btrfs_remove_ordered_extent(inode, ordered); | 
| 738 | mutex_unlock(&tree->mutex); | 744 | spin_unlock(&tree->lock); | 
| 739 | if (ordered) | 745 | if (ordered) | 
| 740 | wake_up(&ordered->wait); | 746 | wake_up(&ordered->wait); | 
| 741 | return ret; | 747 | return ret; | 
| @@ -762,7 +768,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | |||
| 762 | if (!ordered) | 768 | if (!ordered) | 
| 763 | return 1; | 769 | return 1; | 
| 764 | 770 | ||
| 765 | mutex_lock(&tree->mutex); | 771 | spin_lock(&tree->lock); | 
| 766 | list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { | 772 | list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { | 
| 767 | if (disk_bytenr >= ordered_sum->bytenr) { | 773 | if (disk_bytenr >= ordered_sum->bytenr) { | 
| 768 | num_sectors = ordered_sum->len / sectorsize; | 774 | num_sectors = ordered_sum->len / sectorsize; | 
| @@ -777,7 +783,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | |||
| 777 | } | 783 | } | 
| 778 | } | 784 | } | 
| 779 | out: | 785 | out: | 
| 780 | mutex_unlock(&tree->mutex); | 786 | spin_unlock(&tree->lock); | 
| 781 | btrfs_put_ordered_extent(ordered); | 787 | btrfs_put_ordered_extent(ordered); | 
| 782 | return ret; | 788 | return ret; | 
| 783 | } | 789 | } | 
