From: Karel Zak Date: Fri, 6 Sep 2019 11:53:50 +0000 (+0200) Subject: sfdisk: (--move-data) keep step size based on optimal I/O X-Git-Tag: v2.35-rc1~230 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ce4675cce59b6d0ddc730db64bfce30433af39f;p=thirdparty%2Futil-linux.git sfdisk: (--move-data) keep step size based on optimal I/O The current implementation is too paranoid and tries to keep in memory only data which are on disk too. It means very small step size when move partition only a few sectors left/right. This patch enlarge the buffer to at least 1MiB and aligned to optimal I/O. Addresses: https://github.com/karelzak/util-linux/issues/848 Signed-off-by: Karel Zak --- diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c index 80c92fb211..c8efb5280b 100644 --- a/disk-utils/sfdisk.c +++ b/disk-utils/sfdisk.c @@ -370,7 +370,7 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa FILE *f = NULL; int ok = 0, fd, backward = 0; fdisk_sector_t nsectors, from, to, step, i; - size_t ss, step_bytes, cc; + size_t io, ss, step_bytes, cc; uintmax_t src, dst; int errsv; @@ -399,7 +399,7 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa fd = fdisk_get_devfd(sf->cxt); - ss = fdisk_get_sector_size(sf->cxt); + /* set move direction and overlay */ nsectors = fdisk_partition_get_size(orig_pa); from = fdisk_partition_get_start(orig_pa); to = fdisk_partition_get_start(pa); @@ -411,22 +411,24 @@ static int move_partition_data(struct sfdisk *sf, size_t partno, struct fdisk_pa DBG(MISC, ul_debug("overlay between source and target")); backward = from < to; DBG(MISC, ul_debug(" copy order: %s", backward ? "backward" : "forward")); + } - step = from > to ? from - to : to - from; - if (step > nsectors) - step = nsectors; - } else - step = nsectors; + /* set optimal step size -- nearest to 1MiB aligned to optimal I/O */ + io = fdisk_get_optimal_iosize(sf->cxt); + ss = fdisk_get_sector_size(sf->cxt); + if (!io) + io = ss; + if (io < 1024 * 1024) + step_bytes = ((1024 * 1024) + io/2) / io * io; + else + step_bytes = io; - /* make step usable for malloc() */ - if (step * ss > (getpagesize() * 256U)) - step = (getpagesize() * 256) / ss; + step = step_bytes / ss; /* align the step (note that nsectors does not have to be power of 2) */ while (nsectors % step) step--; - step_bytes = step * ss; DBG(MISC, ul_debug(" step: %ju (%zu bytes)", (uintmax_t)step, step_bytes)); #if defined(POSIX_FADV_SEQUENTIAL) && defined(HAVE_POSIX_FADVISE)