@@ -35,6 +35,7 @@
#include "common/messages.h"
#include "common/string-utils.h"
#include "cmds/commands.h"
+#include "check/repair.h"
#define FIELD_BUF_LEN 80
@@ -33,6 +33,53 @@
int opt_check_repair = 0;
+/*
+ * adjust the pointers going up the tree, starting at level
+ * making sure the right key of each node is points to 'key'.
+ * This is used after shifting pointers to the left, so it stops
+ * fixing up pointers when a given leaf/node is not in slot 0 of the
+ * higher levels
+ */
+void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key,
+ int level)
+{
+ int i;
+ struct extent_buffer *t;
+
+ for (i = level; i < BTRFS_MAX_LEVEL; i++) {
+ int tslot = path->slots[i];
+ if (!path->nodes[i])
+ break;
+ t = path->nodes[i];
+ btrfs_set_node_key(t, key, tslot);
+ btrfs_mark_buffer_dirty(path->nodes[i]);
+ if (tslot != 0)
+ break;
+ }
+}
+
+/*
+ * update an item key without the safety checks. This is meant to be called by
+ * fsck only.
+ */
+void btrfs_set_item_key_unsafe(struct btrfs_root *root,
+ struct btrfs_path *path,
+ struct btrfs_key *new_key)
+{
+ struct btrfs_disk_key disk_key;
+ struct extent_buffer *eb;
+ int slot;
+
+ eb = path->nodes[0];
+ slot = path->slots[0];
+
+ btrfs_cpu_key_to_disk(&disk_key, new_key);
+ btrfs_set_item_key(eb, &disk_key, slot);
+ btrfs_mark_buffer_dirty(eb);
+ if (slot == 0)
+ btrfs_fixup_low_keys(path, &disk_key, 1);
+}
+
int btrfs_add_corrupt_extent_record(struct btrfs_fs_info *info,
struct btrfs_key *first_key,
u64 start, u64 len, int level)
@@ -45,4 +45,9 @@ int btrfs_mark_used_blocks(struct btrfs_fs_info *fs_info,
struct extent_io_tree *tree);
enum btrfs_tree_block_status btrfs_check_block_for_repair(struct extent_buffer *eb,
struct btrfs_key *first_key);
+void btrfs_set_item_key_unsafe(struct btrfs_root *root,
+ struct btrfs_path *path,
+ struct btrfs_key *new_key);
+void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key,
+ int level);
#endif
@@ -1321,8 +1321,8 @@ again:
* fixing up pointers when a given leaf/node is not in slot 0 of the
* higher levels
*/
-void btrfs_fixup_low_keys( struct btrfs_path *path, struct btrfs_disk_key *key,
- int level)
+static void fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key,
+ int level)
{
int i;
struct extent_buffer *t;
@@ -1368,29 +1368,7 @@ void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info,
btrfs_set_item_key(eb, &disk_key, slot);
btrfs_mark_buffer_dirty(eb);
if (slot == 0)
- btrfs_fixup_low_keys(path, &disk_key, 1);
-}
-
-/*
- * update an item key without the safety checks. This is meant to be called by
- * fsck only.
- */
-void btrfs_set_item_key_unsafe(struct btrfs_root *root,
- struct btrfs_path *path,
- struct btrfs_key *new_key)
-{
- struct btrfs_disk_key disk_key;
- struct extent_buffer *eb;
- int slot;
-
- eb = path->nodes[0];
- slot = path->slots[0];
-
- btrfs_cpu_key_to_disk(&disk_key, new_key);
- btrfs_set_item_key(eb, &disk_key, slot);
- btrfs_mark_buffer_dirty(eb);
- if (slot == 0)
- btrfs_fixup_low_keys(path, &disk_key, 1);
+ fixup_low_keys(path, &disk_key, 1);
}
/*
@@ -2056,7 +2034,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_mark_buffer_dirty(right);
btrfs_item_key(right, &disk_key, 0);
- btrfs_fixup_low_keys(path, &disk_key, 1);
+ fixup_low_keys(path, &disk_key, 1);
/* then fixup the leaf pointer in the path */
if (path->slots[0] < push_items) {
@@ -2286,7 +2264,7 @@ again:
path->nodes[0] = right;
path->slots[0] = 0;
if (path->slots[1] == 0)
- btrfs_fixup_low_keys(path, &disk_key, 1);
+ fixup_low_keys(path, &disk_key, 1);
}
btrfs_mark_buffer_dirty(right);
return ret;
@@ -2491,7 +2469,7 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end)
btrfs_set_disk_key_offset(&disk_key, offset + size_diff);
btrfs_set_item_key(leaf, &disk_key, slot);
if (slot == 0)
- btrfs_fixup_low_keys(path, &disk_key, 1);
+ fixup_low_keys(path, &disk_key, 1);
}
btrfs_set_item_size(leaf, slot, new_size);
@@ -2655,7 +2633,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
ret = 0;
if (slot == 0) {
btrfs_cpu_key_to_disk(&disk_key, cpu_key);
- btrfs_fixup_low_keys(path, &disk_key, 1);
+ fixup_low_keys(path, &disk_key, 1);
}
if (btrfs_leaf_free_space(leaf) < 0) {
@@ -2728,7 +2706,7 @@ int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path,
struct btrfs_disk_key disk_key;
btrfs_node_key(parent, &disk_key, 0);
- btrfs_fixup_low_keys(path, &disk_key, level + 1);
+ fixup_low_keys(path, &disk_key, level + 1);
}
btrfs_mark_buffer_dirty(parent);
return ret;
@@ -2826,7 +2804,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_disk_key disk_key;
btrfs_item_key(leaf, &disk_key, 0);
- btrfs_fixup_low_keys(path, &disk_key, 1);
+ fixup_low_keys(path, &disk_key, 1);
}
/* delete the leaf if it is mostly empty */
@@ -1051,14 +1051,9 @@ static inline int btrfs_next_item(struct btrfs_root *root,
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_leaf_free_space(struct extent_buffer *leaf);
-void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key,
- int level);
void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info,
struct btrfs_path *path,
const struct btrfs_key *new_key);
-void btrfs_set_item_key_unsafe(struct btrfs_root *root,
- struct btrfs_path *path,
- struct btrfs_key *new_key);
u16 btrfs_super_csum_size(const struct btrfs_super_block *s);
const char *btrfs_super_csum_name(u16 csum_type);
This helper exists for check and for btrfs-corrupt-block. Move the helper and the btrfs_fixup_low_keys helper into check/repair.[ch] so we can keep the kernel-shared sources close to the upstream kernel. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- btrfs-corrupt-block.c | 1 + check/repair.c | 47 +++++++++++++++++++++++++++++++++++++++++++ check/repair.h | 5 +++++ kernel-shared/ctree.c | 40 +++++++++--------------------------- kernel-shared/ctree.h | 5 ----- 5 files changed, 62 insertions(+), 36 deletions(-)