aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 65b4f864b0df..2e7d82ec5d18 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -528,6 +528,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
528 struct btrfs_trans_handle *trans; 528 struct btrfs_trans_handle *trans;
529 struct btrfs_ordered_extent *ordered_extent; 529 struct btrfs_ordered_extent *ordered_extent;
530 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 530 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
531 struct btrfs_file_extent_item *extent_item;
532 struct btrfs_path *path = NULL;
533 struct extent_buffer *leaf;
531 u64 alloc_hint = 0; 534 u64 alloc_hint = 0;
532 struct list_head list; 535 struct list_head list;
533 struct btrfs_key ins; 536 struct btrfs_key ins;
@@ -544,20 +547,15 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
544 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) 547 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags))
545 goto nocow; 548 goto nocow;
546 549
550 path = btrfs_alloc_path();
551 BUG_ON(!path);
552
547 lock_extent(io_tree, ordered_extent->file_offset, 553 lock_extent(io_tree, ordered_extent->file_offset,
548 ordered_extent->file_offset + ordered_extent->len - 1, 554 ordered_extent->file_offset + ordered_extent->len - 1,
549 GFP_NOFS); 555 GFP_NOFS);
550 556
551 INIT_LIST_HEAD(&list); 557 INIT_LIST_HEAD(&list);
552 558
553 ins.objectid = ordered_extent->start;
554 ins.offset = ordered_extent->len;
555 ins.type = BTRFS_EXTENT_ITEM_KEY;
556
557 ret = btrfs_alloc_reserved_extent(trans, root, root->root_key.objectid,
558 trans->transid, inode->i_ino,
559 ordered_extent->file_offset, &ins);
560 BUG_ON(ret);
561 mutex_lock(&BTRFS_I(inode)->extent_mutex); 559 mutex_lock(&BTRFS_I(inode)->extent_mutex);
562 560
563 ret = btrfs_drop_extents(trans, root, inode, 561 ret = btrfs_drop_extents(trans, root, inode,
@@ -566,18 +564,42 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
566 ordered_extent->len, 564 ordered_extent->len,
567 ordered_extent->file_offset, &alloc_hint); 565 ordered_extent->file_offset, &alloc_hint);
568 BUG_ON(ret); 566 BUG_ON(ret);
569 ret = btrfs_insert_file_extent(trans, root, inode->i_ino, 567
570 ordered_extent->file_offset, 568 ins.objectid = inode->i_ino;
571 ordered_extent->start, 569 ins.offset = ordered_extent->file_offset;
572 ordered_extent->len, 570 ins.type = BTRFS_EXTENT_DATA_KEY;
573 ordered_extent->len, 0); 571 ret = btrfs_insert_empty_item(trans, root, path, &ins,
572 sizeof(*extent_item));
574 BUG_ON(ret); 573 BUG_ON(ret);
574 leaf = path->nodes[0];
575 extent_item = btrfs_item_ptr(leaf, path->slots[0],
576 struct btrfs_file_extent_item);
577 btrfs_set_file_extent_generation(leaf, extent_item, trans->transid);
578 btrfs_set_file_extent_type(leaf, extent_item, BTRFS_FILE_EXTENT_REG);
579 btrfs_set_file_extent_disk_bytenr(leaf, extent_item,
580 ordered_extent->start);
581 btrfs_set_file_extent_disk_num_bytes(leaf, extent_item,
582 ordered_extent->len);
583 btrfs_set_file_extent_offset(leaf, extent_item, 0);
584 btrfs_set_file_extent_num_bytes(leaf, extent_item,
585 ordered_extent->len);
586 btrfs_mark_buffer_dirty(leaf);
575 587
576 btrfs_drop_extent_cache(inode, ordered_extent->file_offset, 588 btrfs_drop_extent_cache(inode, ordered_extent->file_offset,
577 ordered_extent->file_offset + 589 ordered_extent->file_offset +
578 ordered_extent->len - 1); 590 ordered_extent->len - 1);
579 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 591 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
580 592
593 ins.objectid = ordered_extent->start;
594 ins.offset = ordered_extent->len;
595 ins.type = BTRFS_EXTENT_ITEM_KEY;
596 ret = btrfs_alloc_reserved_extent(trans, root, leaf->start,
597 root->root_key.objectid,
598 trans->transid, inode->i_ino,
599 ordered_extent->file_offset, &ins);
600 BUG_ON(ret);
601 btrfs_release_path(root, path);
602
581 inode->i_blocks += ordered_extent->len >> 9; 603 inode->i_blocks += ordered_extent->len >> 9;
582 unlock_extent(io_tree, ordered_extent->file_offset, 604 unlock_extent(io_tree, ordered_extent->file_offset,
583 ordered_extent->file_offset + ordered_extent->len - 1, 605 ordered_extent->file_offset + ordered_extent->len - 1,
@@ -596,6 +618,8 @@ nocow:
596 btrfs_put_ordered_extent(ordered_extent); 618 btrfs_put_ordered_extent(ordered_extent);
597 619
598 btrfs_end_transaction(trans, root); 620 btrfs_end_transaction(trans, root);
621 if (path)
622 btrfs_free_path(path);
599 return 0; 623 return 0;
600} 624}
601 625
@@ -1433,10 +1457,7 @@ search_again:
1433 if (root->ref_cows) 1457 if (root->ref_cows)
1434 dec_i_blocks(inode, num_dec); 1458 dec_i_blocks(inode, num_dec);
1435 } 1459 }
1436 if (root->ref_cows) { 1460 root_gen = btrfs_header_generation(leaf);
1437 root_gen =
1438 btrfs_header_generation(leaf);
1439 }
1440 root_owner = btrfs_header_owner(leaf); 1461 root_owner = btrfs_header_owner(leaf);
1441 } 1462 }
1442 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { 1463 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
@@ -1477,7 +1498,7 @@ delete:
1477 if (found_extent) { 1498 if (found_extent) {
1478 ret = btrfs_free_extent(trans, root, extent_start, 1499 ret = btrfs_free_extent(trans, root, extent_start,
1479 extent_num_bytes, 1500 extent_num_bytes,
1480 root_owner, 1501 leaf->start, root_owner,
1481 root_gen, inode->i_ino, 1502 root_gen, inode->i_ino,
1482 found_key.offset, 0); 1503 found_key.offset, 0);
1483 BUG_ON(ret); 1504 BUG_ON(ret);