diff options
author | Karel Zak | 2017-08-22 14:55:51 +0200 |
---|---|---|
committer | Karel Zak | 2017-08-22 14:55:51 +0200 |
commit | adf09b5c380fe616fa28b1975703b83e75d0b32b (patch) | |
tree | 779ed6403b989552397369bf80b28dfc7d09e204 /libfdisk | |
parent | libfdisk: (dos) use size-=1 when alignment not used later (diff) | |
download | kernel-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')
-rw-r--r-- | libfdisk/docs/libfdisk-sections.txt | 1 | ||||
-rw-r--r-- | libfdisk/src/alignment.c | 41 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 1 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h.in | 3 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.sym | 1 |
5 files changed, 46 insertions, 1 deletions
diff --git a/libfdisk/docs/libfdisk-sections.txt b/libfdisk/docs/libfdisk-sections.txt index 68ca0927f..37ceffa86 100644 --- a/libfdisk/docs/libfdisk-sections.txt +++ b/libfdisk/docs/libfdisk-sections.txt @@ -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> 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); diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 1796e18e1..23903b4b4 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -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[] */ diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in index 1c16fe4b3..3586d6626 100644 --- a/libfdisk/src/libfdisk.h.in +++ b/libfdisk/src/libfdisk.h.in @@ -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); diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym index 0d274847a..2c892a0c3 100644 --- a/libfdisk/src/libfdisk.sym +++ b/libfdisk/src/libfdisk.sym @@ -289,4 +289,5 @@ FDISK_2.31 { fdisk_reread_changes; fdisk_disable_dialogs; fdisk_has_dialogs; + fdisk_save_user_grain; } FDISK_2.30; |