fs: btrfs: Do not fail when all root_backups are empty
This is the case when reading freshly created filesystem. The error message is like the following: btrfs_read_superblock: No valid root_backup found! Since the data from super_roots/root_backups is not actually used - decided to rework btrfs_newest_root_backup() into btrfs_check_super_roots() that will only check if super_roots array is valid and correctly handle empty scenario. As a result: * btrfs_read_superblock() now only checks if super_roots array is valid; the case when it is empty is considered OK. * removed root_backup pointer from btrfs_info, which would be NULL in case of empty super_roots. * btrfs_read_superblock() verifies number of devices from the superblock itself, not newest root_backup. Signed-off-by: Yevgeny Popovych <yevgenyp@pointgrab.com> Cc: Marek Behun <marek.behun@nic.cz> Cc: Sergey Struzh <sergeys@pointgrab.com>
This commit is contained in:
parent
28b538b69d
commit
d146a7b9c6
@ -13,7 +13,6 @@
|
||||
|
||||
struct btrfs_info {
|
||||
struct btrfs_super_block sb;
|
||||
struct btrfs_root_backup *root_backup;
|
||||
|
||||
struct btrfs_root tree_root;
|
||||
struct btrfs_root fs_root;
|
||||
|
@ -15,18 +15,34 @@
|
||||
|
||||
#define BTRFS_SUPER_INFO_SIZE 4096
|
||||
|
||||
static int btrfs_newest_root_backup(struct btrfs_super_block *sb)
|
||||
/*
|
||||
* checks if a valid root backup is present.
|
||||
* considers the case when all root backups empty valid.
|
||||
* returns -1 in case of invalid root backup and 0 for valid.
|
||||
*/
|
||||
static int btrfs_check_super_roots(struct btrfs_super_block *sb)
|
||||
{
|
||||
struct btrfs_root_backup *root_backup;
|
||||
int i, newest = -1;
|
||||
int num_empty = 0;
|
||||
|
||||
for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; ++i) {
|
||||
root_backup = sb->super_roots + i;
|
||||
|
||||
if (root_backup->tree_root == 0 && root_backup->tree_root_gen == 0)
|
||||
num_empty++;
|
||||
|
||||
if (root_backup->tree_root_gen == sb->generation)
|
||||
newest = i;
|
||||
}
|
||||
|
||||
return newest;
|
||||
if (num_empty == BTRFS_NUM_BACKUP_ROOTS) {
|
||||
return 0;
|
||||
} else if (newest >= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int is_power_of_2(u64 x)
|
||||
@ -166,7 +182,7 @@ int btrfs_read_superblock(void)
|
||||
char raw_sb[BTRFS_SUPER_INFO_SIZE];
|
||||
struct btrfs_super_block *sb = (struct btrfs_super_block *) raw_sb;
|
||||
u64 dev_total_bytes;
|
||||
int i, root_backup_idx;
|
||||
int i;
|
||||
|
||||
dev_total_bytes = (u64) btrfs_part_info->size * btrfs_part_info->blksz;
|
||||
|
||||
@ -211,17 +227,15 @@ int btrfs_read_superblock(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
root_backup_idx = btrfs_newest_root_backup(&btrfs_info.sb);
|
||||
if (root_backup_idx < 0) {
|
||||
if (btrfs_check_super_roots(&btrfs_info.sb)) {
|
||||
printf("%s: No valid root_backup found!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
btrfs_info.root_backup = btrfs_info.sb.super_roots + root_backup_idx;
|
||||
|
||||
if (btrfs_info.root_backup->num_devices != 1) {
|
||||
if (btrfs_info.sb.num_devices != 1) {
|
||||
printf("%s: Unsupported number of devices (%lli). This driver "
|
||||
"only supports filesystem on one device.\n", __func__,
|
||||
btrfs_info.root_backup->num_devices);
|
||||
btrfs_info.sb.num_devices);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user