summaryrefslogtreecommitdiffstats
path: root/sbin/geom/misc
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2004-06-16 10:44:26 +0000
committerpjd <pjd@FreeBSD.org>2004-06-16 10:44:26 +0000
commit089ffc2ca6b316d9b06111eb3478dad24cd92714 (patch)
tree76ec01de1f590f8f348bf1bb889b07c272ac9009 /sbin/geom/misc
parent32bf9d060d0e1f36f42f99717c0857e4f9ab12c4 (diff)
downloadFreeBSD-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/geom/misc')
-rw-r--r--sbin/geom/misc/subr.c76
-rw-r--r--sbin/geom/misc/subr.h5
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, &sectorsize) < 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, &sectorsize) < 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, &sectorsize) < 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);
OpenPOWER on IntegriCloud