]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: add fdisk_save_user_grain()
authorKarel Zak <kzak@redhat.com>
Tue, 22 Aug 2017 12:55:51 +0000 (14:55 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 22 Aug 2017 12:55:51 +0000 (14:55 +0200)
Let's provide API for applications that don't want to use the default
1MiB grain. The new function allow to use "as minimal as possible" if
grain is set by fdisk_save_user_grain() to 512.

If the phy sector size (or minimal I/O size) is greater than specified
grain size than smallest possible setting is used.

Signed-off-by: Karel Zak <kzak@redhat.com>
libfdisk/docs/libfdisk-sections.txt
libfdisk/src/alignment.c
libfdisk/src/fdiskP.h
libfdisk/src/libfdisk.h.in
libfdisk/src/libfdisk.sym

index 68ca0927fdd0f4e9ec6ed05391e36eadb0d00c61..37ceffa864d8a9749033dd3e28cfaf7aa11db7fa 100644 (file)
@@ -69,6 +69,7 @@ fdisk_override_geometry
 fdisk_reset_alignment
 fdisk_reset_device_properties
 fdisk_save_user_geometry
+fdisk_save_user_grain
 fdisk_save_user_sector_size
 </SECTION>
 
index 6b395b48cd6ce1f3a2e13d005d408f9158042903..4c9fbcb9a78547122b3035498871db435a343068 100644 (file)
@@ -26,7 +26,7 @@
  * It's recommended to not change any alignment or device properties. All is
  * initialized by default by fdisk_assign_device().
  *
- * Note that terminology used by libfdisk is: 
+ * Note that terminology used by libfdisk is:
  *   - device properties: I/O limits (topology), geometry, sector size, ...
  *   - alignment: first, last LBA, grain, ...
  *
@@ -313,6 +313,36 @@ int fdisk_save_user_sector_size(struct fdisk_context *cxt,
        return 0;
 }
 
+/**
+ * fdisk_save_user_grain:
+ * @cxt: context
+ * @grain: size in bytes (>= 512, multiple of 512)
+ *
+ * Save user define grain size. The size is used to align partitions.
+ *
+ * The default is 1MiB (or optimal I/O size if greater than 1MiB). It's strongly
+ * recommended to use the default.
+ *
+ * The smallest possible granularity for partitioning is physical sector size
+ * (or minimal I/O size; the bigger number win). If the user's @grain size is
+ * too small than the smallest possible granularity is used. It means
+ * fdisk_save_user_grain(cxt, 512) forces libfdisk to use grain as small as
+ * possible.
+ *
+ * The setting is applied by fdisk_assign_device() or
+ * fdisk_reset_device_properties().
+ *
+ * Returns: <0 on error, 0 on success.
+ */
+int fdisk_save_user_grain(struct fdisk_context *cxt, unsigned long grain)
+{
+       if (!cxt || grain % 512)
+               return -EINVAL;
+
+       cxt->user_grain = grain;
+       return 0;
+}
+
 /**
  * fdisk_has_user_device_properties:
  * @cxt: context
@@ -322,6 +352,7 @@ int fdisk_save_user_sector_size(struct fdisk_context *cxt,
 int fdisk_has_user_device_properties(struct fdisk_context *cxt)
 {
        return (cxt->user_pyh_sector || cxt->user_log_sector ||
+               cxt->user_grain ||
                fdisk_has_user_device_geometry(cxt));
 }
 
@@ -363,6 +394,14 @@ int fdisk_apply_user_device_properties(struct fdisk_context *cxt)
                recount_geometry(cxt);
 
        fdisk_reset_alignment(cxt);
+
+       if (cxt->user_grain) {
+               unsigned long granularity = max(cxt->phy_sector_size, cxt->min_io_size);
+
+               cxt->grain = cxt->user_grain < granularity ? granularity : cxt->user_grain;
+               DBG(CXT, ul_debugobj(cxt, "new grain: %lu", cxt->grain));
+       }
+
        if (cxt->firstsector_bufsz != cxt->sector_size)
                fdisk_read_firstsector(cxt);
 
index 1796e18e1c1990bf15384a1c04749428086249fa..23903b4b47fbe5051772c107a27a58f8ce39d3ad 100644 (file)
@@ -399,6 +399,7 @@ struct fdisk_context {
        struct fdisk_geometry user_geom;
        unsigned long user_pyh_sector;
        unsigned long user_log_sector;
+       unsigned long user_grain;
 
        struct fdisk_label *label;      /* current label, pointer to labels[] */
 
index 1c16fe4b34fc885ec52fd974c73da8612e100c8b..3586d66267f1bfb22634e13ad43b06985d09ae13 100644 (file)
@@ -503,6 +503,9 @@ int fdisk_save_user_geometry(struct fdisk_context *cxt,
 int fdisk_save_user_sector_size(struct fdisk_context *cxt,
                                unsigned int phy,
                                unsigned int log);
+
+int fdisk_save_user_grain(struct fdisk_context *cxt, unsigned long grain);
+
 int fdisk_has_user_device_properties(struct fdisk_context *cxt);
 int fdisk_reset_alignment(struct fdisk_context *cxt);
 int fdisk_reset_device_properties(struct fdisk_context *cxt);
index 0d274847a02b7fef2b2c61d30ce721309e212db6..2c892a0c394eaec67a1f7ba823ff2cad809d7855 100644 (file)
@@ -289,4 +289,5 @@ FDISK_2.31 {
        fdisk_reread_changes;
        fdisk_disable_dialogs;
        fdisk_has_dialogs;
+       fdisk_save_user_grain;
 } FDISK_2.30;