diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 741666a7676a..31da0002e78b 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -1977,10 +1977,11 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
1977 | { | 1977 | { |
1978 | int index1; | 1978 | int index1; |
1979 | int index2; | 1979 | int index2; |
1980 | int mark; | ||
1980 | int ret; | 1981 | int ret; |
1981 | struct btrfs_root *log = root->log_root; | 1982 | struct btrfs_root *log = root->log_root; |
1982 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; | 1983 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; |
1983 | u64 log_transid = 0; | 1984 | unsigned long log_transid = 0; |
1984 | 1985 | ||
1985 | mutex_lock(&root->log_mutex); | 1986 | mutex_lock(&root->log_mutex); |
1986 | index1 = root->log_transid % 2; | 1987 | index1 = root->log_transid % 2; |
@@ -2014,24 +2015,29 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2014 | goto out; | 2015 | goto out; |
2015 | } | 2016 | } |
2016 | 2017 | ||
2018 | log_transid = root->log_transid; | ||
2019 | if (log_transid % 2 == 0) | ||
2020 | mark = EXTENT_DIRTY; | ||
2021 | else | ||
2022 | mark = EXTENT_NEW; | ||
2023 | |||
2017 | /* we start IO on all the marked extents here, but we don't actually | 2024 | /* we start IO on all the marked extents here, but we don't actually |
2018 | * wait for them until later. | 2025 | * wait for them until later. |
2019 | */ | 2026 | */ |
2020 | ret = btrfs_write_marked_extents(log, &log->dirty_log_pages); | 2027 | ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark); |
2021 | BUG_ON(ret); | 2028 | BUG_ON(ret); |
2022 | 2029 | ||
2023 | btrfs_set_root_node(&log->root_item, log->node); | 2030 | btrfs_set_root_node(&log->root_item, log->node); |
2024 | 2031 | ||
2025 | root->log_batch = 0; | 2032 | root->log_batch = 0; |
2026 | log_transid = root->log_transid; | ||
2027 | root->log_transid++; | 2033 | root->log_transid++; |
2028 | log->log_transid = root->log_transid; | 2034 | log->log_transid = root->log_transid; |
2029 | root->log_start_pid = 0; | 2035 | root->log_start_pid = 0; |
2030 | smp_mb(); | 2036 | smp_mb(); |
2031 | /* | 2037 | /* |
2032 | * log tree has been flushed to disk, new modifications of | 2038 | * IO has been started, blocks of the log tree have WRITTEN flag set |
2033 | * the log will be written to new positions. so it's safe to | 2039 | * in their headers. new modifications of the log will be written to |
2034 | * allow log writers to go in. | 2040 | * new positions. so it's safe to allow log writers to go in. |
2035 | */ | 2041 | */ |
2036 | mutex_unlock(&root->log_mutex); | 2042 | mutex_unlock(&root->log_mutex); |
2037 | 2043 | ||
@@ -2052,7 +2058,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2052 | 2058 | ||
2053 | index2 = log_root_tree->log_transid % 2; | 2059 | index2 = log_root_tree->log_transid % 2; |
2054 | if (atomic_read(&log_root_tree->log_commit[index2])) { | 2060 | if (atomic_read(&log_root_tree->log_commit[index2])) { |
2055 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | 2061 | btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); |
2056 | wait_log_commit(trans, log_root_tree, | 2062 | wait_log_commit(trans, log_root_tree, |
2057 | log_root_tree->log_transid); | 2063 | log_root_tree->log_transid); |
2058 | mutex_unlock(&log_root_tree->log_mutex); | 2064 | mutex_unlock(&log_root_tree->log_mutex); |
@@ -2072,16 +2078,17 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2072 | * check the full commit flag again | 2078 | * check the full commit flag again |
2073 | */ | 2079 | */ |
2074 | if (root->fs_info->last_trans_log_full_commit == trans->transid) { | 2080 | if (root->fs_info->last_trans_log_full_commit == trans->transid) { |
2075 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | 2081 | btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); |
2076 | mutex_unlock(&log_root_tree->log_mutex); | 2082 | mutex_unlock(&log_root_tree->log_mutex); |
2077 | ret = -EAGAIN; | 2083 | ret = -EAGAIN; |
2078 | goto out_wake_log_root; | 2084 | goto out_wake_log_root; |
2079 | } | 2085 | } |
2080 | 2086 | ||
2081 | ret = btrfs_write_and_wait_marked_extents(log_root_tree, | 2087 | ret = btrfs_write_and_wait_marked_extents(log_root_tree, |
2082 | &log_root_tree->dirty_log_pages); | 2088 | &log_root_tree->dirty_log_pages, |
2089 | EXTENT_DIRTY | EXTENT_NEW); | ||
2083 | BUG_ON(ret); | 2090 | BUG_ON(ret); |
2084 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | 2091 | btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); |
2085 | 2092 | ||
2086 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, | 2093 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, |
2087 | log_root_tree->node->start); | 2094 | log_root_tree->node->start); |
@@ -2147,12 +2154,12 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root) | |||
2147 | 2154 | ||
2148 | while (1) { | 2155 | while (1) { |
2149 | ret = find_first_extent_bit(&log->dirty_log_pages, | 2156 | ret = find_first_extent_bit(&log->dirty_log_pages, |
2150 | 0, &start, &end, EXTENT_DIRTY); | 2157 | 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW); |
2151 | if (ret) | 2158 | if (ret) |
2152 | break; | 2159 | break; |
2153 | 2160 | ||
2154 | clear_extent_dirty(&log->dirty_log_pages, | 2161 | clear_extent_bits(&log->dirty_log_pages, start, end, |
2155 | start, end, GFP_NOFS); | 2162 | EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); |
2156 | } | 2163 | } |
2157 | 2164 | ||
2158 | if (log->log_transid > 0) { | 2165 | if (log->log_transid > 0) { |