mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
filter: partitioned: also detect non-empty GPT partition table
We already detect msdos partition table. If it is empty, that is, there is just the partition header and no actual partitions defined, then the filter-partitioned passes, otherwise not. Do the same for GPT partition table.
This commit is contained in:
parent
4708a354f6
commit
84cabd068b
@ -505,6 +505,11 @@ int dev_get_partition_number(struct device *dev, int *num)
|
|||||||
#define PART_MAGIC 0xAA55
|
#define PART_MAGIC 0xAA55
|
||||||
#define PART_MAGIC_OFFSET UINT64_C(0x1FE)
|
#define PART_MAGIC_OFFSET UINT64_C(0x1FE)
|
||||||
#define PART_OFFSET UINT64_C(0x1BE)
|
#define PART_OFFSET UINT64_C(0x1BE)
|
||||||
|
#define PART_TYPE_GPT_PMBR UINT8_C(0xEE)
|
||||||
|
|
||||||
|
#define PART_GPT_HEADER_OFFSET_LBA 0x01
|
||||||
|
#define PART_GPT_MAGIC 0x5452415020494645UL /* "EFI PART" string */
|
||||||
|
#define PART_GPT_ENTRIES_FIELDS_OFFSET UINT64_C(0x48)
|
||||||
|
|
||||||
struct partition {
|
struct partition {
|
||||||
uint8_t boot_ind;
|
uint8_t boot_ind;
|
||||||
@ -570,6 +575,65 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _has_gpt_partition_table(struct device *dev)
|
||||||
|
{
|
||||||
|
unsigned int pbs, lbs;
|
||||||
|
uint64_t entries_start;
|
||||||
|
uint32_t nr_entries, sz_entry, i;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint64_t magic;
|
||||||
|
/* skip fields we're not interested in */
|
||||||
|
uint8_t skip[PART_GPT_ENTRIES_FIELDS_OFFSET - sizeof(uint64_t)];
|
||||||
|
uint64_t part_entries_lba;
|
||||||
|
uint32_t nr_part_entries;
|
||||||
|
uint32_t sz_part_entry;
|
||||||
|
} __attribute__((packed)) gpt_header;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint64_t part_type_guid;
|
||||||
|
/* not interested in any other fields */
|
||||||
|
} __attribute__((packed)) gpt_part_entry;
|
||||||
|
|
||||||
|
if (!dev_get_direct_block_sizes(dev, &pbs, &lbs))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (!dev_read_bytes(dev, PART_GPT_HEADER_OFFSET_LBA * lbs, sizeof(gpt_header), &gpt_header))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
/* the gpt table is always written using LE on disk */
|
||||||
|
|
||||||
|
if (le64_to_cpu(gpt_header.magic) != PART_GPT_MAGIC)
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
entries_start = le64_to_cpu(gpt_header.part_entries_lba) * lbs;
|
||||||
|
nr_entries = le32_to_cpu(gpt_header.nr_part_entries);
|
||||||
|
sz_entry = le32_to_cpu(gpt_header.sz_part_entry);
|
||||||
|
|
||||||
|
for (i = 0; i < nr_entries; i++) {
|
||||||
|
if (!dev_read_bytes(dev, entries_start + i * sz_entry,
|
||||||
|
sizeof(gpt_part_entry), &gpt_part_entry))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
/* just check if the guid is nonzero, no need to call le64_to_cpu here */
|
||||||
|
if (gpt_part_entry.part_type_guid)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if there's a partition table present on the device dev, either msdos or gpt.
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
* 1 - if it has a partition table with at least one real partition defined
|
||||||
|
* (note: the gpt's PMBR partition alone does not count as a real partition)
|
||||||
|
*
|
||||||
|
* 0 - if it has no partition table,
|
||||||
|
* - or if it does have a partition table, but without any partition defined,
|
||||||
|
* - or on error
|
||||||
|
*/
|
||||||
static int _has_partition_table(struct device *dev)
|
static int _has_partition_table(struct device *dev)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -594,10 +658,20 @@ static int _has_partition_table(struct device *dev)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Must have at least one non-empty partition */
|
/* Must have at least one non-empty partition */
|
||||||
if (buf.part[p].nr_sects)
|
if (buf.part[p].nr_sects) {
|
||||||
ret = 1;
|
/*
|
||||||
|
* If this is GPT's PMBR, then also
|
||||||
|
* check for gpt partition table.
|
||||||
|
*/
|
||||||
|
if (buf.part[p].sys_ind == PART_TYPE_GPT_PMBR)
|
||||||
|
ret = _has_gpt_partition_table(dev);
|
||||||
|
else
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
/* Check for gpt partition table. */
|
||||||
|
ret = _has_gpt_partition_table(dev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user