diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 6d9ec285644d..0a1bde268963 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -1980,6 +1980,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
1980 | int ret; | 1980 | int ret; |
1981 | struct btrfs_root *log = root->log_root; | 1981 | struct btrfs_root *log = root->log_root; |
1982 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; | 1982 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; |
1983 | u64 log_transid = 0; | ||
1983 | 1984 | ||
1984 | mutex_lock(&root->log_mutex); | 1985 | mutex_lock(&root->log_mutex); |
1985 | index1 = root->log_transid % 2; | 1986 | index1 = root->log_transid % 2; |
@@ -2018,6 +2019,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2018 | btrfs_set_root_node(&log->root_item, log->node); | 2019 | btrfs_set_root_node(&log->root_item, log->node); |
2019 | 2020 | ||
2020 | root->log_batch = 0; | 2021 | root->log_batch = 0; |
2022 | log_transid = root->log_transid; | ||
2021 | root->log_transid++; | 2023 | root->log_transid++; |
2022 | log->log_transid = root->log_transid; | 2024 | log->log_transid = root->log_transid; |
2023 | root->log_start_pid = 0; | 2025 | root->log_start_pid = 0; |
@@ -2095,6 +2097,11 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2095 | write_ctree_super(trans, root->fs_info->tree_root, 1); | 2097 | write_ctree_super(trans, root->fs_info->tree_root, 1); |
2096 | ret = 0; | 2098 | ret = 0; |
2097 | 2099 | ||
2100 | mutex_lock(&root->log_mutex); | ||
2101 | if (root->last_log_commit < log_transid) | ||
2102 | root->last_log_commit = log_transid; | ||
2103 | mutex_unlock(&root->log_mutex); | ||
2104 | |||
2098 | out_wake_log_root: | 2105 | out_wake_log_root: |
2099 | atomic_set(&log_root_tree->log_commit[index2], 0); | 2106 | atomic_set(&log_root_tree->log_commit[index2], 0); |
2100 | smp_mb(); | 2107 | smp_mb(); |
@@ -2862,6 +2869,21 @@ out: | |||
2862 | return ret; | 2869 | return ret; |
2863 | } | 2870 | } |
2864 | 2871 | ||
2872 | static int inode_in_log(struct btrfs_trans_handle *trans, | ||
2873 | struct inode *inode) | ||
2874 | { | ||
2875 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
2876 | int ret = 0; | ||
2877 | |||
2878 | mutex_lock(&root->log_mutex); | ||
2879 | if (BTRFS_I(inode)->logged_trans == trans->transid && | ||
2880 | BTRFS_I(inode)->last_sub_trans <= root->last_log_commit) | ||
2881 | ret = 1; | ||
2882 | mutex_unlock(&root->log_mutex); | ||
2883 | return ret; | ||
2884 | } | ||
2885 | |||
2886 | |||
2865 | /* | 2887 | /* |
2866 | * helper function around btrfs_log_inode to make sure newly created | 2888 | * helper function around btrfs_log_inode to make sure newly created |
2867 | * parent directories also end up in the log. A minimal inode and backref | 2889 | * parent directories also end up in the log. A minimal inode and backref |
@@ -2901,6 +2923,11 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
2901 | if (ret) | 2923 | if (ret) |
2902 | goto end_no_trans; | 2924 | goto end_no_trans; |
2903 | 2925 | ||
2926 | if (inode_in_log(trans, inode)) { | ||
2927 | ret = BTRFS_NO_LOG_SYNC; | ||
2928 | goto end_no_trans; | ||
2929 | } | ||
2930 | |||
2904 | start_log_trans(trans, root); | 2931 | start_log_trans(trans, root); |
2905 | 2932 | ||
2906 | ret = btrfs_log_inode(trans, root, inode, inode_only); | 2933 | ret = btrfs_log_inode(trans, root, inode, inode_only); |