svn commit: r229301 - in stable/9: sbin/geom/class/raid
sys/geom/raid
Alexander Motin
mav at FreeBSD.org
Mon Jan 2 17:56:46 UTC 2012
Author: mav
Date: Mon Jan 2 17:56:45 2012
New Revision: 229301
URL: http://svn.freebsd.org/changeset/base/229301
Log:
MFC r226816:
Clarify disks/volumes above 2TiB support in geom_raid:
- add support for volumes above 2TiB with Promise metadata format;
- enforse and document other limitations:
- Intel and Promise metadata formats do not support disks above 2TiB;
- NVIDIA metadata format does not support volumes above 2TiB.
Sponsored by: iXsystems, Inc.
Modified:
stable/9/sbin/geom/class/raid/graid.8
stable/9/sys/geom/raid/md_intel.c
stable/9/sys/geom/raid/md_nvidia.c
stable/9/sys/geom/raid/md_promise.c
Directory Properties:
stable/9/sbin/geom/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
Modified: stable/9/sbin/geom/class/raid/graid.8
==============================================================================
--- stable/9/sbin/geom/class/raid/graid.8 Mon Jan 2 17:40:20 2012 (r229300)
+++ stable/9/sbin/geom/class/raid/graid.8 Mon Jan 2 17:56:45 2012 (r229301)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 22, 2011
+.Dd October 26, 2011
.Dt GRAID 8
.Os
.Sh NAME
@@ -250,6 +250,9 @@ If you started migration using BIOS or i
complete it there.
Do not run GEOM RAID class on migrating volumes under pain of possible data
corruption!
+.Sh 2TiB BARRIERS
+Intel and Promise metadata formats do not support disks above 2TiB.
+NVIDIA metadata format does not support volumes above 2TiB.
.Sh EXIT STATUS
Exit status is 0 on success, and non-zero if the command fails.
.Sh SEE ALSO
Modified: stable/9/sys/geom/raid/md_intel.c
==============================================================================
--- stable/9/sys/geom/raid/md_intel.c Mon Jan 2 17:40:20 2012 (r229300)
+++ stable/9/sys/geom/raid/md_intel.c Mon Jan 2 17:56:45 2012 (r229301)
@@ -1172,15 +1172,18 @@ g_raid_md_taste_intel(struct g_raid_md_o
g_access(cp, -1, 0, 0);
if (meta == NULL) {
if (g_raid_aggressive_spare) {
- if (vendor == 0x8086) {
+ if (vendor != 0x8086) {
+ G_RAID_DEBUG(1,
+ "Intel vendor mismatch 0x%04x != 0x8086",
+ vendor);
+ } else if (pp->mediasize / pp->sectorsize > UINT32_MAX) {
+ G_RAID_DEBUG(1,
+ "Intel disk '%s' is too big.", pp->name);
+ } else {
G_RAID_DEBUG(1,
"No Intel metadata, forcing spare.");
spare = 2;
goto search;
- } else {
- G_RAID_DEBUG(1,
- "Intel vendor mismatch 0x%04x != 0x8086",
- vendor);
}
}
return (G_RAID_MD_TASTE_FAIL);
@@ -1194,9 +1197,9 @@ g_raid_md_taste_intel(struct g_raid_md_o
}
if (meta->disk[disk_pos].sectors !=
(pp->mediasize / pp->sectorsize)) {
- G_RAID_DEBUG(1, "Intel size mismatch %u != %u",
- meta->disk[disk_pos].sectors,
- (u_int)(pp->mediasize / pp->sectorsize));
+ G_RAID_DEBUG(1, "Intel size mismatch %ju != %ju",
+ (off_t)meta->disk[disk_pos].sectors,
+ (off_t)(pp->mediasize / pp->sectorsize));
goto fail1;
}
@@ -1449,6 +1452,13 @@ g_raid_md_ctl_intel(struct g_raid_md_obj
cp->private = disk;
g_topology_unlock();
+ if (pp->mediasize / pp->sectorsize > UINT32_MAX) {
+ gctl_error(req,
+ "Disk '%s' is too big.", diskname);
+ error = -8;
+ break;
+ }
+
error = g_raid_md_get_label(cp,
&pd->pd_disk_meta.serial[0], INTEL_SERIAL_LEN);
if (error != 0) {
@@ -1940,6 +1950,14 @@ g_raid_md_ctl_intel(struct g_raid_md_obj
pp = cp->provider;
g_topology_unlock();
+ if (pp->mediasize / pp->sectorsize > UINT32_MAX) {
+ gctl_error(req,
+ "Disk '%s' is too big.", diskname);
+ g_raid_kill_consumer(sc, cp);
+ error = -8;
+ break;
+ }
+
/* Read disk serial. */
error = g_raid_md_get_label(cp,
&serial[0], INTEL_SERIAL_LEN);
Modified: stable/9/sys/geom/raid/md_nvidia.c
==============================================================================
--- stable/9/sys/geom/raid/md_nvidia.c Mon Jan 2 17:40:20 2012 (r229300)
+++ stable/9/sys/geom/raid/md_nvidia.c Mon Jan 2 17:56:45 2012 (r229301)
@@ -1033,7 +1033,7 @@ g_raid_md_ctl_nvidia(struct g_raid_md_ob
char arg[16];
const char *verb, *volname, *levelname, *diskname;
int *nargs, *force;
- off_t size, sectorsize, strip;
+ off_t size, sectorsize, strip, volsize;
intmax_t *sizearg, *striparg;
int numdisks, i, len, level, qual, update;
int error;
@@ -1182,7 +1182,20 @@ g_raid_md_ctl_nvidia(struct g_raid_md_ob
gctl_error(req, "Size too small.");
return (-13);
}
- if (size > 0xffffffffffffllu * sectorsize) {
+
+ if (level == G_RAID_VOLUME_RL_RAID0 ||
+ level == G_RAID_VOLUME_RL_CONCAT ||
+ level == G_RAID_VOLUME_RL_SINGLE)
+ volsize = size * numdisks;
+ else if (level == G_RAID_VOLUME_RL_RAID1)
+ volsize = size;
+ else if (level == G_RAID_VOLUME_RL_RAID5)
+ volsize = size * (numdisks - 1);
+ else { /* RAID1E */
+ volsize = ((size * numdisks) / strip / 2) *
+ strip;
+ }
+ if (volsize > 0xffffffffllu * sectorsize) {
gctl_error(req, "Size too big.");
return (-14);
}
@@ -1196,18 +1209,7 @@ g_raid_md_ctl_nvidia(struct g_raid_md_ob
vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_NONE;
vol->v_strip_size = strip;
vol->v_disks_count = numdisks;
- if (level == G_RAID_VOLUME_RL_RAID0 ||
- level == G_RAID_VOLUME_RL_CONCAT ||
- level == G_RAID_VOLUME_RL_SINGLE)
- vol->v_mediasize = size * numdisks;
- else if (level == G_RAID_VOLUME_RL_RAID1)
- vol->v_mediasize = size;
- else if (level == G_RAID_VOLUME_RL_RAID5)
- vol->v_mediasize = size * (numdisks - 1);
- else { /* RAID1E */
- vol->v_mediasize = ((size * numdisks) / strip / 2) *
- strip;
- }
+ vol->v_mediasize = volsize;
vol->v_sectorsize = sectorsize;
g_raid_start_volume(vol);
Modified: stable/9/sys/geom/raid/md_promise.c
==============================================================================
--- stable/9/sys/geom/raid/md_promise.c Mon Jan 2 17:40:20 2012 (r229300)
+++ stable/9/sys/geom/raid/md_promise.c Mon Jan 2 17:56:45 2012 (r229301)
@@ -121,7 +121,8 @@ struct promise_raid_conf {
uint64_t rebuild_lba64; /* Per-volume rebuild position. */
uint32_t magic_4;
uint32_t magic_5;
- uint32_t filler3[325];
+ uint32_t total_sectors_high;
+ uint32_t filler3[324];
uint32_t checksum;
} __packed;
@@ -213,6 +214,7 @@ g_raid_md_promise_print(struct promise_r
printf("rebuild_lba64 %ju\n", meta->rebuild_lba64);
printf("magic_4 0x%08x\n", meta->magic_4);
printf("magic_5 0x%08x\n", meta->magic_5);
+ printf("total_sectors_high 0x%08x\n", meta->total_sectors_high);
printf("=================================================\n");
}
@@ -867,6 +869,9 @@ g_raid_md_promise_start(struct g_raid_vo
vol->v_strip_size = 512 << meta->stripe_shift; //ZZZ
vol->v_disks_count = meta->total_disks;
vol->v_mediasize = (off_t)meta->total_sectors * 512; //ZZZ
+ if (meta->total_sectors_high < 256) /* If value looks sane. */
+ vol->v_mediasize |=
+ ((off_t)meta->total_sectors_high << 32) * 512; //ZZZ
vol->v_sectorsize = 512; //ZZZ
for (i = 0; i < vol->v_disks_count; i++) {
sd = &vol->v_subdisks[i];
@@ -1318,6 +1323,13 @@ g_raid_md_ctl_promise(struct g_raid_md_o
cp->private = disk;
g_topology_unlock();
+ if (pp->mediasize / pp->sectorsize > UINT32_MAX) {
+ gctl_error(req,
+ "Disk '%s' is too big.", diskname);
+ error = -8;
+ break;
+ }
+
/* Read kernel dumping information. */
disk->d_kd.offset = 0;
disk->d_kd.length = OFF_MAX;
@@ -1609,8 +1621,17 @@ g_raid_md_ctl_promise(struct g_raid_md_o
error = -4;
break;
}
+ pp = cp->provider;
g_topology_unlock();
+ if (pp->mediasize / pp->sectorsize > UINT32_MAX) {
+ gctl_error(req,
+ "Disk '%s' is too big.", diskname);
+ g_raid_kill_consumer(sc, cp);
+ error = -8;
+ break;
+ }
+
pd = malloc(sizeof(*pd), M_MD_PROMISE, M_WAITOK | M_ZERO);
disk = g_raid_create_disk(sc);
@@ -1716,6 +1737,8 @@ g_raid_md_write_promise(struct g_raid_md
meta->array_width /= 2;
meta->array_number = vol->v_global_id;
meta->total_sectors = vol->v_mediasize / vol->v_sectorsize;
+ meta->total_sectors_high =
+ (vol->v_mediasize / vol->v_sectorsize) >> 32;
meta->cylinders = meta->total_sectors / (255 * 63) - 1;
meta->heads = 254;
meta->sectors = 63;
More information about the svn-src-stable-9
mailing list