]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: (gpt) write PMBR only when useful
authorPhilippe Reynes <philippe.reynes@softathome.com>
Mon, 11 Apr 2022 12:42:29 +0000 (14:42 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 12 Apr 2022 09:50:39 +0000 (11:50 +0200)
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@softathome.com>
libfdisk/src/gpt.c

index 72370a19a7b8093bf654724000d59bda3f5efb11..c6f482fd861c83c6e15beb8ba1168aae2cddb387 100644 (file)
@@ -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,24 @@ 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)
+               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);