diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 57 |
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); |