From owner-svn-src-stable@FreeBSD.ORG Mon Jan 2 17:56:46 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 87EA3106564A; Mon, 2 Jan 2012 17:56:46 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 74ECA8FC0C; Mon, 2 Jan 2012 17:56:46 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q02Huk59078726; Mon, 2 Jan 2012 17:56:46 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q02HukTK078721; Mon, 2 Jan 2012 17:56:46 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201201021756.q02HukTK078721@svn.freebsd.org> From: Alexander Motin Date: Mon, 2 Jan 2012 17:56:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r229301 - in stable/9: sbin/geom/class/raid sys/geom/raid X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Jan 2012 17:56:46 -0000 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;