xref: /onnv-gate/usr/src/lib/libadm/common/rdwr_vtoc.c (revision 7563:84ec90ffc3f7)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7563SPrasad.Singamsetty@Sun.COM  * Common Development and Distribution License (the "License").
6*7563SPrasad.Singamsetty@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*7563SPrasad.Singamsetty@Sun.COM 
220Sstevel@tonic-gate /*
23*7563SPrasad.Singamsetty@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*LINTLIBRARY*/
280Sstevel@tonic-gate 
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <stdio.h>
310Sstevel@tonic-gate #include <errno.h>
320Sstevel@tonic-gate #include <memory.h>
330Sstevel@tonic-gate #include <unistd.h>
340Sstevel@tonic-gate #include <sys/types.h>
350Sstevel@tonic-gate #include <sys/param.h>
360Sstevel@tonic-gate #include <sys/dkio.h>
370Sstevel@tonic-gate #include <sys/vtoc.h>
38*7563SPrasad.Singamsetty@Sun.COM #include <strings.h>
39*7563SPrasad.Singamsetty@Sun.COM #include <limits.h>
40*7563SPrasad.Singamsetty@Sun.COM 
41*7563SPrasad.Singamsetty@Sun.COM /*
42*7563SPrasad.Singamsetty@Sun.COM  * To copy each field of vtoc individually for copying extvtoc
43*7563SPrasad.Singamsetty@Sun.COM  * to 32 bit vtoc and vs.
44*7563SPrasad.Singamsetty@Sun.COM  * Currently bootinfo and timestamp are not really supported.
45*7563SPrasad.Singamsetty@Sun.COM  */
46*7563SPrasad.Singamsetty@Sun.COM 
47*7563SPrasad.Singamsetty@Sun.COM #define	libadm_vtoc_copy(vs, vd) \
48*7563SPrasad.Singamsetty@Sun.COM 	{							\
49*7563SPrasad.Singamsetty@Sun.COM 	int i;							\
50*7563SPrasad.Singamsetty@Sun.COM 	vd->v_bootinfo[0]	= (unsigned)vs->v_bootinfo[0];	\
51*7563SPrasad.Singamsetty@Sun.COM 	vd->v_bootinfo[1]	= (unsigned)vs->v_bootinfo[1];	\
52*7563SPrasad.Singamsetty@Sun.COM 	vd->v_bootinfo[2]	= (unsigned)vs->v_bootinfo[2];	\
53*7563SPrasad.Singamsetty@Sun.COM 	vd->v_sanity		= (unsigned)vs->v_sanity;	\
54*7563SPrasad.Singamsetty@Sun.COM 	vd->v_version		= (unsigned)vs->v_version;	\
55*7563SPrasad.Singamsetty@Sun.COM 	bcopy(vs->v_volume, vd->v_volume, LEN_DKL_VVOL);	\
56*7563SPrasad.Singamsetty@Sun.COM 	vd->v_sectorsz		= vs->v_sectorsz;		\
57*7563SPrasad.Singamsetty@Sun.COM 	vd->v_nparts		= vs->v_nparts;			\
58*7563SPrasad.Singamsetty@Sun.COM 	vd->v_version		= (unsigned)vs->v_version;	\
59*7563SPrasad.Singamsetty@Sun.COM 	for (i = 0; i < 10; i++)				\
60*7563SPrasad.Singamsetty@Sun.COM 		vd->v_reserved[i] = (unsigned)vs->v_reserved[i];\
61*7563SPrasad.Singamsetty@Sun.COM 	for (i = 0; i < V_NUMPAR; i++) {			\
62*7563SPrasad.Singamsetty@Sun.COM 		vd->v_part[i].p_tag = vs->v_part[i].p_tag;	\
63*7563SPrasad.Singamsetty@Sun.COM 		vd->v_part[i].p_flag = vs->v_part[i].p_flag;	\
64*7563SPrasad.Singamsetty@Sun.COM 		vd->v_part[i].p_start = (unsigned)vs->v_part[i].p_start;\
65*7563SPrasad.Singamsetty@Sun.COM 		vd->v_part[i].p_size = (unsigned)vs->v_part[i].p_size;	\
66*7563SPrasad.Singamsetty@Sun.COM 	}								\
67*7563SPrasad.Singamsetty@Sun.COM 	for (i = 0; i < V_NUMPAR; i++)					\
68*7563SPrasad.Singamsetty@Sun.COM 		if ((sizeof (vd->timestamp[i]) != sizeof (vs->timestamp[i])) &&\
69*7563SPrasad.Singamsetty@Sun.COM 		    (vs->timestamp[i] > INT32_MAX))			\
70*7563SPrasad.Singamsetty@Sun.COM 			vd->timestamp[i] = INT32_MAX;			\
71*7563SPrasad.Singamsetty@Sun.COM 		else							\
72*7563SPrasad.Singamsetty@Sun.COM 			vd->timestamp[i] = (unsigned)vs->timestamp[i];	\
73*7563SPrasad.Singamsetty@Sun.COM 	bcopy(vs->v_asciilabel, vd->v_asciilabel, LEN_DKL_ASCII);	\
74*7563SPrasad.Singamsetty@Sun.COM 	}
75*7563SPrasad.Singamsetty@Sun.COM 
760Sstevel@tonic-gate 
770Sstevel@tonic-gate /*
780Sstevel@tonic-gate  * Read VTOC - return partition number.
790Sstevel@tonic-gate  */
800Sstevel@tonic-gate int
read_vtoc(int fd,struct vtoc * vtoc)810Sstevel@tonic-gate read_vtoc(int fd, struct vtoc *vtoc)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate 	struct dk_cinfo		dki_info;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	/*
860Sstevel@tonic-gate 	 * Read the vtoc.
870Sstevel@tonic-gate 	 */
880Sstevel@tonic-gate 	if (ioctl(fd, DKIOCGVTOC, (caddr_t)vtoc) == -1) {
890Sstevel@tonic-gate 		switch (errno) {
900Sstevel@tonic-gate 		case EIO:
910Sstevel@tonic-gate 			return (VT_EIO);
920Sstevel@tonic-gate 		case EINVAL:
930Sstevel@tonic-gate 			return (VT_EINVAL);
940Sstevel@tonic-gate 		case ENOTSUP:
95*7563SPrasad.Singamsetty@Sun.COM 			/* GPT labeled or disk > 1TB with no extvtoc support */
960Sstevel@tonic-gate 			return (VT_ENOTSUP);
97*7563SPrasad.Singamsetty@Sun.COM 		case EOVERFLOW:
98*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EOVERFLOW);
990Sstevel@tonic-gate 		default:
1000Sstevel@tonic-gate 			return (VT_ERROR);
1010Sstevel@tonic-gate 		}
1020Sstevel@tonic-gate 	}
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	/*
1050Sstevel@tonic-gate 	 * Sanity-check the vtoc.
1060Sstevel@tonic-gate 	 */
1070Sstevel@tonic-gate 	if (vtoc->v_sanity != VTOC_SANE) {
1080Sstevel@tonic-gate 		return (VT_EINVAL);
1090Sstevel@tonic-gate 	}
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate 	/*
1120Sstevel@tonic-gate 	 * Convert older-style vtoc's.
1130Sstevel@tonic-gate 	 */
1140Sstevel@tonic-gate 	switch (vtoc->v_version) {
1150Sstevel@tonic-gate 	case 0:
1160Sstevel@tonic-gate 		/*
1170Sstevel@tonic-gate 		 * No vtoc information.  Install default
1180Sstevel@tonic-gate 		 * nparts/sectorsz and version.  We are
1190Sstevel@tonic-gate 		 * assuming that the driver returns the
1200Sstevel@tonic-gate 		 * current partition information correctly.
1210Sstevel@tonic-gate 		 */
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 		vtoc->v_version = V_VERSION;
1240Sstevel@tonic-gate 		if (vtoc->v_nparts == 0)
1250Sstevel@tonic-gate 			vtoc->v_nparts = V_NUMPAR;
1260Sstevel@tonic-gate 		if (vtoc->v_sectorsz == 0)
1270Sstevel@tonic-gate 			vtoc->v_sectorsz = DEV_BSIZE;
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 		break;
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	case V_VERSION:
1320Sstevel@tonic-gate 		break;
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	default:
1350Sstevel@tonic-gate 		return (VT_EINVAL);
1360Sstevel@tonic-gate 	}
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	/*
1390Sstevel@tonic-gate 	 * Return partition number for this file descriptor.
1400Sstevel@tonic-gate 	 */
1410Sstevel@tonic-gate 	if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
1420Sstevel@tonic-gate 		switch (errno) {
1430Sstevel@tonic-gate 		case EIO:
1440Sstevel@tonic-gate 			return (VT_EIO);
1450Sstevel@tonic-gate 		case EINVAL:
1460Sstevel@tonic-gate 			return (VT_EINVAL);
1470Sstevel@tonic-gate 		default:
1480Sstevel@tonic-gate 			return (VT_ERROR);
1490Sstevel@tonic-gate 		}
1500Sstevel@tonic-gate 	}
1510Sstevel@tonic-gate 	if (dki_info.dki_partition > V_NUMPAR) {
1520Sstevel@tonic-gate 		return (VT_EINVAL);
1530Sstevel@tonic-gate 	}
1540Sstevel@tonic-gate 	return ((int)dki_info.dki_partition);
1550Sstevel@tonic-gate }
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate /*
1580Sstevel@tonic-gate  * Write VTOC
1590Sstevel@tonic-gate  */
1600Sstevel@tonic-gate int
write_vtoc(int fd,struct vtoc * vtoc)1610Sstevel@tonic-gate write_vtoc(int fd, struct vtoc *vtoc)
1620Sstevel@tonic-gate {
1630Sstevel@tonic-gate 	int i;
1640Sstevel@tonic-gate 	/*
1650Sstevel@tonic-gate 	 * Sanity-check the vtoc
1660Sstevel@tonic-gate 	 */
1670Sstevel@tonic-gate 	if (vtoc->v_sanity != VTOC_SANE || vtoc->v_nparts > V_NUMPAR) {
1680Sstevel@tonic-gate 		return (-1);
1690Sstevel@tonic-gate 	}
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 	/*
1720Sstevel@tonic-gate 	 * since many drivers won't allow opening a device make sure
1730Sstevel@tonic-gate 	 * all partitions aren't being set to zero. If all are zero then
1740Sstevel@tonic-gate 	 * we have no way to set them to something else
1750Sstevel@tonic-gate 	 */
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 	for (i = 0; i < (int)vtoc->v_nparts; i++)
1780Sstevel@tonic-gate 		if (vtoc->v_part[i].p_size > 0)
1790Sstevel@tonic-gate 			break;
1800Sstevel@tonic-gate 	if (i == (int)vtoc->v_nparts)
1810Sstevel@tonic-gate 		return (-1);
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 	/*
1840Sstevel@tonic-gate 	 * Write the vtoc
1850Sstevel@tonic-gate 	 */
1860Sstevel@tonic-gate 	if (ioctl(fd, DKIOCSVTOC, (caddr_t)vtoc) == -1) {
1870Sstevel@tonic-gate 		switch (errno) {
1880Sstevel@tonic-gate 		case EIO:
1890Sstevel@tonic-gate 			return (VT_EIO);
1900Sstevel@tonic-gate 		case EINVAL:
1910Sstevel@tonic-gate 			return (VT_EINVAL);
1920Sstevel@tonic-gate 		case ENOTSUP:
193*7563SPrasad.Singamsetty@Sun.COM 			/* GPT labeled or disk > 1TB with no extvtoc support */
1940Sstevel@tonic-gate 			return (VT_ENOTSUP);
195*7563SPrasad.Singamsetty@Sun.COM 		case EOVERFLOW:
196*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EOVERFLOW);
1970Sstevel@tonic-gate 		default:
1980Sstevel@tonic-gate 			return (VT_ERROR);
1990Sstevel@tonic-gate 		}
2000Sstevel@tonic-gate 	}
2010Sstevel@tonic-gate 	return (0);
2020Sstevel@tonic-gate }
203*7563SPrasad.Singamsetty@Sun.COM 
204*7563SPrasad.Singamsetty@Sun.COM int
read_extvtoc(int fd,struct extvtoc * extvtoc)205*7563SPrasad.Singamsetty@Sun.COM read_extvtoc(int fd, struct extvtoc *extvtoc)
206*7563SPrasad.Singamsetty@Sun.COM {
207*7563SPrasad.Singamsetty@Sun.COM 	struct dk_cinfo		dki_info;
208*7563SPrasad.Singamsetty@Sun.COM 	struct vtoc	oldvtoc;
209*7563SPrasad.Singamsetty@Sun.COM 	struct vtoc *oldvtocp = &oldvtoc;
210*7563SPrasad.Singamsetty@Sun.COM 	int ret;
211*7563SPrasad.Singamsetty@Sun.COM 
212*7563SPrasad.Singamsetty@Sun.COM 	/*
213*7563SPrasad.Singamsetty@Sun.COM 	 * Read the vtoc.
214*7563SPrasad.Singamsetty@Sun.COM 	 */
215*7563SPrasad.Singamsetty@Sun.COM 	if (ioctl(fd, DKIOCGEXTVTOC, (caddr_t)extvtoc) == -1) {
216*7563SPrasad.Singamsetty@Sun.COM 		switch (errno) {
217*7563SPrasad.Singamsetty@Sun.COM 		case EIO:
218*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EIO);
219*7563SPrasad.Singamsetty@Sun.COM 		case EINVAL:
220*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EINVAL);
221*7563SPrasad.Singamsetty@Sun.COM 		/* for disks > 1TB */
222*7563SPrasad.Singamsetty@Sun.COM 		case ENOTSUP:
223*7563SPrasad.Singamsetty@Sun.COM 			return (VT_ENOTSUP);
224*7563SPrasad.Singamsetty@Sun.COM 		case EOVERFLOW:
225*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EOVERFLOW);
226*7563SPrasad.Singamsetty@Sun.COM 		case ENOTTY:
227*7563SPrasad.Singamsetty@Sun.COM 
228*7563SPrasad.Singamsetty@Sun.COM 			if ((ret = read_vtoc(fd, oldvtocp)) < 0)
229*7563SPrasad.Singamsetty@Sun.COM 				return (ret);
230*7563SPrasad.Singamsetty@Sun.COM 
231*7563SPrasad.Singamsetty@Sun.COM #ifdef _LP64
232*7563SPrasad.Singamsetty@Sun.COM 			/*
233*7563SPrasad.Singamsetty@Sun.COM 			 * 64-bit vtoc and extvtoc have the same field sizes
234*7563SPrasad.Singamsetty@Sun.COM 			 * and offsets.
235*7563SPrasad.Singamsetty@Sun.COM 			 */
236*7563SPrasad.Singamsetty@Sun.COM 			bcopy(oldvtocp, extvtoc, sizeof (struct extvtoc));
237*7563SPrasad.Singamsetty@Sun.COM #else
238*7563SPrasad.Singamsetty@Sun.COM 			bzero(extvtoc, sizeof (struct extvtoc));
239*7563SPrasad.Singamsetty@Sun.COM 			libadm_vtoc_copy(oldvtocp, extvtoc);
240*7563SPrasad.Singamsetty@Sun.COM #endif
241*7563SPrasad.Singamsetty@Sun.COM 			return (ret);
242*7563SPrasad.Singamsetty@Sun.COM 
243*7563SPrasad.Singamsetty@Sun.COM 
244*7563SPrasad.Singamsetty@Sun.COM 		default:
245*7563SPrasad.Singamsetty@Sun.COM 			return (VT_ERROR);
246*7563SPrasad.Singamsetty@Sun.COM 		}
247*7563SPrasad.Singamsetty@Sun.COM 	}
248*7563SPrasad.Singamsetty@Sun.COM 
249*7563SPrasad.Singamsetty@Sun.COM 	/*
250*7563SPrasad.Singamsetty@Sun.COM 	 * Sanity-check the vtoc.
251*7563SPrasad.Singamsetty@Sun.COM 	 */
252*7563SPrasad.Singamsetty@Sun.COM 	if (extvtoc->v_sanity != VTOC_SANE) {
253*7563SPrasad.Singamsetty@Sun.COM 		return (VT_EINVAL);
254*7563SPrasad.Singamsetty@Sun.COM 	}
255*7563SPrasad.Singamsetty@Sun.COM 
256*7563SPrasad.Singamsetty@Sun.COM 	switch (extvtoc->v_version) {
257*7563SPrasad.Singamsetty@Sun.COM 	case 0:
258*7563SPrasad.Singamsetty@Sun.COM 		/*
259*7563SPrasad.Singamsetty@Sun.COM 		 * For pre-version 1 vtoc keep same functionality
260*7563SPrasad.Singamsetty@Sun.COM 		 * as read_vtoc.
261*7563SPrasad.Singamsetty@Sun.COM 		 */
262*7563SPrasad.Singamsetty@Sun.COM 
263*7563SPrasad.Singamsetty@Sun.COM 		extvtoc->v_version = V_VERSION;
264*7563SPrasad.Singamsetty@Sun.COM 		if (extvtoc->v_nparts == 0)
265*7563SPrasad.Singamsetty@Sun.COM 			extvtoc->v_nparts = V_NUMPAR;
266*7563SPrasad.Singamsetty@Sun.COM 		if (extvtoc->v_sectorsz == 0)
267*7563SPrasad.Singamsetty@Sun.COM 			extvtoc->v_sectorsz = DEV_BSIZE;
268*7563SPrasad.Singamsetty@Sun.COM 
269*7563SPrasad.Singamsetty@Sun.COM 		break;
270*7563SPrasad.Singamsetty@Sun.COM 
271*7563SPrasad.Singamsetty@Sun.COM 	case V_VERSION:
272*7563SPrasad.Singamsetty@Sun.COM 		break;
273*7563SPrasad.Singamsetty@Sun.COM 
274*7563SPrasad.Singamsetty@Sun.COM 	default:
275*7563SPrasad.Singamsetty@Sun.COM 		return (VT_EINVAL);
276*7563SPrasad.Singamsetty@Sun.COM 	}
277*7563SPrasad.Singamsetty@Sun.COM 
278*7563SPrasad.Singamsetty@Sun.COM 	/*
279*7563SPrasad.Singamsetty@Sun.COM 	 * Return partition number for this file descriptor.
280*7563SPrasad.Singamsetty@Sun.COM 	 */
281*7563SPrasad.Singamsetty@Sun.COM 	if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
282*7563SPrasad.Singamsetty@Sun.COM 		switch (errno) {
283*7563SPrasad.Singamsetty@Sun.COM 		case EIO:
284*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EIO);
285*7563SPrasad.Singamsetty@Sun.COM 		case EINVAL:
286*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EINVAL);
287*7563SPrasad.Singamsetty@Sun.COM 		default:
288*7563SPrasad.Singamsetty@Sun.COM 			return (VT_ERROR);
289*7563SPrasad.Singamsetty@Sun.COM 		}
290*7563SPrasad.Singamsetty@Sun.COM 	}
291*7563SPrasad.Singamsetty@Sun.COM 	if (dki_info.dki_partition > V_NUMPAR) {
292*7563SPrasad.Singamsetty@Sun.COM 		return (VT_EINVAL);
293*7563SPrasad.Singamsetty@Sun.COM 	}
294*7563SPrasad.Singamsetty@Sun.COM 	return ((int)dki_info.dki_partition);
295*7563SPrasad.Singamsetty@Sun.COM }
296*7563SPrasad.Singamsetty@Sun.COM 
297*7563SPrasad.Singamsetty@Sun.COM /*
298*7563SPrasad.Singamsetty@Sun.COM  * Write ext VTOC.
299*7563SPrasad.Singamsetty@Sun.COM  */
300*7563SPrasad.Singamsetty@Sun.COM int
write_extvtoc(int fd,struct extvtoc * extvtoc)301*7563SPrasad.Singamsetty@Sun.COM write_extvtoc(int fd, struct extvtoc *extvtoc)
302*7563SPrasad.Singamsetty@Sun.COM {
303*7563SPrasad.Singamsetty@Sun.COM 	int i;
304*7563SPrasad.Singamsetty@Sun.COM 	struct vtoc	oldvtoc;
305*7563SPrasad.Singamsetty@Sun.COM 	struct vtoc	*oldvtocp = &oldvtoc;
306*7563SPrasad.Singamsetty@Sun.COM 	/*
307*7563SPrasad.Singamsetty@Sun.COM 	 * Sanity-check the vtoc
308*7563SPrasad.Singamsetty@Sun.COM 	 */
309*7563SPrasad.Singamsetty@Sun.COM 	if (extvtoc->v_sanity != VTOC_SANE || extvtoc->v_nparts > V_NUMPAR) {
310*7563SPrasad.Singamsetty@Sun.COM 		return (-1);
311*7563SPrasad.Singamsetty@Sun.COM 	}
312*7563SPrasad.Singamsetty@Sun.COM 
313*7563SPrasad.Singamsetty@Sun.COM 	/*
314*7563SPrasad.Singamsetty@Sun.COM 	 * since many drivers won't allow opening a device make sure
315*7563SPrasad.Singamsetty@Sun.COM 	 * all partitions aren't being set to zero. If all are zero then
316*7563SPrasad.Singamsetty@Sun.COM 	 * we have no way to set them to something else
317*7563SPrasad.Singamsetty@Sun.COM 	 */
318*7563SPrasad.Singamsetty@Sun.COM 
319*7563SPrasad.Singamsetty@Sun.COM 	for (i = 0; i < (int)extvtoc->v_nparts; i++)
320*7563SPrasad.Singamsetty@Sun.COM 		if (extvtoc->v_part[i].p_size > 0)
321*7563SPrasad.Singamsetty@Sun.COM 			break;
322*7563SPrasad.Singamsetty@Sun.COM 	if (i == (int)extvtoc->v_nparts)
323*7563SPrasad.Singamsetty@Sun.COM 		return (-1);
324*7563SPrasad.Singamsetty@Sun.COM 
325*7563SPrasad.Singamsetty@Sun.COM 	/*
326*7563SPrasad.Singamsetty@Sun.COM 	 * Write the extvtoc
327*7563SPrasad.Singamsetty@Sun.COM 	 */
328*7563SPrasad.Singamsetty@Sun.COM 	if (ioctl(fd, DKIOCSEXTVTOC, (caddr_t)extvtoc) == -1) {
329*7563SPrasad.Singamsetty@Sun.COM 		switch (errno) {
330*7563SPrasad.Singamsetty@Sun.COM 		case EIO:
331*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EIO);
332*7563SPrasad.Singamsetty@Sun.COM 		case EINVAL:
333*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EINVAL);
334*7563SPrasad.Singamsetty@Sun.COM 		/* for disks > 1TB */
335*7563SPrasad.Singamsetty@Sun.COM 		case ENOTSUP:
336*7563SPrasad.Singamsetty@Sun.COM 			return (VT_ENOTSUP);
337*7563SPrasad.Singamsetty@Sun.COM 		case EOVERFLOW:
338*7563SPrasad.Singamsetty@Sun.COM 			return (VT_EOVERFLOW);
339*7563SPrasad.Singamsetty@Sun.COM 		case ENOTTY:
340*7563SPrasad.Singamsetty@Sun.COM #ifdef _LP64
341*7563SPrasad.Singamsetty@Sun.COM 			/*
342*7563SPrasad.Singamsetty@Sun.COM 			 * 64-bit vtoc and extvtoc have the same field sizes
343*7563SPrasad.Singamsetty@Sun.COM 			 * and offsets.
344*7563SPrasad.Singamsetty@Sun.COM 			 */
345*7563SPrasad.Singamsetty@Sun.COM 			bcopy(extvtoc, oldvtocp, sizeof (struct vtoc));
346*7563SPrasad.Singamsetty@Sun.COM #else
347*7563SPrasad.Singamsetty@Sun.COM 			bzero(oldvtocp, sizeof (struct vtoc));
348*7563SPrasad.Singamsetty@Sun.COM 			libadm_vtoc_copy(extvtoc, oldvtocp);
349*7563SPrasad.Singamsetty@Sun.COM 
350*7563SPrasad.Singamsetty@Sun.COM #endif
351*7563SPrasad.Singamsetty@Sun.COM 			return (write_vtoc(fd, &oldvtoc));
352*7563SPrasad.Singamsetty@Sun.COM 
353*7563SPrasad.Singamsetty@Sun.COM 		default:
354*7563SPrasad.Singamsetty@Sun.COM 			return (VT_ERROR);
355*7563SPrasad.Singamsetty@Sun.COM 		}
356*7563SPrasad.Singamsetty@Sun.COM 	}
357*7563SPrasad.Singamsetty@Sun.COM 
358*7563SPrasad.Singamsetty@Sun.COM 	return (0);
359*7563SPrasad.Singamsetty@Sun.COM }
360