NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/39552: ataraid(4): Intel MatrixRAID multiple volumes support
The following reply was made to PR kern/39552; it has been noted by GNATS.
From: Juan RP <xtraeme%gmail.com@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: kern/39552: ataraid(4): Intel MatrixRAID multiple volumes
support
Date: Mon, 15 Sep 2008 14:32:35 +0200
Here's the patch:
Index: share/man/man4/ataraid.4
===================================================================
RCS file: /cvsroot/src/share/man/man4/ataraid.4,v
retrieving revision 1.13
diff -b -u -p -r1.13 ataraid.4
--- share/man/man4/ataraid.4 15 Sep 2008 11:44:50 -0000 1.13
+++ share/man/man4/ataraid.4 15 Sep 2008 12:11:44 -0000
@@ -92,7 +92,3 @@ state, and it does not do the right thin
.Pp
At least part of the reason for this is that the publically-available
information on these formats is quite limited.
-.Pp
-The support with Intel MatrixRAID controller is incomplete, and only
-the first volume found will be used.
-This will be fixed in future revisions of this driver.
Index: sys/dev/ata/ata_raid_intel.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_raid_intel.c,v
retrieving revision 1.2
diff -b -u -p -r1.2 ata_raid_intel.c
--- sys/dev/ata/ata_raid_intel.c 15 Sep 2008 11:44:50 -0000 1.2
+++ sys/dev/ata/ata_raid_intel.c 15 Sep 2008 12:11:44 -0000
@@ -140,7 +140,7 @@ ata_raid_read_config_intel(struct wd_sof
struct vnode *vp;
uint32_t checksum, *ptr;
static int curdrive;
- int bmajor, count, error = 0;
+ int bmajor, count, curvol = 0, error = 0;
char *tmp;
dev_t dev;
@@ -203,14 +203,11 @@ ata_raid_read_config_intel(struct wd_sof
/* This one points to the first volume */
map = (struct intel_raid_mapping *)&info->disk[info->total_disks];
+findvol:
/*
* Lookup or allocate a new array info structure for this array.
- *
- * TODO:
- * We only look at the first volume. Need to solve a few issues before
- * multiple volumes are working correctly.
*/
- aai = ata_raid_get_array_info(ATA_RAID_TYPE_INTEL, 0);
+ aai = ata_raid_get_array_info(ATA_RAID_TYPE_INTEL, curvol);
/* Fill in array info */
aai->aai_generation = info->generation;
@@ -244,7 +241,7 @@ ata_raid_read_config_intel(struct wd_sof
aai->aai_type = ATA_RAID_TYPE_INTEL;
aai->aai_capacity = map->total_sectors;
- aai->aai_interleave = map->stripe_sectors;
+ aai->aai_interleave = map->stripe_sectors / 2;
aai->aai_ndisks = map->total_disks;
aai->aai_heads = 255;
aai->aai_sectors = 63;
@@ -274,6 +271,16 @@ ata_raid_read_config_intel(struct wd_sof
adi->adi_dev = sc->sc_dev;
adi->adi_sectors = info->disk[curdrive].sectors;
adi->adi_compsize = adi->adi_sectors - aai->aai_reserved;
+ /*
+ * Check if that is the only volume, otherwise repeat
+ * the process to find more.
+ */
+ if ((curvol + 1) < info->total_volumes) {
+ curvol++;
+ map = (struct intel_raid_mapping *)
+ &map->disk_idx[map->total_disks];
+ goto findvol;
+ }
curdrive++;
}
Index: sys/dev/ata/ata_raid_subr.c
===================================================================
RCS file: sys/dev/ata/ata_raid_subr.c
diff -N sys/dev/ata/ata_raid_subr.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/dev/ata/ata_raid_subr.c 15 Sep 2008 12:11:44 -0000
@@ -0,0 +1,101 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2008 Juan Romero Pardines.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/dkio.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/fcntl.h>
+#include <sys/vnode.h>
+#include <sys/kauth.h>
+#include <sys/kmem.h>
+
+#include <dev/ata/ata_raidvar.h>
+
+struct ataraid_disk_vnode {
+ struct ataraid_disk_info *adv_adi;
+ struct vnode *adv_vnode;
+ SLIST_ENTRY(ataraid_disk_vnode) adv_next;
+};
+
+static SLIST_HEAD(, ataraid_disk_vnode) ataraid_disk_vnode_list =
+ SLIST_HEAD_INITIALIZER(ataraid_disk_vnode_list);
+
+/*
+ * Finds the RAW_PART vnode of the block device associated with a component
+ * by looking at the singly linked list; otherwise creates, opens and
+ * returns the vnode to the caller.
+ */
+struct vnode *
+ata_raid_disk_vnode_find(struct ataraid_disk_info *adi)
+{
+ struct ataraid_disk_vnode *adv = NULL;
+ struct vnode *vp = NULL;
+ device_t devlist;
+ int bmajor, error = 0;
+ dev_t dev;
+
+ SLIST_FOREACH(adv, &ataraid_disk_vnode_list, adv_next) {
+ devlist = adv->adv_adi->adi_dev;
+ if (strcmp(device_xname(devlist),
+ device_xname(adi->adi_dev)) == 0)
+ return adv->adv_vnode;
+ }
+
+ adv = NULL;
+ adv = kmem_zalloc(sizeof(struct ataraid_disk_vnode), KM_SLEEP);
+
+ bmajor = devsw_name2blk(device_xname(adi->adi_dev), NULL, 0);
+ dev = MAKEDISKDEV(bmajor, device_unit(adi->adi_dev), RAW_PART);
+
+ error = bdevvp(dev, &vp);
+ if (error) {
+ kmem_free(adv, sizeof(struct ataraid_disk_vnode));
+ return NULL;
+ }
+ error = VOP_OPEN(vp, FREAD|FWRITE, NOCRED);
+ if (error) {
+ vput(vp);
+ kmem_free(adv, sizeof(struct ataraid_disk_vnode));
+ return NULL;
+ }
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ VOP_UNLOCK(vp, 0);
+
+ adv->adv_adi = adi;
+ adv->adv_vnode = vp;
+
+ SLIST_INSERT_HEAD(&ataraid_disk_vnode_list, adv, adv_next);
+
+ return adv->adv_vnode;
+}
Index: sys/dev/ata/ata_raidvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_raidvar.h,v
retrieving revision 1.9
diff -b -u -p -r1.9 ata_raidvar.h
--- sys/dev/ata/ata_raidvar.h 15 Sep 2008 11:44:50 -0000 1.9
+++ sys/dev/ata/ata_raidvar.h 15 Sep 2008 12:11:45 -0000
@@ -126,6 +126,8 @@ struct ataraid_array_info *ata_raid_get_
int ata_raid_config_block_rw(struct vnode *, daddr_t, void *,
size_t, int);
+struct vnode *ata_raid_disk_vnode_find(struct ataraid_disk_info *);
+
/* Promise RAID support */
int ata_raid_read_config_promise(struct wd_softc *);
Index: sys/dev/ata/files.ata
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/files.ata,v
retrieving revision 1.19
diff -b -u -p -r1.19 files.ata
--- sys/dev/ata/files.ata 11 Sep 2008 11:08:50 -0000 1.19
+++ sys/dev/ata/files.ata 15 Sep 2008 12:11:45 -0000
@@ -18,6 +18,7 @@ file dev/ata/ata.c (ata_hl | atapi) &
# ATA RAID configuration support
defpseudodev ataraid {[vendtype = -1], [unit = -1]}
file dev/ata/ata_raid.c ataraid needs-flag
+file dev/ata/ata_raid_subr.c ataraid
file dev/ata/ata_raid_promise.c ataraid
file dev/ata/ata_raid_adaptec.c ataraid
file dev/ata/ata_raid_nvidia.c ataraid
Index: sys/dev/ata/ld_ataraid.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ld_ataraid.c,v
retrieving revision 1.31
diff -b -u -p -r1.31 ld_ataraid.c
--- sys/dev/ata/ld_ataraid.c 15 Sep 2008 11:53:52 -0000 1.31
+++ sys/dev/ata/ld_ataraid.c 15 Sep 2008 12:11:45 -0000
@@ -143,6 +143,7 @@ ld_ataraid_attach(device_t parent, devic
struct ld_ataraid_softc *sc = device_private(self);
struct ld_softc *ld = &sc->sc_ld;
struct ataraid_array_info *aai = aux;
+ struct ataraid_disk_info *adi = NULL;
const char *level;
struct vnode *vp;
char unklev[32];
@@ -215,18 +216,9 @@ ld_ataraid_attach(device_t parent, devic
* Configure all the component disks.
*/
for (i = 0; i < aai->aai_ndisks; i++) {
- struct ataraid_disk_info *adi = &aai->aai_disks[i];
- int bmajor, error;
- dev_t dev;
-
- bmajor = devsw_name2blk(device_xname(adi->adi_dev), NULL, 0);
- dev = MAKEDISKDEV(bmajor, device_unit(adi->adi_dev), RAW_PART);
- error = bdevvp(dev, &vp);
- if (error)
- break;
- error = VOP_OPEN(vp, FREAD|FWRITE, NOCRED);
- if (error) {
- vput(vp);
+ adi = &aai->aai_disks[i];
+ vp = ata_raid_disk_vnode_find(adi);
+ if (vp == NULL) {
/*
* XXX This is bogus. We should just mark the
* XXX component as FAILED, and write-back new
@@ -234,8 +226,6 @@ ld_ataraid_attach(device_t parent, devic
*/
break;
}
-
- VOP_UNLOCK(vp, 0);
sc->sc_vnodes[i] = vp;
}
if (i == aai->aai_ndisks) {
Home |
Main Index |
Thread Index |
Old Index