]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: accept grain script header
authorKarel Zak <kzak@redhat.com>
Wed, 12 Sep 2018 11:18:08 +0000 (13:18 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 12 Sep 2018 11:26:18 +0000 (13:26 +0200)
The "grain" variable is used to calculate partitions alignment. The
default is 1MiB (or minimal I/O size). The libfdisk provides API to overwrite
this default, but this feature has been nowhere accessible for
end-user.

This patch support for "grain: <size>" in libfdisk scripts.

Addresses: https://github.com/karelzak/util-linux/issues/688
Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/sfdisk.8
libfdisk/src/alignment.c
libfdisk/src/script.c

index 4ea7cf363cd24c666d95ebee704368c43bfbb6d2..98b574e45fb59a32238f794d6d5b11978a77bf43 100644 (file)
@@ -322,6 +322,11 @@ Specify the last usable sector for GPT partitions.
 .TP
 .B table-length
 Specify the maximal number of GPT partitions.
+.TP
+.B grain
+Specify minimal size in bytes used to calculate partitions alignment.  The
+default is 1MiB and it's strongly recommended to use the default.  Do not
+modify this variable if you're not sure.
 .RE
 .sp
 Note that it is only possible to use header lines before the first partition
index 891285aaa0b274c6f86321a0f866501f01cbf077..a238c7bf0dc0104723f962d050d44da73b56f98a 100644 (file)
@@ -338,6 +338,7 @@ int fdisk_save_user_grain(struct fdisk_context *cxt, unsigned long grain)
        if (!cxt || grain % 512)
                return -EINVAL;
 
+       DBG(CXT, ul_debugobj(cxt, "user grain size: %lu", grain));
        cxt->user_grain = grain;
        return 0;
 }
index 1970e7b66fc8e6e6295905ca64eb573e04c59eee..24c40f8ce9ce6268d8068031dc829276910979e2 100644 (file)
@@ -241,7 +241,6 @@ const char *fdisk_script_get_header(struct fdisk_script *dp, const char *name)
        return fi ? fi->data : NULL;
 }
 
-
 /**
  * fdisk_script_set_header:
  * @dp: script instance
@@ -447,6 +446,14 @@ int fdisk_script_read_context(struct fdisk_script *dp, struct fdisk_context *cxt
                }
        }
 
+       if (!rc && fdisk_get_grain_size(cxt) != 2048 * 512) {
+               char buf[64];
+
+               snprintf(buf, sizeof(buf), "%zu", fdisk_get_grain_size(cxt));
+               rc = fdisk_script_set_header(dp, "grain", buf);
+       }
+
+
        DBG(SCRIPT, ul_debugobj(dp, "read context done [rc=%d]", rc));
        return rc;
 }
@@ -759,6 +766,7 @@ static int parse_line_header(struct fdisk_script *dp, char *s)
                        goto done;                      /* only "sectors" supported */
        } else if (strcmp(name, "label-id") == 0
                   || strcmp(name, "device") == 0
+                  || strcmp(name, "grain") == 0
                   || strcmp(name, "first-lba") == 0
                   || strcmp(name, "last-lba") == 0
                   || strcmp(name, "table-length") == 0) {
@@ -1432,6 +1440,20 @@ int fdisk_apply_script_headers(struct fdisk_context *cxt, struct fdisk_script *d
        DBG(SCRIPT, ul_debugobj(dp, "applying script headers"));
        fdisk_set_script(cxt, dp);
 
+       str = fdisk_script_get_header(dp, "grain");
+       if (str) {
+               uintmax_t sz;
+
+               rc = parse_size(str, &sz, NULL);
+               if (rc == 0)
+                       rc = fdisk_save_user_grain(cxt, sz);
+               if (rc)
+                       return rc;
+       }
+
+       if (fdisk_has_user_device_properties(cxt))
+               fdisk_apply_user_device_properties(cxt);
+
        /* create empty label */
        name = fdisk_script_get_header(dp, "label");
        if (!name)