Commit 735bd7e4 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Mike Snitzer

dm zoned: use array for superblock zones

Instead of storing just the first superblock zone and calculate
the secondary relative to that we should be using an array for
holding the superblock zones.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarDamien Le Moal <damien.lemoal@wdc.com>
Reviewed-by: default avatarBob Liu <bob.liu@oracle.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent b7122873
...@@ -124,6 +124,7 @@ struct dmz_sb { ...@@ -124,6 +124,7 @@ struct dmz_sb {
sector_t block; sector_t block;
struct dmz_mblock *mblk; struct dmz_mblock *mblk;
struct dmz_super *sb; struct dmz_super *sb;
struct dm_zone *zone;
}; };
/* /*
...@@ -150,7 +151,6 @@ struct dmz_metadata { ...@@ -150,7 +151,6 @@ struct dmz_metadata {
/* Zone information array */ /* Zone information array */
struct dm_zone *zones; struct dm_zone *zones;
struct dm_zone *sb_zone;
struct dmz_sb sb[2]; struct dmz_sb sb[2];
unsigned int mblk_primary; unsigned int mblk_primary;
u64 sb_gen; u64 sb_gen;
...@@ -839,8 +839,9 @@ int dmz_flush_metadata(struct dmz_metadata *zmd) ...@@ -839,8 +839,9 @@ int dmz_flush_metadata(struct dmz_metadata *zmd)
/* /*
* Check super block. * Check super block.
*/ */
static int dmz_check_sb(struct dmz_metadata *zmd, struct dmz_super *sb) static int dmz_check_sb(struct dmz_metadata *zmd, unsigned int set)
{ {
struct dmz_super *sb = zmd->sb[set].sb;
unsigned int nr_meta_zones, nr_data_zones; unsigned int nr_meta_zones, nr_data_zones;
struct dmz_dev *dev = zmd->dev; struct dmz_dev *dev = zmd->dev;
u32 crc, stored_crc; u32 crc, stored_crc;
...@@ -932,16 +933,20 @@ static int dmz_lookup_secondary_sb(struct dmz_metadata *zmd) ...@@ -932,16 +933,20 @@ static int dmz_lookup_secondary_sb(struct dmz_metadata *zmd)
/* Bad first super block: search for the second one */ /* Bad first super block: search for the second one */
zmd->sb[1].block = zmd->sb[0].block + zone_nr_blocks; zmd->sb[1].block = zmd->sb[0].block + zone_nr_blocks;
zmd->sb[1].zone = zmd->sb[0].zone + 1;
for (i = 0; i < zmd->nr_rnd_zones - 1; i++) { for (i = 0; i < zmd->nr_rnd_zones - 1; i++) {
if (dmz_read_sb(zmd, 1) != 0) if (dmz_read_sb(zmd, 1) != 0)
break; break;
if (le32_to_cpu(zmd->sb[1].sb->magic) == DMZ_MAGIC) if (le32_to_cpu(zmd->sb[1].sb->magic) == DMZ_MAGIC) {
zmd->sb[1].zone += i;
return 0; return 0;
}
zmd->sb[1].block += zone_nr_blocks; zmd->sb[1].block += zone_nr_blocks;
} }
dmz_free_mblock(zmd, mblk); dmz_free_mblock(zmd, mblk);
zmd->sb[1].mblk = NULL; zmd->sb[1].mblk = NULL;
zmd->sb[1].zone = NULL;
return -EIO; return -EIO;
} }
...@@ -985,11 +990,9 @@ static int dmz_recover_mblocks(struct dmz_metadata *zmd, unsigned int dst_set) ...@@ -985,11 +990,9 @@ static int dmz_recover_mblocks(struct dmz_metadata *zmd, unsigned int dst_set)
dmz_dev_warn(zmd->dev, "Metadata set %u invalid: recovering", dst_set); dmz_dev_warn(zmd->dev, "Metadata set %u invalid: recovering", dst_set);
if (dst_set == 0) if (dst_set == 0)
zmd->sb[0].block = dmz_start_block(zmd, zmd->sb_zone); zmd->sb[0].block = dmz_start_block(zmd, zmd->sb[0].zone);
else { else
zmd->sb[1].block = zmd->sb[0].block + zmd->sb[1].block = dmz_start_block(zmd, zmd->sb[1].zone);
(zmd->nr_meta_zones << zmd->dev->zone_nr_blocks_shift);
}
page = alloc_page(GFP_NOIO); page = alloc_page(GFP_NOIO);
if (!page) if (!page)
...@@ -1033,21 +1036,27 @@ static int dmz_load_sb(struct dmz_metadata *zmd) ...@@ -1033,21 +1036,27 @@ static int dmz_load_sb(struct dmz_metadata *zmd)
u64 sb_gen[2] = {0, 0}; u64 sb_gen[2] = {0, 0};
int ret; int ret;
if (!zmd->sb[0].zone) {
dmz_dev_err(zmd->dev, "Primary super block zone not set");
return -ENXIO;
}
/* Read and check the primary super block */ /* Read and check the primary super block */
zmd->sb[0].block = dmz_start_block(zmd, zmd->sb_zone); zmd->sb[0].block = dmz_start_block(zmd, zmd->sb[0].zone);
ret = dmz_get_sb(zmd, 0); ret = dmz_get_sb(zmd, 0);
if (ret) { if (ret) {
dmz_dev_err(zmd->dev, "Read primary super block failed"); dmz_dev_err(zmd->dev, "Read primary super block failed");
return ret; return ret;
} }
ret = dmz_check_sb(zmd, zmd->sb[0].sb); ret = dmz_check_sb(zmd, 0);
/* Read and check secondary super block */ /* Read and check secondary super block */
if (ret == 0) { if (ret == 0) {
sb_good[0] = true; sb_good[0] = true;
zmd->sb[1].block = zmd->sb[0].block + if (!zmd->sb[1].zone)
(zmd->nr_meta_zones << zmd->dev->zone_nr_blocks_shift); zmd->sb[1].zone = zmd->sb[0].zone + zmd->nr_meta_zones;
zmd->sb[1].block = dmz_start_block(zmd, zmd->sb[1].zone);
ret = dmz_get_sb(zmd, 1); ret = dmz_get_sb(zmd, 1);
} else } else
ret = dmz_lookup_secondary_sb(zmd); ret = dmz_lookup_secondary_sb(zmd);
...@@ -1057,7 +1066,7 @@ static int dmz_load_sb(struct dmz_metadata *zmd) ...@@ -1057,7 +1066,7 @@ static int dmz_load_sb(struct dmz_metadata *zmd)
return ret; return ret;
} }
ret = dmz_check_sb(zmd, zmd->sb[1].sb); ret = dmz_check_sb(zmd, 1);
if (ret == 0) if (ret == 0)
sb_good[1] = true; sb_good[1] = true;
...@@ -1142,9 +1151,9 @@ static int dmz_init_zone(struct blk_zone *blkz, unsigned int idx, void *data) ...@@ -1142,9 +1151,9 @@ static int dmz_init_zone(struct blk_zone *blkz, unsigned int idx, void *data)
zmd->nr_useable_zones++; zmd->nr_useable_zones++;
if (dmz_is_rnd(zone)) { if (dmz_is_rnd(zone)) {
zmd->nr_rnd_zones++; zmd->nr_rnd_zones++;
if (!zmd->sb_zone) { if (!zmd->sb[0].zone) {
/* Super block zone */ /* Super block zone */
zmd->sb_zone = zone; zmd->sb[0].zone = zone;
} }
} }
} }
...@@ -2415,7 +2424,7 @@ int dmz_ctr_metadata(struct dmz_dev *dev, struct dmz_metadata **metadata) ...@@ -2415,7 +2424,7 @@ int dmz_ctr_metadata(struct dmz_dev *dev, struct dmz_metadata **metadata)
/* Set metadata zones starting from sb_zone */ /* Set metadata zones starting from sb_zone */
for (i = 0; i < zmd->nr_meta_zones << 1; i++) { for (i = 0; i < zmd->nr_meta_zones << 1; i++) {
zone = dmz_get(zmd, zmd->sb_zone->id + i); zone = dmz_get(zmd, zmd->sb[0].zone->id + i);
if (!dmz_is_rnd(zone)) if (!dmz_is_rnd(zone))
goto err; goto err;
set_bit(DMZ_META, &zone->flags); set_bit(DMZ_META, &zone->flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment