btrfs-progs: Add new option for specify chunk root bytenr
Add new btrfsck option, '--chunk-root', to specify chunk root bytenr. And allow open_ctree_fs_info() function accept chunk_root_bytenr to override the bytenr in superblock. This will be mainly used when chunk tree corruption. Signed-off-by: Lu Fengqi <lufq.fnst@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
da3ae9c69a
commit
05640939ea
8 changed files with 38 additions and 15 deletions
|
@ -190,7 +190,7 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
fs_info = open_ctree_fs_info(argv[optind], 0, 0,
|
||||
fs_info = open_ctree_fs_info(argv[optind], 0, 0, 0,
|
||||
OPEN_CTREE_CHUNK_ROOT_ONLY |
|
||||
OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR);
|
||||
if (!fs_info) {
|
||||
|
|
|
@ -2471,7 +2471,7 @@ static int restore_metadump(const char *input, FILE *out, int old_restore,
|
|||
/* NOTE: open with write mode */
|
||||
if (fixup_offset) {
|
||||
BUG_ON(!target);
|
||||
info = open_ctree_fs_info(target, 0, 0,
|
||||
info = open_ctree_fs_info(target, 0, 0, 0,
|
||||
OPEN_CTREE_WRITES |
|
||||
OPEN_CTREE_RESTORE |
|
||||
OPEN_CTREE_PARTIAL);
|
||||
|
@ -2817,7 +2817,7 @@ int main(int argc, char *argv[])
|
|||
u64 total_devs;
|
||||
int i;
|
||||
|
||||
info = open_ctree_fs_info(target, 0, 0,
|
||||
info = open_ctree_fs_info(target, 0, 0, 0,
|
||||
OPEN_CTREE_PARTIAL |
|
||||
OPEN_CTREE_RESTORE);
|
||||
if (!info) {
|
||||
|
|
10
cmds-check.c
10
cmds-check.c
|
@ -9480,6 +9480,7 @@ const char * const cmd_check_usage[] = {
|
|||
"-E|--subvol-extents <subvolid>",
|
||||
" print subvolume extents and sharing state",
|
||||
"-r|--tree-root <bytenr> use the given bytenr for the tree root",
|
||||
"-c|--chunk-root <bytenr> use the given bytenr for the chunk tree root",
|
||||
"-p|--progress indicate progress",
|
||||
NULL
|
||||
};
|
||||
|
@ -9492,6 +9493,7 @@ int cmd_check(int argc, char **argv)
|
|||
u64 bytenr = 0;
|
||||
u64 subvolid = 0;
|
||||
u64 tree_root_bytenr = 0;
|
||||
u64 chunk_root_bytenr = 0;
|
||||
char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
|
||||
int ret;
|
||||
u64 num;
|
||||
|
@ -9515,11 +9517,12 @@ int cmd_check(int argc, char **argv)
|
|||
{ "subvol-extents", required_argument, NULL, 'E' },
|
||||
{ "qgroup-report", no_argument, NULL, 'Q' },
|
||||
{ "tree-root", required_argument, NULL, 'r' },
|
||||
{ "chunk-root", required_argument, NULL, 'c' },
|
||||
{ "progress", no_argument, NULL, 'p' },
|
||||
{ NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "as:br:p", long_options, NULL);
|
||||
c = getopt_long(argc, argv, "as:br:pc:", long_options, NULL);
|
||||
if (c < 0)
|
||||
break;
|
||||
switch(c) {
|
||||
|
@ -9548,6 +9551,9 @@ int cmd_check(int argc, char **argv)
|
|||
case 'r':
|
||||
tree_root_bytenr = arg_strtou64(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
chunk_root_bytenr = arg_strtou64(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
ctx.progress_enabled = true;
|
||||
break;
|
||||
|
@ -9611,7 +9617,7 @@ int cmd_check(int argc, char **argv)
|
|||
ctree_flags |= OPEN_CTREE_PARTIAL;
|
||||
|
||||
info = open_ctree_fs_info(argv[optind], bytenr, tree_root_bytenr,
|
||||
ctree_flags);
|
||||
chunk_root_bytenr, ctree_flags);
|
||||
if (!info) {
|
||||
fprintf(stderr, "Couldn't open file system\n");
|
||||
ret = -EIO;
|
||||
|
|
|
@ -720,7 +720,7 @@ static int map_seed_devices(struct list_head *all_uuids)
|
|||
/*
|
||||
* open_ctree_* detects seed/sprout mapping
|
||||
*/
|
||||
fs_info = open_ctree_fs_info(device->name, 0, 0,
|
||||
fs_info = open_ctree_fs_info(device->name, 0, 0, 0,
|
||||
OPEN_CTREE_PARTIAL);
|
||||
if (!fs_info)
|
||||
continue;
|
||||
|
|
|
@ -194,7 +194,7 @@ int cmd_inspect_dump_tree(int argc, char **argv)
|
|||
goto out;
|
||||
}
|
||||
|
||||
info = open_ctree_fs_info(argv[optind], 0, 0, OPEN_CTREE_PARTIAL);
|
||||
info = open_ctree_fs_info(argv[optind], 0, 0, 0, OPEN_CTREE_PARTIAL);
|
||||
if (!info) {
|
||||
error("unable to open %s", argv[optind]);
|
||||
goto out;
|
||||
|
|
|
@ -1262,7 +1262,7 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location,
|
|||
|
||||
for (i = super_mirror; i < BTRFS_SUPER_MIRROR_MAX; i++) {
|
||||
bytenr = btrfs_sb_offset(i);
|
||||
fs_info = open_ctree_fs_info(dev, bytenr, root_location,
|
||||
fs_info = open_ctree_fs_info(dev, bytenr, root_location, 0,
|
||||
OPEN_CTREE_PARTIAL);
|
||||
if (fs_info)
|
||||
break;
|
||||
|
|
27
disk-io.c
27
disk-io.c
|
@ -1146,7 +1146,8 @@ int btrfs_scan_fs_devices(int fd, const char *path,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info)
|
||||
int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info,
|
||||
u64 chunk_root_bytenr)
|
||||
{
|
||||
struct btrfs_super_block *sb = fs_info->super_copy;
|
||||
u32 sectorsize;
|
||||
|
@ -1173,8 +1174,20 @@ int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info)
|
|||
btrfs_super_chunk_root_level(sb));
|
||||
generation = btrfs_super_chunk_root_generation(sb);
|
||||
|
||||
if (chunk_root_bytenr && !IS_ALIGNED(chunk_root_bytenr,
|
||||
btrfs_super_sectorsize(sb))) {
|
||||
warning("chunk_root_bytenr %llu is unaligned to %u, ignore it",
|
||||
chunk_root_bytenr, btrfs_super_sectorsize(sb));
|
||||
chunk_root_bytenr = 0;
|
||||
}
|
||||
|
||||
if (!chunk_root_bytenr)
|
||||
chunk_root_bytenr = btrfs_super_chunk_root(sb);
|
||||
else
|
||||
generation = 0;
|
||||
|
||||
fs_info->chunk_root->node = read_tree_block(fs_info->chunk_root,
|
||||
btrfs_super_chunk_root(sb),
|
||||
chunk_root_bytenr,
|
||||
blocksize, generation);
|
||||
if (!extent_buffer_uptodate(fs_info->chunk_root->node)) {
|
||||
if (fs_info->ignore_chunk_tree_error) {
|
||||
|
@ -1200,6 +1213,7 @@ int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info)
|
|||
static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
|
||||
u64 sb_bytenr,
|
||||
u64 root_tree_bytenr,
|
||||
u64 chunk_root_bytenr,
|
||||
enum btrfs_open_ctree_flags flags)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info;
|
||||
|
@ -1273,7 +1287,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
|
|||
if (ret)
|
||||
goto out_devices;
|
||||
|
||||
ret = btrfs_setup_chunk_tree_and_device_map(fs_info);
|
||||
ret = btrfs_setup_chunk_tree_and_device_map(fs_info, chunk_root_bytenr);
|
||||
if (ret)
|
||||
goto out_chunk;
|
||||
|
||||
|
@ -1305,6 +1319,7 @@ out:
|
|||
|
||||
struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
|
||||
u64 sb_bytenr, u64 root_tree_bytenr,
|
||||
u64 chunk_root_bytenr,
|
||||
enum btrfs_open_ctree_flags flags)
|
||||
{
|
||||
int fp;
|
||||
|
@ -1320,7 +1335,7 @@ struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
|
|||
return NULL;
|
||||
}
|
||||
info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr,
|
||||
flags);
|
||||
chunk_root_bytenr, flags);
|
||||
close(fp);
|
||||
return info;
|
||||
}
|
||||
|
@ -1332,7 +1347,7 @@ struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
|
|||
|
||||
/* This flags may not return fs_info with any valid root */
|
||||
BUG_ON(flags & OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR);
|
||||
info = open_ctree_fs_info(filename, sb_bytenr, 0, flags);
|
||||
info = open_ctree_fs_info(filename, sb_bytenr, 0, 0, flags);
|
||||
if (!info)
|
||||
return NULL;
|
||||
if (flags & __OPEN_CTREE_RETURN_CHUNK_ROOT)
|
||||
|
@ -1347,7 +1362,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
|
|||
|
||||
/* This flags may not return fs_info with any valid root */
|
||||
BUG_ON(flags & OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR);
|
||||
info = __open_ctree_fd(fp, path, sb_bytenr, 0, flags);
|
||||
info = __open_ctree_fd(fp, path, sb_bytenr, 0, 0, flags);
|
||||
if (!info)
|
||||
return NULL;
|
||||
if (flags & __OPEN_CTREE_RETURN_CHUNK_ROOT)
|
||||
|
|
|
@ -109,7 +109,8 @@ void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info);
|
|||
int btrfs_scan_fs_devices(int fd, const char *path,
|
||||
struct btrfs_fs_devices **fs_devices, u64 sb_bytenr,
|
||||
int super_recover, int skip_devices);
|
||||
int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info,
|
||||
u64 chunk_root_bytenr);
|
||||
|
||||
struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
|
||||
enum btrfs_open_ctree_flags flags);
|
||||
|
@ -117,6 +118,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
|
|||
enum btrfs_open_ctree_flags flags);
|
||||
struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
|
||||
u64 sb_bytenr, u64 root_tree_bytenr,
|
||||
u64 chunk_root_bytenr,
|
||||
enum btrfs_open_ctree_flags flags);
|
||||
int close_ctree_fs_info(struct btrfs_fs_info *fs_info);
|
||||
static inline int close_ctree(struct btrfs_root *root)
|
||||
|
|
Loading…
Reference in a new issue