From 7dc6bce18942789bf4a2971a04530de476410356 Mon Sep 17 00:00:00 2001 From: Nathan Owens Date: Fri, 22 Nov 2019 18:50:32 -0600 Subject: [PATCH] gpart: various improvements Add patch to fix crash non-disk device Add patch to avoid superfluous seek calls Add patches to increase reading speed Add patch for LVM2 and btrfs to list of supported modules Signed-off-by: Nathan Owens --- .../0001-Fix-crash-on-a-non-disk-device.patch | 152 ++++++++++++++++++ ...2-gpart-avoid-superfluous-seek-calls.patch | 113 +++++++++++++ ...ix_fadvise-to-increase-reading-speed.patch | 42 +++++ ...04-Speed-up-by-reading-larger-chunks.patch | 54 +++++++ ...d-btrfs-to-list-of-supported-modules.patch | 26 +++ srcpkgs/gpart/template | 12 +- 6 files changed, 390 insertions(+), 9 deletions(-) create mode 100644 srcpkgs/gpart/patches/0001-Fix-crash-on-a-non-disk-device.patch create mode 100644 srcpkgs/gpart/patches/0002-gpart-avoid-superfluous-seek-calls.patch create mode 100644 srcpkgs/gpart/patches/0003-gpart-use-posix_fadvise-to-increase-reading-speed.patch create mode 100644 srcpkgs/gpart/patches/0004-Speed-up-by-reading-larger-chunks.patch create mode 100644 srcpkgs/gpart/patches/0005-Add-LVM2-and-btrfs-to-list-of-supported-modules.patch diff --git a/srcpkgs/gpart/patches/0001-Fix-crash-on-a-non-disk-device.patch b/srcpkgs/gpart/patches/0001-Fix-crash-on-a-non-disk-device.patch new file mode 100644 index 0000000000..f5b213f793 --- /dev/null +++ b/srcpkgs/gpart/patches/0001-Fix-crash-on-a-non-disk-device.patch @@ -0,0 +1,152 @@ +From 42c45995fdee50f135f1ac42d0ab496dd0d01f60 Mon Sep 17 00:00:00 2001 +From: Baruch Even +Date: Wed, 25 Nov 2015 23:02:38 +0200 +Subject: [PATCH 1/5] Fix crash on a non-disk device + +Closes #9 +--- + src/disku.c | 115 +++++++++++++++++++++++++++------------------------- + 1 file changed, 59 insertions(+), 56 deletions(-) + +diff --git src/disku.c src/disku.c +index b918147..b33ba91 100644 +--- src/disku.c ++++ src/disku.c +@@ -36,66 +36,33 @@ + + #include + +- +-/* +- * get disk geometry. The medium is opened for reading, +- * descriptor in d_fd. +- */ +- +-struct disk_geom *disk_geometry(disk_desc *d) +-{ +- static struct disk_geom g; +- uint64_t nsects; +- +- memset(&g, 0, sizeof(g)); +- + #if defined(__linux__) +- struct hd_geometry hg; +-#endif +-#if defined(__FreeBSD__) +- struct disklabel dl; +-#endif +- +- struct stat st; +- int ret; +- uint64_t lba; +- ret = stat(d->d_dev, &st); +- if (ret == 0) +- { +- if (S_ISREG(st.st_mode)) +- { +- nsects = st.st_size / 512; +- if (nsects == 0) +- pr(FATAL, EM_FATALERROR, "Not a block device image file"); +- lba = nsects - 1; +- g.d_h = (lba / 63) % 255; +- g.d_s = lba % 63 + 1; +- g.d_c = lba / (255 * 63); +- g.d_nsecs = nsects; +- return (&g); +- } ++static void os_disk_geometry(disk_desc *d, struct disk_geom *g) ++{ ++ struct hd_geometry hg; ++ uint64_t nsects; ++ ++ if (ioctl(d->d_fd, HDIO_GETGEO, &hg) == -1) ++ pr(FATAL, EM_IOCTLFAILED, "HDIO_GETGEO", strerror(errno)); ++ else { ++ g->d_h = hg.heads; ++ g->d_s = hg.sectors; ++ g->d_c = hg.cylinders; + } +- +-#if defined(__linux__) +- if (ioctl(d->d_fd,HDIO_GETGEO,&hg) == -1) +- pr(FATAL,EM_IOCTLFAILED,"HDIO_GETGEO",strerror(errno)); + #ifdef BLKGETSIZE +- if (ioctl(d->d_fd,BLKGETSIZE,&nsects) == -1) +- pr(FATAL,EM_IOCTLFAILED,"BLKGETSIZE",strerror(errno)); +- g.d_nsecs = nsects; +- g.d_c = nsects / (hg.heads * hg.sectors); +-#else +- g.d_c = hg.cylinders; +-#endif +- g.d_h = hg.heads; +- g.d_s = hg.sectors; +- ++ if (ioctl(d->d_fd, BLKGETSIZE, &nsects) == -1) ++ pr(FATAL, EM_IOCTLFAILED, "BLKGETSIZE", strerror(errno)); ++ else ++ g->d_c = nsects / (hg.heads * hg.sectors); + #endif +- +-#if defined(__FreeBSD__) +- struct disklabel loclab; +- u_int u; +- off_t o; /* total disk size */ ++} ++#elif defined(__FreeBSD__) ++static void os_disk_geometry(disk_desc *d, struct disk_geom *g) ++{ ++ struct disklabel dl; ++ struct disklabel loclab; ++ u_int u; ++ off_t o; /* total disk size */ + + if (ioctl(d->d_fd, DIOCGFWSECTORS, &u) == 0) + g.d_s = u; +@@ -114,8 +81,44 @@ struct disk_geom *disk_geometry(disk_desc *d) + + g.d_nsecs = o / u; + g.d_c = g.d_nsecs / g.d_h / g.d_s; ++} ++#else ++#error Only Linux and FreeBSD supported + #endif + ++/* ++ * get disk geometry. The medium is opened for reading, ++ * descriptor in d_fd. ++ */ ++ ++struct disk_geom *disk_geometry(disk_desc *d) ++{ ++ static struct disk_geom g; ++ uint64_t nsects; ++ ++ memset(&g, 0, sizeof(g)); ++ ++ struct stat st; ++ int ret; ++ uint64_t lba; ++ ret = stat(d->d_dev, &st); ++ if (ret == 0) { ++ // We have something, we'll use it for a first fill of the data ++ nsects = st.st_size / 512; ++ if (nsects == 0) ++ pr(FATAL, EM_FATALERROR, "Not a block device image file"); ++ lba = nsects - 1; ++ g.d_h = (lba / 63) % 255; ++ g.d_s = lba % 63 + 1; ++ g.d_c = lba / (255 * 63); ++ g.d_nsecs = nsects; ++ ++ // If it is a regular file there is no reason to try anything else ++ if (S_ISREG(st.st_mode)) ++ return (&g); ++ } ++ ++ os_disk_geometry(d, &g); + return (&g); + } + +-- +2.24.0 + diff --git a/srcpkgs/gpart/patches/0002-gpart-avoid-superfluous-seek-calls.patch b/srcpkgs/gpart/patches/0002-gpart-avoid-superfluous-seek-calls.patch new file mode 100644 index 0000000000..7c91cce1c5 --- /dev/null +++ b/srcpkgs/gpart/patches/0002-gpart-avoid-superfluous-seek-calls.patch @@ -0,0 +1,113 @@ +From bba08ed9c64e8e8dad239b19e6ca8128adcaac64 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 20 Nov 2015 00:17:13 +0100 +Subject: [PATCH 2/5] gpart: avoid superfluous seek calls + +The l64opush() logic would cause 2 lseek() syscalls per guess loop. +By simply seeking back after every probing call, we do with a single +seek() call. +--- + src/gpart.c | 42 ++++++++++++++++++++++-------------------- + 1 file changed, 22 insertions(+), 20 deletions(-) + +diff --git src/gpart.c src/gpart.c +index 8555f66..bd3806a 100644 +--- src/gpart.c ++++ src/gpart.c +@@ -13,7 +13,7 @@ + * Modified: 11.06.1999 + * Handle disk read errors. + * Minor fixes. +- * ++ * + * 29.06.1999 + * Made every disk read/write buffer aligned to pagesize. + * +@@ -21,7 +21,7 @@ + * Default scan increment now 's'. + * Extended ptbl boundary condition now depends on scan + * increment. +- * ++ * + * 26.02.2000 + * Default scan increment 'h' again. + * Fixed faulty head boundary condition. +@@ -871,7 +871,7 @@ static void add_guessed_p(disk_desc *d,dos_part_entry *p,int cnt) + gpt = d->d_gl = (dos_guessed_pt *)alloc(sizeof(dos_guessed_pt)); + else + { +- for (gpt = d->d_gl; gpt->g_next; gpt = gpt->g_next) ++ for (gpt = d->d_gl; gpt->g_next; gpt = gpt->g_next) + ; + gpt->g_next = (dos_guessed_pt *)alloc(sizeof(dos_guessed_pt)); + gpt = gpt->g_next; +@@ -999,15 +999,18 @@ static void do_guess_loop(disk_desc *d) + pr(MSG,DM_STARTSCAN); + + scanloop: +- while ((rd = bread(d->d_fd,d->d_sbuf,d->d_ssize,nsecs)) == bsize) +- { +- int mod, have_ext = 0; +- g_module *bg; +- s64_t sz, ofs; +- +- d->d_nsb += incr; noffset = 0; +- ofs = d->d_nsb; s2mb(d,ofs); +- if (maxsec && (d->d_nsb > maxsec)) break; ++ while ((rd = bread(d->d_fd, d->d_sbuf, d->d_ssize, nsecs)) == bsize) { ++ int mod, have_ext = 0; ++ g_module *bg; ++ s64_t sz, ofs, fpos; ++ ++ d->d_nsb += incr; ++ noffset = 0; ++ ofs = d->d_nsb; ++ s2mb(d, ofs); ++ fpos = d->d_nsb * d->d_ssize + bsize; ++ if (maxsec && (d->d_nsb > maxsec)) ++ break; + + /* + * reset modules +@@ -1026,15 +1029,14 @@ guessit: + /* + * because a gmodule is allowed to seek on + * d->d_fd the current file position must be +- * saved. ++ * restored after calling it. + */ + +- memset(&m->m_part,0,sizeof(dos_part_entry)); +- m->m_guess = GM_NO; l64opush(d->d_fd); +- if ((*m->m_gfun)(d,m) && (m->m_guess * m->m_weight >= GM_PERHAPS)) ++ memset(&m->m_part, 0, sizeof(dos_part_entry)); ++ m->m_guess = GM_NO; ++ if ((*m->m_gfun)(d, m) && (m->m_guess * m->m_weight >= GM_PERHAPS)) + guesses[mod++] = m; +- if ((sz = l64opop(d->d_fd)) != l64tell(d->d_fd)) +- l64seek(d->d_fd,sz,SEEK_SET); ++ l64seek(d->d_fd, fpos, SEEK_SET); + } + + /* +@@ -1288,7 +1290,7 @@ static void write_primary_ptbl(disk_desc *d,char *dev) + { + if ((n = number_or_quit(DM_ACTWHICHPART,1,NDOSPARTS)) < 0) + break; +- if ((n >= 1) && (n <= NDOSPARTS) && ++ if ((n >= 1) && (n <= NDOSPARTS) && + get_part_type(d->d_gpt.t_parts[n].p_typ)) + { + d->d_gpt.t_parts[n - 1].p_flag = DOSPARTACTIVE; +@@ -1571,7 +1573,7 @@ static int check_partition_list(disk_desc *d) + if (gp->g_orph) pr(MSG,PM_G_ORPHANED); + if (gp->g_prim) pr(MSG,PM_G_PRIMARY); + if (gp->g_log) pr(MSG,PM_G_LOGICAL); +- pr(MSG,"\n"); ++ pr(MSG,"\n"); + if (f_verbose > 1) + print_partition(d,p,gp->g_log ? 1 : 0,0); + } +-- +2.24.0 + diff --git a/srcpkgs/gpart/patches/0003-gpart-use-posix_fadvise-to-increase-reading-speed.patch b/srcpkgs/gpart/patches/0003-gpart-use-posix_fadvise-to-increase-reading-speed.patch new file mode 100644 index 0000000000..c562e5a560 --- /dev/null +++ b/srcpkgs/gpart/patches/0003-gpart-use-posix_fadvise-to-increase-reading-speed.patch @@ -0,0 +1,42 @@ +From b01b124b36f81a76d38eb0169e6d279a777646c9 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 19 Nov 2015 23:24:43 +0100 +Subject: [PATCH 3/5] gpart: use posix_fadvise to increase reading speed + +Use fadvise to tell the OS to try readahead. +--- + configure.ac | 2 +- + src/gpart.c | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git configure.ac configure.ac +index 6eca1de..21dfc00 100644 +--- configure.ac ++++ configure.ac +@@ -26,7 +26,7 @@ AC_TYPE_UINT8_T + + # Checks for library functions. + AC_FUNC_MALLOC +-AC_CHECK_FUNCS([getpagesize memset strchr strdup strerror strtoul]) ++AC_CHECK_FUNCS([getpagesize memset strchr strdup strerror strtoul posix_fadvise]) + + # Configure system services. + AC_SYS_LARGEFILE +diff --git src/gpart.c src/gpart.c +index bd3806a..63b36a5 100644 +--- src/gpart.c ++++ src/gpart.c +@@ -949,6 +949,10 @@ static void do_guess_loop(disk_desc *d) + if ((d->d_fd = open(d->d_dev,O_RDONLY)) == -1) + pr(FATAL,EM_OPENFAIL,d->d_dev,strerror(errno)); + ++#if HAVE_POSIX_FADVISE ++ posix_fadvise(d->d_fd, 0, 0, POSIX_FADV_SEQUENTIAL); ++ posix_fadvise(d->d_fd, 0, 0, POSIX_FADV_WILLNEED); ++#endif /* HAVE_POSIX_FADVISE */ + /* + * initialize modules. Each should return the minimum + * size in bytes it wants to receive for a test. +-- +2.24.0 + diff --git a/srcpkgs/gpart/patches/0004-Speed-up-by-reading-larger-chunks.patch b/srcpkgs/gpart/patches/0004-Speed-up-by-reading-larger-chunks.patch new file mode 100644 index 0000000000..f83932c323 --- /dev/null +++ b/srcpkgs/gpart/patches/0004-Speed-up-by-reading-larger-chunks.patch @@ -0,0 +1,54 @@ +From d56778515e88e8fd5821b49850006962fe81b18d Mon Sep 17 00:00:00 2001 +From: Baruch Even +Date: Wed, 25 Nov 2015 08:58:10 +0200 +Subject: [PATCH 4/5] Speed up by reading larger chunks + +Based on work initiated by mwilck +--- + src/gpart.c | 27 ++++++++++++++++----------- + 1 file changed, 16 insertions(+), 11 deletions(-) + +diff --git src/gpart.c src/gpart.c +index 63b36a5..d530547 100644 +--- src/gpart.c ++++ src/gpart.c +@@ -163,20 +163,25 @@ byte_t *alloc(ssize_t s) + + ssize_t bread(int fd,byte_t *buf,size_t ssize,size_t nsecs) + { +- ssize_t cs = 0, nr = 0; +- +- for ( ; nsecs > 0; nsecs--) +- { +- if ((nr = read(fd,buf,ssize)) == -1) +- { ++ const size_t total = ssize * nsecs; ++ size_t read_bytes = 0; ++ ++ while (read_bytes < total) { ++ ssize_t ret = read(fd, buf + read_bytes, total - read_bytes); ++ if (ret > 0) ++ read_bytes += ret; ++ else if (ret == 0) { ++ return read_bytes; ++ } else { ++ // ret < 0, an error case ++ if (errno == EINTR) ++ continue; // Rogue signal interruption, retry + berrno = errno; +- return ((cs == 0) ? -1 : cs); +- } +- cs += nr; buf += nr; +- if (nr < ssize) + break; ++ } + } +- return (cs); ++ ++ return read_bytes ? read_bytes : -1; + } + + +-- +2.24.0 + diff --git a/srcpkgs/gpart/patches/0005-Add-LVM2-and-btrfs-to-list-of-supported-modules.patch b/srcpkgs/gpart/patches/0005-Add-LVM2-and-btrfs-to-list-of-supported-modules.patch new file mode 100644 index 0000000000..cc7c6d76bf --- /dev/null +++ b/srcpkgs/gpart/patches/0005-Add-LVM2-and-btrfs-to-list-of-supported-modules.patch @@ -0,0 +1,26 @@ +From 1bf2faf1340d4ae946a1f0d1aecc2ddc4b79c4bc Mon Sep 17 00:00:00 2001 +From: Baruch Even +Date: Wed, 25 Nov 2015 08:17:17 +0200 +Subject: [PATCH 5/5] Add LVM2 and btrfs to list of supported modules + +--- + README.md | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git README.md README.md +index 7cd3e2d..330821b 100644 +--- README.md ++++ README.md +@@ -41,7 +41,8 @@ See file *INSTALL*. + qnx4 | 0x4F | QNX 4.x + beos | 0xEB | BeOS fs + xfs | 0x83 | SGI XFS filesystem +- ++ btrfs | 0x83 | BtrFS ++ LVM2 | 0x8E | LVM2 + + + ## Guessing modules +-- +2.24.0 + diff --git a/srcpkgs/gpart/template b/srcpkgs/gpart/template index 23b20483dc..d222fbf9a7 100644 --- a/srcpkgs/gpart/template +++ b/srcpkgs/gpart/template @@ -1,21 +1,15 @@ # Template file for 'gpart' pkgname=gpart version=0.3 -revision=3 +revision=4 build_style=gnu-configure hostmakedepends="automake" short_desc="Partition table rescue/guessing tool" maintainer="Orphaned " license="GPL-2.0-or-later" homepage="https://github.com/baruch/gpart" -distfiles="https://github.com/baruch/gpart/archive/${version}.tar.gz - https://github.com/ndowens/voidpatches/archive/gpart-patches.tar.gz" -checksum="ec56d12ec9ffdb9877c12692ea6e51620b1ae44473d3d253b27fc31ed9ebb4dd - ac68a5275d878623add392fc6a68913735e6cfbed5a6c49fcbe48105f88b97eb" - - post_extract() { - patch -p0 < ../voidpatches-gpart-patches/0004-Real-fix-for-crash.patch - } +distfiles="https://github.com/baruch/gpart/archive/${version}.tar.gz" +checksum=ec56d12ec9ffdb9877c12692ea6e51620b1ae44473d3d253b27fc31ed9ebb4dd pre_configure() { autoreconf -fi