diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 60852ada658e..3da12a4d913d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -485,7 +485,7 @@ int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end) | |||
485 | fixup = kzalloc(sizeof(*fixup), GFP_NOFS); | 485 | fixup = kzalloc(sizeof(*fixup), GFP_NOFS); |
486 | if (!fixup) | 486 | if (!fixup) |
487 | return -EAGAIN; | 487 | return -EAGAIN; |
488 | printk("queueing worker to fixup page %lu %Lu\n", inode->i_ino, page_offset(page)); | 488 | |
489 | SetPageChecked(page); | 489 | SetPageChecked(page); |
490 | page_cache_get(page); | 490 | page_cache_get(page); |
491 | fixup->work.func = btrfs_writepage_fixup_worker; | 491 | fixup->work.func = btrfs_writepage_fixup_worker; |
@@ -502,11 +502,13 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
502 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 502 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
503 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 503 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
504 | struct extent_map *em; | 504 | struct extent_map *em; |
505 | struct extent_map *em_orig; | ||
505 | u64 alloc_hint = 0; | 506 | u64 alloc_hint = 0; |
506 | u64 clear_start; | 507 | u64 clear_start; |
507 | u64 clear_end; | 508 | u64 clear_end; |
508 | struct list_head list; | 509 | struct list_head list; |
509 | struct btrfs_key ins; | 510 | struct btrfs_key ins; |
511 | struct rb_node *rb; | ||
510 | int ret; | 512 | int ret; |
511 | 513 | ||
512 | ret = btrfs_dec_test_ordered_pending(inode, start, end - start + 1); | 514 | ret = btrfs_dec_test_ordered_pending(inode, start, end - start + 1); |
@@ -535,6 +537,22 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
535 | 537 | ||
536 | mutex_lock(&BTRFS_I(inode)->extent_mutex); | 538 | mutex_lock(&BTRFS_I(inode)->extent_mutex); |
537 | 539 | ||
540 | spin_lock(&em_tree->lock); | ||
541 | clear_start = ordered_extent->file_offset; | ||
542 | clear_end = ordered_extent->file_offset + ordered_extent->len; | ||
543 | em = lookup_extent_mapping(em_tree, clear_start, | ||
544 | ordered_extent->len); | ||
545 | em_orig = em; | ||
546 | while(em && clear_start < extent_map_end(em) && clear_end > em->start) { | ||
547 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); | ||
548 | rb = rb_next(&em->rb_node); | ||
549 | if (!rb) | ||
550 | break; | ||
551 | em = rb_entry(rb, struct extent_map, rb_node); | ||
552 | } | ||
553 | free_extent_map(em_orig); | ||
554 | spin_unlock(&em_tree->lock); | ||
555 | |||
538 | ret = btrfs_drop_extents(trans, root, inode, | 556 | ret = btrfs_drop_extents(trans, root, inode, |
539 | ordered_extent->file_offset, | 557 | ordered_extent->file_offset, |
540 | ordered_extent->file_offset + | 558 | ordered_extent->file_offset + |
@@ -548,22 +566,6 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
548 | ordered_extent->len, 0); | 566 | ordered_extent->len, 0); |
549 | BUG_ON(ret); | 567 | BUG_ON(ret); |
550 | 568 | ||
551 | spin_lock(&em_tree->lock); | ||
552 | clear_start = ordered_extent->file_offset; | ||
553 | clear_end = ordered_extent->file_offset + ordered_extent->len; | ||
554 | while(clear_start < clear_end) { | ||
555 | em = lookup_extent_mapping(em_tree, clear_start, | ||
556 | clear_end - clear_start); | ||
557 | if (em) { | ||
558 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); | ||
559 | clear_start = em->start + em->len; | ||
560 | free_extent_map(em); | ||
561 | } else { | ||
562 | break; | ||
563 | } | ||
564 | } | ||
565 | spin_unlock(&em_tree->lock); | ||
566 | |||
567 | btrfs_drop_extent_cache(inode, ordered_extent->file_offset, | 569 | btrfs_drop_extent_cache(inode, ordered_extent->file_offset, |
568 | ordered_extent->file_offset + | 570 | ordered_extent->file_offset + |
569 | ordered_extent->len - 1); | 571 | ordered_extent->len - 1); |
@@ -2318,7 +2320,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
2318 | u64 extent_end = 0; | 2320 | u64 extent_end = 0; |
2319 | u64 objectid = inode->i_ino; | 2321 | u64 objectid = inode->i_ino; |
2320 | u32 found_type; | 2322 | u32 found_type; |
2321 | struct btrfs_path *path; | 2323 | struct btrfs_path *path = NULL; |
2322 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2324 | struct btrfs_root *root = BTRFS_I(inode)->root; |
2323 | struct btrfs_file_extent_item *item; | 2325 | struct btrfs_file_extent_item *item; |
2324 | struct extent_buffer *leaf; | 2326 | struct extent_buffer *leaf; |
@@ -2328,9 +2330,6 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
2328 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 2330 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
2329 | struct btrfs_trans_handle *trans = NULL; | 2331 | struct btrfs_trans_handle *trans = NULL; |
2330 | 2332 | ||
2331 | path = btrfs_alloc_path(); | ||
2332 | BUG_ON(!path); | ||
2333 | |||
2334 | again: | 2333 | again: |
2335 | spin_lock(&em_tree->lock); | 2334 | spin_lock(&em_tree->lock); |
2336 | em = lookup_extent_mapping(em_tree, start, len); | 2335 | em = lookup_extent_mapping(em_tree, start, len); |
@@ -2354,6 +2353,12 @@ again: | |||
2354 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 2353 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
2355 | em->start = EXTENT_MAP_HOLE; | 2354 | em->start = EXTENT_MAP_HOLE; |
2356 | em->len = (u64)-1; | 2355 | em->len = (u64)-1; |
2356 | |||
2357 | if (!path) { | ||
2358 | path = btrfs_alloc_path(); | ||
2359 | BUG_ON(!path); | ||
2360 | } | ||
2361 | |||
2357 | ret = btrfs_lookup_file_extent(trans, root, path, | 2362 | ret = btrfs_lookup_file_extent(trans, root, path, |
2358 | objectid, start, trans != NULL); | 2363 | objectid, start, trans != NULL); |
2359 | if (ret < 0) { | 2364 | if (ret < 0) { |
@@ -2530,7 +2535,8 @@ insert: | |||
2530 | } | 2535 | } |
2531 | spin_unlock(&em_tree->lock); | 2536 | spin_unlock(&em_tree->lock); |
2532 | out: | 2537 | out: |
2533 | btrfs_free_path(path); | 2538 | if (path) |
2539 | btrfs_free_path(path); | ||
2534 | if (trans) { | 2540 | if (trans) { |
2535 | ret = btrfs_end_transaction(trans, root); | 2541 | ret = btrfs_end_transaction(trans, root); |
2536 | if (!err) { | 2542 | if (!err) { |
@@ -2643,8 +2649,8 @@ static int btrfs_writepage(struct page *page, struct writeback_control *wbc) | |||
2643 | return extent_write_full_page(tree, page, btrfs_get_extent, wbc); | 2649 | return extent_write_full_page(tree, page, btrfs_get_extent, wbc); |
2644 | } | 2650 | } |
2645 | 2651 | ||
2646 | static int btrfs_writepages(struct address_space *mapping, | 2652 | int btrfs_writepages(struct address_space *mapping, |
2647 | struct writeback_control *wbc) | 2653 | struct writeback_control *wbc) |
2648 | { | 2654 | { |
2649 | struct extent_io_tree *tree; | 2655 | struct extent_io_tree *tree; |
2650 | tree = &BTRFS_I(mapping->host)->io_tree; | 2656 | tree = &BTRFS_I(mapping->host)->io_tree; |