aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c106
1 files changed, 96 insertions, 10 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index d31a0c4f56be..e935035ac034 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -27,6 +27,7 @@
27#include "backref.h" 27#include "backref.h"
28#include "hash.h" 28#include "hash.h"
29#include "compression.h" 29#include "compression.h"
30#include "qgroup.h"
30 31
31/* magic values for the inode_only field in btrfs_log_inode: 32/* magic values for the inode_only field in btrfs_log_inode:
32 * 33 *
@@ -680,6 +681,21 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
680 ins.type = BTRFS_EXTENT_ITEM_KEY; 681 ins.type = BTRFS_EXTENT_ITEM_KEY;
681 offset = key->offset - btrfs_file_extent_offset(eb, item); 682 offset = key->offset - btrfs_file_extent_offset(eb, item);
682 683
684 /*
685 * Manually record dirty extent, as here we did a shallow
686 * file extent item copy and skip normal backref update,
687 * but modifying extent tree all by ourselves.
688 * So need to manually record dirty extent for qgroup,
689 * as the owner of the file extent changed from log tree
690 * (doesn't affect qgroup) to fs/file tree(affects qgroup)
691 */
692 ret = btrfs_qgroup_insert_dirty_extent(trans, root->fs_info,
693 btrfs_file_extent_disk_bytenr(eb, item),
694 btrfs_file_extent_disk_num_bytes(eb, item),
695 GFP_NOFS);
696 if (ret < 0)
697 goto out;
698
683 if (ins.objectid > 0) { 699 if (ins.objectid > 0) {
684 u64 csum_start; 700 u64 csum_start;
685 u64 csum_end; 701 u64 csum_end;
@@ -2807,7 +2823,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2807 */ 2823 */
2808 mutex_unlock(&root->log_mutex); 2824 mutex_unlock(&root->log_mutex);
2809 2825
2810 btrfs_init_log_ctx(&root_log_ctx); 2826 btrfs_init_log_ctx(&root_log_ctx, NULL);
2811 2827
2812 mutex_lock(&log_root_tree->log_mutex); 2828 mutex_lock(&log_root_tree->log_mutex);
2813 atomic_inc(&log_root_tree->log_batch); 2829 atomic_inc(&log_root_tree->log_batch);
@@ -4469,7 +4485,8 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
4469static int btrfs_check_ref_name_override(struct extent_buffer *eb, 4485static int btrfs_check_ref_name_override(struct extent_buffer *eb,
4470 const int slot, 4486 const int slot,
4471 const struct btrfs_key *key, 4487 const struct btrfs_key *key,
4472 struct inode *inode) 4488 struct inode *inode,
4489 u64 *other_ino)
4473{ 4490{
4474 int ret; 4491 int ret;
4475 struct btrfs_path *search_path; 4492 struct btrfs_path *search_path;
@@ -4528,7 +4545,16 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb,
4528 search_path, parent, 4545 search_path, parent,
4529 name, this_name_len, 0); 4546 name, this_name_len, 0);
4530 if (di && !IS_ERR(di)) { 4547 if (di && !IS_ERR(di)) {
4531 ret = 1; 4548 struct btrfs_key di_key;
4549
4550 btrfs_dir_item_key_to_cpu(search_path->nodes[0],
4551 di, &di_key);
4552 if (di_key.type == BTRFS_INODE_ITEM_KEY) {
4553 ret = 1;
4554 *other_ino = di_key.objectid;
4555 } else {
4556 ret = -EAGAIN;
4557 }
4532 goto out; 4558 goto out;
4533 } else if (IS_ERR(di)) { 4559 } else if (IS_ERR(di)) {
4534 ret = PTR_ERR(di); 4560 ret = PTR_ERR(di);
@@ -4722,16 +4748,72 @@ again:
4722 if ((min_key.type == BTRFS_INODE_REF_KEY || 4748 if ((min_key.type == BTRFS_INODE_REF_KEY ||
4723 min_key.type == BTRFS_INODE_EXTREF_KEY) && 4749 min_key.type == BTRFS_INODE_EXTREF_KEY) &&
4724 BTRFS_I(inode)->generation == trans->transid) { 4750 BTRFS_I(inode)->generation == trans->transid) {
4751 u64 other_ino = 0;
4752
4725 ret = btrfs_check_ref_name_override(path->nodes[0], 4753 ret = btrfs_check_ref_name_override(path->nodes[0],
4726 path->slots[0], 4754 path->slots[0],
4727 &min_key, inode); 4755 &min_key, inode,
4756 &other_ino);
4728 if (ret < 0) { 4757 if (ret < 0) {
4729 err = ret; 4758 err = ret;
4730 goto out_unlock; 4759 goto out_unlock;
4731 } else if (ret > 0) { 4760 } else if (ret > 0 && ctx &&
4732 err = 1; 4761 other_ino != btrfs_ino(ctx->inode)) {
4733 btrfs_set_log_full_commit(root->fs_info, trans); 4762 struct btrfs_key inode_key;
4734 goto out_unlock; 4763 struct inode *other_inode;
4764
4765 if (ins_nr > 0) {
4766 ins_nr++;
4767 } else {
4768 ins_nr = 1;
4769 ins_start_slot = path->slots[0];
4770 }
4771 ret = copy_items(trans, inode, dst_path, path,
4772 &last_extent, ins_start_slot,
4773 ins_nr, inode_only,
4774 logged_isize);
4775 if (ret < 0) {
4776 err = ret;
4777 goto out_unlock;
4778 }
4779 ins_nr = 0;
4780 btrfs_release_path(path);
4781 inode_key.objectid = other_ino;
4782 inode_key.type = BTRFS_INODE_ITEM_KEY;
4783 inode_key.offset = 0;
4784 other_inode = btrfs_iget(root->fs_info->sb,
4785 &inode_key, root,
4786 NULL);
4787 /*
4788 * If the other inode that had a conflicting dir
4789 * entry was deleted in the current transaction,
4790 * we don't need to do more work nor fallback to
4791 * a transaction commit.
4792 */
4793 if (IS_ERR(other_inode) &&
4794 PTR_ERR(other_inode) == -ENOENT) {
4795 goto next_key;
4796 } else if (IS_ERR(other_inode)) {
4797 err = PTR_ERR(other_inode);
4798 goto out_unlock;
4799 }
4800 /*
4801 * We are safe logging the other inode without
4802 * acquiring its i_mutex as long as we log with
4803 * the LOG_INODE_EXISTS mode. We're safe against
4804 * concurrent renames of the other inode as well
4805 * because during a rename we pin the log and
4806 * update the log with the new name before we
4807 * unpin it.
4808 */
4809 err = btrfs_log_inode(trans, root, other_inode,
4810 LOG_INODE_EXISTS,
4811 0, LLONG_MAX, ctx);
4812 iput(other_inode);
4813 if (err)
4814 goto out_unlock;
4815 else
4816 goto next_key;
4735 } 4817 }
4736 } 4818 }
4737 4819
@@ -4799,7 +4881,7 @@ next_slot:
4799 ins_nr = 0; 4881 ins_nr = 0;
4800 } 4882 }
4801 btrfs_release_path(path); 4883 btrfs_release_path(path);
4802 4884next_key:
4803 if (min_key.offset < (u64)-1) { 4885 if (min_key.offset < (u64)-1) {
4804 min_key.offset++; 4886 min_key.offset++;
4805 } else if (min_key.type < max_key.type) { 4887 } else if (min_key.type < max_key.type) {
@@ -4993,8 +5075,12 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
4993 if (!parent || d_really_is_negative(parent) || sb != parent->d_sb) 5075 if (!parent || d_really_is_negative(parent) || sb != parent->d_sb)
4994 break; 5076 break;
4995 5077
4996 if (IS_ROOT(parent)) 5078 if (IS_ROOT(parent)) {
5079 inode = d_inode(parent);
5080 if (btrfs_must_commit_transaction(trans, inode))
5081 ret = 1;
4997 break; 5082 break;
5083 }
4998 5084
4999 parent = dget_parent(parent); 5085 parent = dget_parent(parent);
5000 dput(old_parent); 5086 dput(old_parent);