partitions/efi: Support non-standard GPT location
authorDmitry Osipenko <digetx@gmail.com>
Fri, 20 Aug 2021 00:45:34 +0000 (03:45 +0300)
committerJens Axboe <axboe@kernel.dk>
Tue, 24 Aug 2021 16:09:06 +0000 (10:09 -0600)
Support looking up GPT at a non-standard location specified by a block
device driver.

Acked-by: Davidlohr Bueso <dbueso@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Link: https://lore.kernel.org/r/20210820004536.15791-3-digetx@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/partitions/efi.c

index aaa3dc4..7ca5c4c 100644 (file)
@@ -585,6 +585,8 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
        gpt_header *pgpt = NULL, *agpt = NULL;
        gpt_entry *pptes = NULL, *aptes = NULL;
        legacy_mbr *legacymbr;
        gpt_header *pgpt = NULL, *agpt = NULL;
        gpt_entry *pptes = NULL, *aptes = NULL;
        legacy_mbr *legacymbr;
+       struct gendisk *disk = state->disk;
+       const struct block_device_operations *fops = disk->fops;
        sector_t total_sectors = get_capacity(state->disk);
        u64 lastlba;
 
        sector_t total_sectors = get_capacity(state->disk);
        u64 lastlba;
 
@@ -619,6 +621,16 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
         if (!good_agpt && force_gpt)
                 good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes);
 
         if (!good_agpt && force_gpt)
                 good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes);
 
+       if (!good_agpt && force_gpt && fops->alternative_gpt_sector) {
+               sector_t agpt_sector;
+               int err;
+
+               err = fops->alternative_gpt_sector(disk, &agpt_sector);
+               if (!err)
+                       good_agpt = is_gpt_valid(state, agpt_sector,
+                                                &agpt, &aptes);
+       }
+
         /* The obviously unsuccessful case */
         if (!good_pgpt && !good_agpt)
                 goto fail;
         /* The obviously unsuccessful case */
         if (!good_pgpt && !good_agpt)
                 goto fail;