summaryrefslogtreecommitdiff
path: root/btrfsck.c
diff options
context:
space:
mode:
Diffstat (limited to 'btrfsck.c')
-rw-r--r--btrfsck.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/btrfsck.c b/btrfsck.c
index a8510085..dd0f18bf 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -22,8 +22,11 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <getopt.h>
+#include <uuid/uuid.h>
#include "kerncompat.h"
#include "ctree.h"
#include "volumes.h"
@@ -96,6 +99,7 @@ struct inode_backref {
unsigned int found_inode_ref:1;
unsigned int filetype:8;
int errors;
+ unsigned int ref_type;
u64 dir;
u64 index;
u16 namelen;
@@ -469,12 +473,14 @@ static int add_inode_backref(struct cache_tree *inode_cache,
backref->filetype = filetype;
backref->found_dir_item = 1;
- } else if (itemtype == BTRFS_INODE_REF_KEY) {
+ } else if ((itemtype == BTRFS_INODE_REF_KEY) ||
+ (itemtype == BTRFS_INODE_EXTREF_KEY)) {
if (backref->found_inode_ref)
backref->errors |= REF_ERR_DUP_INODE_REF;
if (backref->found_dir_index && backref->index != index)
backref->errors |= REF_ERR_INDEX_UNMATCH;
+ backref->ref_type = itemtype;
backref->index = index;
backref->found_inode_ref = 1;
} else {
@@ -510,7 +516,7 @@ static int merge_inode_recs(struct inode_record *src, struct inode_record *dst,
add_inode_backref(dst_cache, dst->ino,
backref->dir, backref->index,
backref->name, backref->namelen, 0,
- BTRFS_INODE_REF_KEY, backref->errors);
+ backref->ref_type, backref->errors);
}
}
@@ -914,6 +920,49 @@ static int process_inode_ref(struct extent_buffer *eb,
return 0;
}
+static int process_inode_extref(struct extent_buffer *eb,
+ int slot, struct btrfs_key *key,
+ struct shared_node *active_node)
+{
+ u32 total;
+ u32 cur = 0;
+ u32 len;
+ u32 name_len;
+ u64 index;
+ u64 parent;
+ int error;
+ struct cache_tree *inode_cache;
+ struct btrfs_inode_extref *extref;
+ char namebuf[BTRFS_NAME_LEN];
+
+ inode_cache = &active_node->inode_cache;
+
+ extref = btrfs_item_ptr(eb, slot, struct btrfs_inode_extref);
+ total = btrfs_item_size_nr(eb, slot);
+ while (cur < total) {
+ name_len = btrfs_inode_extref_name_len(eb, extref);
+ index = btrfs_inode_extref_index(eb, extref);
+ parent = btrfs_inode_extref_parent(eb, extref);
+ if (name_len <= BTRFS_NAME_LEN) {
+ len = name_len;
+ error = 0;
+ } else {
+ len = BTRFS_NAME_LEN;
+ error = REF_ERR_NAME_TOO_LONG;
+ }
+ read_extent_buffer(eb, namebuf,
+ (unsigned long)(extref + 1), len);
+ add_inode_backref(inode_cache, key->objectid, parent,
+ index, namebuf, len, 0, key->type, error);
+
+ len = sizeof(*extref) + name_len;
+ extref = (struct btrfs_inode_extref *)((char *)extref + len);
+ cur += len;
+ }
+ return 0;
+
+}
+
static u64 count_csum_range(struct btrfs_root *root, u64 start, u64 len)
{
struct btrfs_key key;
@@ -1100,6 +1149,9 @@ static int process_one_leaf(struct btrfs_root *root, struct extent_buffer *eb,
case BTRFS_INODE_REF_KEY:
ret = process_inode_ref(eb, i, &key, active_node);
break;
+ case BTRFS_INODE_EXTREF_KEY:
+ ret = process_inode_extref(eb, i, &key, active_node);
+ break;
case BTRFS_INODE_ITEM_KEY:
ret = process_inode_item(eb, i, &key, active_node);
break;
@@ -3492,6 +3544,7 @@ int main(int ac, char **av)
struct btrfs_fs_info *info;
struct btrfs_trans_handle *trans = NULL;
u64 bytenr = 0;
+ char uuidbuf[37];
int ret;
int num;
int repair = 0;
@@ -3544,6 +3597,8 @@ int main(int ac, char **av)
}
info = open_ctree_fs_info(av[optind], bytenr, rw, 1);
+ uuid_unparse(info->super_copy.fsid, uuidbuf);
+ printf("Checking filesystem on %s\nUUID: %s\n", av[optind], uuidbuf);
if (info == NULL)
return 1;