Skip to content
Snippets Groups Projects
Commit d146a7b9 authored by Yevgeny Popovych's avatar Yevgeny Popovych Committed by Tom Rini
Browse files

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: default avatarYevgeny Popovych <yevgenyp@pointgrab.com>
Cc: Marek Behun <marek.behun@nic.cz>
Cc: Sergey Struzh <sergeys@pointgrab.com>
parent 28b538b6
No related branches found
No related tags found
No related merge requests found
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
struct btrfs_info { struct btrfs_info {
struct btrfs_super_block sb; struct btrfs_super_block sb;
struct btrfs_root_backup *root_backup;
struct btrfs_root tree_root; struct btrfs_root tree_root;
struct btrfs_root fs_root; struct btrfs_root fs_root;
......
...@@ -15,18 +15,34 @@ ...@@ -15,18 +15,34 @@
#define BTRFS_SUPER_INFO_SIZE 4096 #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; struct btrfs_root_backup *root_backup;
int i, newest = -1; int i, newest = -1;
int num_empty = 0;
for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; ++i) { for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; ++i) {
root_backup = sb->super_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) if (root_backup->tree_root_gen == sb->generation)
newest = i; 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) static inline int is_power_of_2(u64 x)
...@@ -166,7 +182,7 @@ int btrfs_read_superblock(void) ...@@ -166,7 +182,7 @@ int btrfs_read_superblock(void)
char raw_sb[BTRFS_SUPER_INFO_SIZE]; char raw_sb[BTRFS_SUPER_INFO_SIZE];
struct btrfs_super_block *sb = (struct btrfs_super_block *) raw_sb; struct btrfs_super_block *sb = (struct btrfs_super_block *) raw_sb;
u64 dev_total_bytes; u64 dev_total_bytes;
int i, root_backup_idx; int i;
dev_total_bytes = (u64) btrfs_part_info->size * btrfs_part_info->blksz; dev_total_bytes = (u64) btrfs_part_info->size * btrfs_part_info->blksz;
...@@ -211,17 +227,15 @@ int btrfs_read_superblock(void) ...@@ -211,17 +227,15 @@ int btrfs_read_superblock(void)
return -1; return -1;
} }
root_backup_idx = btrfs_newest_root_backup(&btrfs_info.sb); if (btrfs_check_super_roots(&btrfs_info.sb)) {
if (root_backup_idx < 0) {
printf("%s: No valid root_backup found!\n", __func__); printf("%s: No valid root_backup found!\n", __func__);
return -1; 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 " printf("%s: Unsupported number of devices (%lli). This driver "
"only supports filesystem on one device.\n", __func__, "only supports filesystem on one device.\n", __func__,
btrfs_info.root_backup->num_devices); btrfs_info.sb.num_devices);
return -1; return -1;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment