From 09cc9ab63d0f50d107a03390b70dfdfbfe6aa363 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Wed, 16 Jun 2004 10:44:26 +0000 Subject: [PATCH] Implement 3 new functions: - g_lcm() - calculates Least Common Multiple of two given values, it is helpful when we need to find sector size for provider which is based on disks with different sector size; - g_get_mediasize() - returns media size of given provider; - g_get_sectorsize() - returns sector size of given provider; Those function aren't used now, but are used by geom_mirror which will be committed soon. --- sbin/geom/misc/subr.c | 76 ++++++++++++++++++++++++++++++++++++++++--- sbin/geom/misc/subr.h | 5 +++ 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/sbin/geom/misc/subr.c b/sbin/geom/misc/subr.c index 9d72e3483442..ae639b7a9017 100644 --- a/sbin/geom/misc/subr.c +++ b/sbin/geom/misc/subr.c @@ -69,6 +69,70 @@ pathgen(const char *name, char *path, size_t size) strlcpy(path, name, size); } +/* + * Greatest Common Divisor. + */ +static unsigned +gcd(unsigned a, unsigned b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +unsigned +g_lcm(unsigned a, unsigned b) +{ + + return ((a * b) / gcd(a, b)); +} + +off_t +g_get_mediasize(const char *name) +{ + char path[MAXPATHLEN]; + off_t mediasize; + int fd; + + pathgen(name, path, sizeof(path)); + fd = open(path, O_RDONLY); + if (fd == -1) + return (0); + if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) { + close(fd); + return (0); + } + close(fd); + return (mediasize); +} + +unsigned +g_get_sectorsize(const char *name) +{ + char path[MAXPATHLEN]; + unsigned sectorsize; + int fd; + + pathgen(name, path, sizeof(path)); + fd = open(path, O_RDONLY); + if (fd == -1) + return (0); + if (ioctl(fd, DIOCGSECTORSIZE, §orsize) < 0) { + close(fd); + return (0); + } + close(fd); + return (sectorsize); +} + int g_metadata_store(const char *name, u_char *md, size_t size) { @@ -85,11 +149,13 @@ g_metadata_store(const char *name, u_char *md, size_t size) fd = open(path, O_WRONLY); if (fd == -1) return (errno); - if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) { + mediasize = g_get_mediasize(name); + if (mediasize == 0) { error = errno; goto out; } - if (ioctl(fd, DIOCGSECTORSIZE, §orsize) < 0) { + sectorsize = g_get_sectorsize(name); + if (sectorsize == 0) { error = errno; goto out; } @@ -129,11 +195,13 @@ g_metadata_clear(const char *name, const char *magic) fd = open(path, O_RDWR); if (fd == -1) return (errno); - if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) { + mediasize = g_get_mediasize(name); + if (mediasize == 0) { error = errno; goto out; } - if (ioctl(fd, DIOCGSECTORSIZE, §orsize) < 0) { + sectorsize = g_get_sectorsize(name); + if (sectorsize == 0) { error = errno; goto out; } diff --git a/sbin/geom/misc/subr.h b/sbin/geom/misc/subr.h index 487f3db5ceb8..f88af01bddb2 100644 --- a/sbin/geom/misc/subr.h +++ b/sbin/geom/misc/subr.h @@ -28,6 +28,11 @@ #ifndef _SUBR_H_ #define _SUBR_H_ +unsigned g_lcm(unsigned a, unsigned b); + +off_t g_get_mediasize(const char *name); +unsigned g_get_sectorsize(const char *name); + int g_metadata_store(const char *name, u_char *md, size_t size); int g_metadata_clear(const char *name, const char *magic);