summaryrefslogtreecommitdiffstats
path: root/sys/dev/vinum
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2002-10-05 03:44:00 +0000
committerrwatson <rwatson@FreeBSD.org>2002-10-05 03:44:00 +0000
commit722fc75788765602970e34ec0188aa8418139df0 (patch)
tree4f3b57d2125b5e908a875ca598e83230c3fd053d /sys/dev/vinum
parentfc6cf98e7909a70a0e94a4b1863730932292d105 (diff)
downloadFreeBSD-src-722fc75788765602970e34ec0188aa8418139df0.zip
FreeBSD-src-722fc75788765602970e34ec0188aa8418139df0.tar.gz
Get Vinum up and running with GEOM:
(1) Use namei() and devfs to discover devices rather than a hard-coded MAKEDEV implementation. Once rootfs is in place, this will allow Vinum to be used for the root file system partition. (2) Pass FREAD to device opens so that GEOM will return sector size rather than an error on attempts to read label data. (3) Avoid clobbering return values from close_drive() and masking this failure, resulting in a later divide by zero due to not having updated the Vinum-cached sector size. (4) Ignore failures from DIOCWLABEL as that appears not to be required in the GEOM environment. We've done testing in simple Vinum environments, but those with more complex environments might want to give this a spin in DP2 and make sure everything is up to speed. Fixes in collaboration with: iedowse Reviewed by: grog
Diffstat (limited to 'sys/dev/vinum')
-rw-r--r--sys/dev/vinum/vinumio.c107
1 files changed, 21 insertions, 86 deletions
diff --git a/sys/dev/vinum/vinumio.c b/sys/dev/vinum/vinumio.c
index d7e5c95..612f5ed 100644
--- a/sys/dev/vinum/vinumio.c
+++ b/sys/dev/vinum/vinumio.c
@@ -50,92 +50,25 @@ static int drivecmp(const void *va, const void *vb);
int
open_drive(struct drive *drive, struct thread *td, int verbose)
{
- int devmajor; /* major devs for disk device */
- int devminor; /* minor devs for disk device */
- int unit;
- char *dname;
+ struct nameidata nd;
struct cdevsw *dsw; /* pointer to cdevsw entry */
+ int error;
- if (bcmp(drive->devicename, "/dev/", 5)) /* device name doesn't start with /dev */
- return ENOENT; /* give up */
if (drive->flags & VF_OPEN) /* open already, */
return EBUSY; /* don't do it again */
- /*
- * Yes, Bruce, I know this is horrible, but we
- * don't have a root filesystem when we first
- * try to do this. If you can come up with a
- * better solution, I'd really like it. I'm
- * just putting it in now to add ammuntion to
- * moving the system to devfs.
- */
- dname = &drive->devicename[5];
- drive->dev = NULL; /* no device yet */
-
- /* Find the device */
- if (bcmp(dname, "ad", 2) == 0) /* IDE disk */
- devmajor = 116;
- else if (bcmp(dname, "wd", 2) == 0) /* IDE disk */
- devmajor = 3;
- else if (bcmp(dname, "da", 2) == 0)
- devmajor = 13;
- else if (bcmp(dname, "vn", 2) == 0)
- devmajor = 43;
- else if (bcmp(dname, "md", 2) == 0)
- devmajor = 95;
- else if (bcmp(dname, "ar", 2) == 0)
- devmajor = 157;
- else if (bcmp(dname, "amrd", 4) == 0) {
- devmajor = 133;
- dname += 2;
- } else if (bcmp(dname, "mlxd", 4) == 0) {
- devmajor = 131;
- dname += 2;
- } else if (bcmp(dname, "idad", 4) == 0) {
- devmajor = 109;
- dname += 2;
- } else if (bcmp(dname, "twed", 4) == 0) { /* 3ware raid */
- devmajor = 147;
- dname += 2;
- } else
- return ENODEV;
- dname += 2; /* point past */
-
- /*
- * Found the device. We can expect one of
- * two formats for the rest: a unit number,
- * then either a partition letter for the
- * compatiblity partition (e.g. h) or a
- * slice ID and partition (e.g. s2e).
- * Create a minor number for each of them.
- */
- unit = 0;
- while ((*dname >= '0') /* unit number */
- &&(*dname <= '9')) {
- unit = unit * 10 + *dname - '0';
- dname++;
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, drive->devicename,
+ curthread);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ if (!vn_isdisk(nd.ni_vp, &error)) {
+ NDFREE(&nd, 0);
+ return (error);
}
+ drive->dev = udev2dev(nd.ni_vp->v_rdev->si_udev, 0);
+ NDFREE(&nd, 0);
- if (*dname == 's') { /* slice */
- if (((dname[1] < '1') || (dname[1] > '4')) /* invalid slice */
- ||((dname[2] < 'a') || (dname[2] > 'h'))) /* or invalid partition */
- return ENODEV;
- devminor = ((unit & 31) << 3) /* unit */
- +(dname[2] - 'a') /* partition */
- +((dname[1] - '0' + 1) << 16) /* slice */
- +((unit & ~31) << 16); /* high-order unit bits */
- } else { /* compatibility partition */
- if ((*dname < 'a') || (*dname > 'h')) /* or invalid partition */
- return ENODEV;
- devminor = (*dname - 'a') /* partition */
- +((unit & 31) << 3) /* unit */
- +((unit & ~31) << 16); /* high-order unit bits */
- }
-
- if ((devminor & 7) == 2) /* partition c */
- return ENOTTY; /* not buying that */
-
- drive->dev = makedev(devmajor, devminor); /* find the device */
if (drive->dev == NULL) /* didn't find anything */
return ENODEV;
@@ -144,7 +77,7 @@ open_drive(struct drive *drive, struct thread *td, int verbose)
if (dsw == NULL)
drive->lasterror = ENOENT;
else
- drive->lasterror = (dsw->d_open) (drive->dev, FWRITE, 0, NULL);
+ drive->lasterror = (dsw->d_open) (drive->dev, FWRITE | FREAD, 0, NULL);
if (drive->lasterror != 0) { /* failed */
drive->state = drive_down; /* just force it down */
@@ -278,13 +211,17 @@ close_drive(struct drive *drive)
void
close_locked_drive(struct drive *drive)
{
+ int error;
+
/*
* If we can't access the drive, we can't flush
* the queues, which spec_close() will try to
* do. Get rid of them here first.
*/
- drive->lasterror = (*devsw(drive->dev)->d_close) (drive->dev, 0, 0, NULL);
+ error = (*devsw(drive->dev)->d_close) (drive->dev, 0, 0, NULL);
drive->flags &= ~VF_OPEN; /* no longer open */
+ if (drive->lasterror == 0)
+ drive->lasterror = error;
}
/*
@@ -678,20 +615,18 @@ daemon_save_config(void)
if ((drive->state != drive_unallocated)
&& (drive->state != drive_referenced)) { /* and it's a real drive */
wlabel_on = 1; /* enable writing the label */
- error = (*devsw(drive->dev)->d_ioctl) (drive->dev, /* make the label writeable */
+ (void) (*devsw(drive->dev)->d_ioctl) (drive->dev, /* make the label writeable */
DIOCWLABEL,
(caddr_t) & wlabel_on,
FWRITE,
curthread);
- if (error == 0)
- error = write_drive(drive, (char *) vhdr, VINUMHEADERLEN, VINUM_LABEL_OFFSET);
+ error = write_drive(drive, (char *) vhdr, VINUMHEADERLEN, VINUM_LABEL_OFFSET);
if (error == 0)
error = write_drive(drive, config, MAXCONFIG, VINUM_CONFIG_OFFSET); /* first config copy */
if (error == 0)
error = write_drive(drive, config, MAXCONFIG, VINUM_CONFIG_OFFSET + MAXCONFIG); /* second copy */
wlabel_on = 0; /* enable writing the label */
- if (error == 0)
- error = (*devsw(drive->dev)->d_ioctl) (drive->dev, /* make the label non-writeable again */
+ (void) (*devsw(drive->dev)->d_ioctl) (drive->dev, /* make the label non-writeable again */
DIOCWLABEL,
(caddr_t) & wlabel_on,
FWRITE,
OpenPOWER on IntegriCloud