[PATCH] dm store geometry

Allow drive geometry to be stored with a new DM_DEV_SET_GEOMETRY ioctl.
Device-mapper will now respond to HDIO_GETGEO.  If the geometry information is
not available, zero will be returned for all of the parameters.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Darrick J. Wong
2006-03-27 01:17:54 -08:00
committed by Linus Torvalds
parent 1134e5ae79
commit 3ac51e741a
5 changed files with 121 additions and 3 deletions
+51 -1
View File
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/dm-ioctl.h>
#include <linux/hdreg.h>
#include <asm/uaccess.h>
@@ -700,6 +701,54 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
return dm_hash_rename(param->name, new_name);
}
static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
{
int r = -EINVAL, x;
struct mapped_device *md;
struct hd_geometry geometry;
unsigned long indata[4];
char *geostr = (char *) param + param->data_start;
md = find_device(param);
if (!md)
return -ENXIO;
if (geostr < (char *) (param + 1) ||
invalid_str(geostr, (void *) param + param_size)) {
DMWARN("Invalid geometry supplied.");
goto out;
}
x = sscanf(geostr, "%lu %lu %lu %lu", indata,
indata + 1, indata + 2, indata + 3);
if (x != 4) {
DMWARN("Unable to interpret geometry settings.");
goto out;
}
if (indata[0] > 65535 || indata[1] > 255 ||
indata[2] > 255 || indata[3] > ULONG_MAX) {
DMWARN("Geometry exceeds range limits.");
goto out;
}
geometry.cylinders = indata[0];
geometry.heads = indata[1];
geometry.sectors = indata[2];
geometry.start = indata[3];
r = dm_set_geometry(md, &geometry);
if (!r)
r = __dev_status(md, param);
param->data_size = 0;
out:
dm_put(md);
return r;
}
static int do_suspend(struct dm_ioctl *param)
{
int r = 0;
@@ -1234,7 +1283,8 @@ static ioctl_fn lookup_ioctl(unsigned int cmd)
{DM_LIST_VERSIONS_CMD, list_versions},
{DM_TARGET_MSG_CMD, target_message}
{DM_TARGET_MSG_CMD, target_message},
{DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry}
};
return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;