From 8a534253bc52f453db21af02299efacd12f40fda Mon Sep 17 00:00:00 2001 From: =?utf8?q?Thomas=20Wei=C3=9Fschuh?= Date: Sat, 30 Sep 2023 23:59:44 +0200 Subject: [PATCH 1/1] libblkid: (probe) read data in chunks MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Weißschuh --- libblkid/src/blkidP.h | 1 + libblkid/src/probe.c | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h index a02df7eb6f..63d1946f9b 100644 --- a/libblkid/src/blkidP.h +++ b/libblkid/src/blkidP.h @@ -206,6 +206,7 @@ struct blkid_struct_probe int fd; /* device file descriptor */ uint64_t off; /* begin of data on the device */ uint64_t size; /* end of data on the device */ + uint64_t io_size; /* optimal size of IO */ dev_t devno; /* device number (st.st_rdev) */ dev_t disk_devno; /* devno of the whole-disk or 0 */ diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 24cbd1761b..552bed22c0 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -184,6 +184,7 @@ blkid_probe blkid_clone_probe(blkid_probe parent) pr->fd = parent->fd; pr->off = parent->off; pr->size = parent->size; + pr->io_size = parent->io_size; pr->devno = parent->devno; pr->disk_devno = parent->disk_devno; pr->blkssz = parent->blkssz; @@ -729,13 +730,21 @@ static int hide_buffer(blkid_probe pr, uint64_t off, uint64_t len) const unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len) { struct blkid_bufinfo *bf = NULL; - uint64_t real_off = pr->off + off; + uint64_t real_off, bias; + + bias = off % pr->io_size; + off -= bias; + len += bias; + if (len % pr->io_size) + len += pr->io_size - (len % pr->io_size); + + real_off = pr->off + off; /* DBG(BUFFER, ul_debug("\t>>>> off=%ju, real-off=%ju (probe <%ju..%ju>, len=%ju", off, real_off, pr->off, pr->off + pr->size, len)); */ - if (pr->size == 0) { + if (pr->size == 0 || pr->io_size == 0) { errno = EINVAL; return NULL; } @@ -788,7 +797,7 @@ const unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64 assert(bf->off + bf->len >= real_off + len); errno = 0; - return real_off ? bf->data + (real_off - bf->off) : bf->data; + return real_off ? bf->data + (real_off - bf->off + bias) : bf->data + bias; } /** @@ -953,6 +962,22 @@ failed: #endif +static uint64_t blkid_get_io_size(int fd) +{ + static const int ioctls[] = { BLKIOOPT, BLKIOMIN, BLKBSZGET }; + unsigned int s; + size_t i; + int r; + + for (i = 0; i < ARRAY_SIZE(ioctls); i++) { + r = ioctl(fd, ioctls[i], &s); + if (r == 0 && is_power_of_2(s) && s >= DEFAULT_SECTOR_SIZE) + return min(s, 1U << 16); + } + + return DEFAULT_SECTOR_SIZE; +} + /** * blkid_probe_set_device: * @pr: probe @@ -996,6 +1021,7 @@ int blkid_probe_set_device(blkid_probe pr, int fd, pr->fd = fd; pr->off = (uint64_t) off; pr->size = 0; + pr->io_size = DEFAULT_SECTOR_SIZE; pr->devno = 0; pr->disk_devno = 0; pr->mode = 0; @@ -1159,8 +1185,11 @@ int blkid_probe_set_device(blkid_probe pr, int fd, } # endif - DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%"PRIu64", size=%"PRIu64", zonesize=%"PRIu64, - pr->off, pr->size, pr->zone_size)); + if (S_ISBLK(sb.st_mode) && !is_floppy && !blkid_probe_is_tiny(pr)) + pr->io_size = blkid_get_io_size(fd); + + DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%"PRIu64", size=%"PRIu64", zonesize=%"PRIu64", iosize=%"PRIu64, + pr->off, pr->size, pr->zone_size, pr->io_size)); DBG(LOWPROBE, ul_debug("whole-disk: %s, regfile: %s", blkid_probe_is_wholedisk(pr) ?"YES" : "NO", S_ISREG(pr->mode) ? "YES" : "NO")); -- 2.39.5