diff options
author | pjd <pjd@FreeBSD.org> | 2004-06-16 10:44:26 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2004-06-16 10:44:26 +0000 |
commit | 089ffc2ca6b316d9b06111eb3478dad24cd92714 (patch) | |
tree | 76ec01de1f590f8f348bf1bb889b07c272ac9009 /sbin | |
parent | 32bf9d060d0e1f36f42f99717c0857e4f9ab12c4 (diff) | |
download | FreeBSD-src-089ffc2ca6b316d9b06111eb3478dad24cd92714.zip FreeBSD-src-089ffc2ca6b316d9b06111eb3478dad24cd92714.tar.gz |
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.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/geom/misc/subr.c | 76 | ||||
-rw-r--r-- | 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 9d72e34..ae639b7 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 487f3db..f88af01 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); |