diff options
author | Chris Mason <chris.mason@fusionio.com> | 2013-02-06 12:42:24 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-02-06 12:42:24 -0500 |
commit | 7b1c567c84a6292c138db3bd1638e19e73e0e593 (patch) | |
tree | 9ab6983c6fa2cbb837e9b782d1020899e0d2d846 /btrfsck.c | |
parent | 5ffe6597e708d74c02d72d79ebb4a8fd2181e227 (diff) | |
parent | 2161e1b6f35d1c084fda49b479951219117c86e9 (diff) |
Merge branch 'for-chris' of git://repo.or.cz/btrfs-progs-unstable/devel into raid56
Conflicts:
ctree.h
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'btrfsck.c')
-rw-r--r-- | btrfsck.c | 59 |
1 files changed, 57 insertions, 2 deletions
@@ -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; |