summaryrefslogtreecommitdiffstats
path: root/libfdisk/src/alignment.c
diff options
context:
space:
mode:
authorKarel Zak2017-08-22 14:55:51 +0200
committerKarel Zak2017-08-22 14:55:51 +0200
commitadf09b5c380fe616fa28b1975703b83e75d0b32b (patch)
tree779ed6403b989552397369bf80b28dfc7d09e204 /libfdisk/src/alignment.c
parentlibfdisk: (dos) use size-=1 when alignment not used later (diff)
downloadkernel-qcow2-util-linux-adf09b5c380fe616fa28b1975703b83e75d0b32b.tar.gz
kernel-qcow2-util-linux-adf09b5c380fe616fa28b1975703b83e75d0b32b.tar.xz
kernel-qcow2-util-linux-adf09b5c380fe616fa28b1975703b83e75d0b32b.zip
libfdisk: add fdisk_save_user_grain()
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>
Diffstat (limited to 'libfdisk/src/alignment.c')
-rw-r--r--libfdisk/src/alignment.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/libfdisk/src/alignment.c b/libfdisk/src/alignment.c
index 6b395b48c..4c9fbcb9a 100644
--- a/libfdisk/src/alignment.c
+++ b/libfdisk/src/alignment.c
@@ -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, ...
*
@@ -314,6 +314,36 @@ int fdisk_save_user_sector_size(struct fdisk_context *cxt,
}
/**
+ * 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);