|
@@ -29,6 +29,7 @@
|
|
|
#include "hash.h"
|
|
|
#include "compression.h"
|
|
|
#include "qgroup.h"
|
|
|
+#include "inode-map.h"
|
|
|
|
|
|
/* magic values for the inode_only field in btrfs_log_inode:
|
|
|
*
|
|
@@ -2472,6 +2473,9 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
|
|
|
clean_tree_block(fs_info, next);
|
|
|
btrfs_wait_tree_block_writeback(next);
|
|
|
btrfs_tree_unlock(next);
|
|
|
+ } else {
|
|
|
+ if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
|
|
|
+ clear_extent_buffer_dirty(next);
|
|
|
}
|
|
|
|
|
|
WARN_ON(root_owner !=
|
|
@@ -2552,6 +2556,9 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
|
|
|
clean_tree_block(fs_info, next);
|
|
|
btrfs_wait_tree_block_writeback(next);
|
|
|
btrfs_tree_unlock(next);
|
|
|
+ } else {
|
|
|
+ if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
|
|
|
+ clear_extent_buffer_dirty(next);
|
|
|
}
|
|
|
|
|
|
WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID);
|
|
@@ -2630,6 +2637,9 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
|
|
|
clean_tree_block(fs_info, next);
|
|
|
btrfs_wait_tree_block_writeback(next);
|
|
|
btrfs_tree_unlock(next);
|
|
|
+ } else {
|
|
|
+ if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
|
|
|
+ clear_extent_buffer_dirty(next);
|
|
|
}
|
|
|
|
|
|
WARN_ON(log->root_key.objectid !=
|
|
@@ -3018,13 +3028,14 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
while (1) {
|
|
|
ret = find_first_extent_bit(&log->dirty_log_pages,
|
|
|
- 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW,
|
|
|
+ 0, &start, &end,
|
|
|
+ EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT,
|
|
|
NULL);
|
|
|
if (ret)
|
|
|
break;
|
|
|
|
|
|
clear_extent_bits(&log->dirty_log_pages, start, end,
|
|
|
- EXTENT_DIRTY | EXTENT_NEW);
|
|
|
+ EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -5677,6 +5688,23 @@ again:
|
|
|
path);
|
|
|
}
|
|
|
|
|
|
+ if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
|
|
|
+ struct btrfs_root *root = wc.replay_dest;
|
|
|
+
|
|
|
+ btrfs_release_path(path);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We have just replayed everything, and the highest
|
|
|
+ * objectid of fs roots probably has changed in case
|
|
|
+ * some inode_item's got replayed.
|
|
|
+ *
|
|
|
+ * root->objectid_mutex is not acquired as log replay
|
|
|
+ * could only happen during mount.
|
|
|
+ */
|
|
|
+ ret = btrfs_find_highest_objectid(root,
|
|
|
+ &root->highest_objectid);
|
|
|
+ }
|
|
|
+
|
|
|
key.offset = found_key.offset - 1;
|
|
|
wc.replay_dest->log_root = NULL;
|
|
|
free_extent_buffer(log->node);
|