The MBR is critical as it doesn't have a backup, so we only write it when it is really useful (ie: the current MBR is different than the new one). Signed-off-by: Philippe Reynes <philippe.reynes@xxxxxxxxxxxxxx> --- libfdisk/src/gpt.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c index 72370a19a..08b0a81dd 100644 --- a/libfdisk/src/gpt.c +++ b/libfdisk/src/gpt.c @@ -2024,6 +2024,19 @@ static int gpt_set_partition(struct fdisk_context *cxt, size_t n, return rc; } +static int gpt_read(struct fdisk_context *cxt, off_t offset, void *buf, size_t count) +{ + if (offset != lseek(cxt->dev_fd, offset, SEEK_SET)) + return -errno; + + if (read_all(cxt->dev_fd, buf, count)) + return -errno; + + DBG(GPT, ul_debug(" read OK [offset=%zu, size=%zu]", + (size_t) offset, count)); + return 0; +} + static int gpt_write(struct fdisk_context *cxt, off_t offset, void *buf, size_t count) { if (offset != lseek(cxt->dev_fd, offset, SEEK_SET)) @@ -2079,6 +2092,8 @@ static int gpt_write_header(struct fdisk_context *cxt, static int gpt_write_pmbr(struct fdisk_context *cxt) { struct gpt_legacy_mbr *pmbr; + struct gpt_legacy_mbr *current; + int rc; assert(cxt); assert(cxt->firstsector); @@ -2107,6 +2122,25 @@ static int gpt_write_pmbr(struct fdisk_context *cxt) pmbr->partition_record[0].size_in_lba = cpu_to_le32((uint32_t) (cxt->total_sectors - 1ULL)); + current = malloc(sizeof(*current)); + if (!current) + goto do_write; + + rc = gpt_read(cxt, GPT_PMBR_LBA * cxt->sector_size, + current, cxt->sector_size); + if (rc) + goto do_write; + + rc = memcmp(pmbr, current, sizeof(*current)); + + free(current); + + if (!rc) { + DBG(GPT, ul_debug("Same MBR on disk => don't write it")); + return 0; + } + + do_write: /* pMBR covers the first sector (LBA) of the disk */ return gpt_write(cxt, GPT_PMBR_LBA * cxt->sector_size, pmbr, cxt->sector_size); -- 2.25.1