diff options
author | Yevgeny Popovych <yevgenyp@pointgrab.com> | 2018-06-11 14:14:33 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-06-18 14:43:12 -0400 |
commit | d146a7b9c6200c7a84a15208f0c06e0ab60890dd (patch) | |
tree | 3aa7e880487de5353ed1e4e04e3d787971229079 /fs | |
parent | 28b538b69dd44b5f4ea595059612115069ace96b (diff) |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/btrfs.h | 1 | ||||
-rw-r--r-- | fs/btrfs/super.c | 30 |
2 files changed, 22 insertions, 9 deletions
diff --git a/fs/btrfs/btrfs.h b/fs/btrfs/btrfs.h index 27d78837c5..986d078679 100644 --- a/fs/btrfs/btrfs.h +++ b/fs/btrfs/btrfs.h @@ -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; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index ad6641f314..e680caa56a 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -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; } |