17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*342440ecSPrasad Singamsetty  * Common Development and Distribution License (the "License").
6*342440ecSPrasad Singamsetty  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*342440ecSPrasad Singamsetty 
227c478bd9Sstevel@tonic-gate /*
23*342440ecSPrasad Singamsetty  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <errno.h>
327c478bd9Sstevel@tonic-gate #include <memory.h>
337c478bd9Sstevel@tonic-gate #include <unistd.h>
347c478bd9Sstevel@tonic-gate #include <sys/types.h>
357c478bd9Sstevel@tonic-gate #include <sys/param.h>
367c478bd9Sstevel@tonic-gate #include <sys/dkio.h>
377c478bd9Sstevel@tonic-gate #include <sys/vtoc.h>
38*342440ecSPrasad Singamsetty #include <strings.h>
39*342440ecSPrasad Singamsetty #include <limits.h>
40*342440ecSPrasad Singamsetty 
41*342440ecSPrasad Singamsetty /*
42*342440ecSPrasad Singamsetty  * To copy each field of vtoc individually for copying extvtoc
43*342440ecSPrasad Singamsetty  * to 32 bit vtoc and vs.
44*342440ecSPrasad Singamsetty  * Currently bootinfo and timestamp are not really supported.
45*342440ecSPrasad Singamsetty  */
46*342440ecSPrasad Singamsetty 
47*342440ecSPrasad Singamsetty #define	libadm_vtoc_copy(vs, vd) \
48*342440ecSPrasad Singamsetty 	{							\
49*342440ecSPrasad Singamsetty 	int i;							\
50*342440ecSPrasad Singamsetty 	vd->v_bootinfo[0]	= (unsigned)vs->v_bootinfo[0];	\
51*342440ecSPrasad Singamsetty 	vd->v_bootinfo[1]	= (unsigned)vs->v_bootinfo[1];	\
52*342440ecSPrasad Singamsetty 	vd->v_bootinfo[2]	= (unsigned)vs->v_bootinfo[2];	\
53*342440ecSPrasad Singamsetty 	vd->v_sanity		= (unsigned)vs->v_sanity;	\
54*342440ecSPrasad Singamsetty 	vd->v_version		= (unsigned)vs->v_version;	\
55*342440ecSPrasad Singamsetty 	bcopy(vs->v_volume, vd->v_volume, LEN_DKL_VVOL);	\
56*342440ecSPrasad Singamsetty 	vd->v_sectorsz		= vs->v_sectorsz;		\
57*342440ecSPrasad Singamsetty 	vd->v_nparts		= vs->v_nparts;			\
58*342440ecSPrasad Singamsetty 	vd->v_version		= (unsigned)vs->v_version;	\
59*342440ecSPrasad Singamsetty 	for (i = 0; i < 10; i++)				\
60*342440ecSPrasad Singamsetty 		vd->v_reserved[i] = (unsigned)vs->v_reserved[i];\
61*342440ecSPrasad Singamsetty 	for (i = 0; i < V_NUMPAR; i++) {			\
62*342440ecSPrasad Singamsetty 		vd->v_part[i].p_tag = vs->v_part[i].p_tag;	\
63*342440ecSPrasad Singamsetty 		vd->v_part[i].p_flag = vs->v_part[i].p_flag;	\
64*342440ecSPrasad Singamsetty 		vd->v_part[i].p_start = (unsigned)vs->v_part[i].p_start;\
65*342440ecSPrasad Singamsetty 		vd->v_part[i].p_size = (unsigned)vs->v_part[i].p_size;	\
66*342440ecSPrasad Singamsetty 	}								\
67*342440ecSPrasad Singamsetty 	for (i = 0; i < V_NUMPAR; i++)					\
68*342440ecSPrasad Singamsetty 		if ((sizeof (vd->timestamp[i]) != sizeof (vs->timestamp[i])) &&\
69*342440ecSPrasad Singamsetty 		    (vs->timestamp[i] > INT32_MAX))			\
70*342440ecSPrasad Singamsetty 			vd->timestamp[i] = INT32_MAX;			\
71*342440ecSPrasad Singamsetty 		else							\
72*342440ecSPrasad Singamsetty 			vd->timestamp[i] = (unsigned)vs->timestamp[i];	\
73*342440ecSPrasad Singamsetty 	bcopy(vs->v_asciilabel, vd->v_asciilabel, LEN_DKL_ASCII);	\
74*342440ecSPrasad Singamsetty 	}
75*342440ecSPrasad Singamsetty 
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  * Read VTOC - return partition number.
797c478bd9Sstevel@tonic-gate  */
807c478bd9Sstevel@tonic-gate int
read_vtoc(int fd,struct vtoc * vtoc)817c478bd9Sstevel@tonic-gate read_vtoc(int fd, struct vtoc *vtoc)
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate 	struct dk_cinfo		dki_info;
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	/*
867c478bd9Sstevel@tonic-gate 	 * Read the vtoc.
877c478bd9Sstevel@tonic-gate 	 */
887c478bd9Sstevel@tonic-gate 	if (ioctl(fd, DKIOCGVTOC, (caddr_t)vtoc) == -1) {
897c478bd9Sstevel@tonic-gate 		switch (errno) {
907c478bd9Sstevel@tonic-gate 		case EIO:
917c478bd9Sstevel@tonic-gate 			return (VT_EIO);
927c478bd9Sstevel@tonic-gate 		case EINVAL:
937c478bd9Sstevel@tonic-gate 			return (VT_EINVAL);
947c478bd9Sstevel@tonic-gate 		case ENOTSUP:
95*342440ecSPrasad Singamsetty 			/* GPT labeled or disk > 1TB with no extvtoc support */
967c478bd9Sstevel@tonic-gate 			return (VT_ENOTSUP);
97*342440ecSPrasad Singamsetty 		case EOVERFLOW:
98*342440ecSPrasad Singamsetty 			return (VT_EOVERFLOW);
997c478bd9Sstevel@tonic-gate 		default:
1007c478bd9Sstevel@tonic-gate 			return (VT_ERROR);
1017c478bd9Sstevel@tonic-gate 		}
1027c478bd9Sstevel@tonic-gate 	}
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 	/*
1057c478bd9Sstevel@tonic-gate 	 * Sanity-check the vtoc.
1067c478bd9Sstevel@tonic-gate 	 */
1077c478bd9Sstevel@tonic-gate 	if (vtoc->v_sanity != VTOC_SANE) {
1087c478bd9Sstevel@tonic-gate 		return (VT_EINVAL);
1097c478bd9Sstevel@tonic-gate 	}
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	/*
1127c478bd9Sstevel@tonic-gate 	 * Convert older-style vtoc's.
1137c478bd9Sstevel@tonic-gate 	 */
1147c478bd9Sstevel@tonic-gate 	switch (vtoc->v_version) {
1157c478bd9Sstevel@tonic-gate 	case 0:
1167c478bd9Sstevel@tonic-gate 		/*
1177c478bd9Sstevel@tonic-gate 		 * No vtoc information.  Install default
1187c478bd9Sstevel@tonic-gate 		 * nparts/sectorsz and version.  We are
1197c478bd9Sstevel@tonic-gate 		 * assuming that the driver returns the
1207c478bd9Sstevel@tonic-gate 		 * current partition information correctly.
1217c478bd9Sstevel@tonic-gate 		 */
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 		vtoc->v_version = V_VERSION;
1247c478bd9Sstevel@tonic-gate 		if (vtoc->v_nparts == 0)
1257c478bd9Sstevel@tonic-gate 			vtoc->v_nparts = V_NUMPAR;
1267c478bd9Sstevel@tonic-gate 		if (vtoc->v_sectorsz == 0)
1277c478bd9Sstevel@tonic-gate 			vtoc->v_sectorsz = DEV_BSIZE;
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 		break;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	case V_VERSION:
1327c478bd9Sstevel@tonic-gate 		break;
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	default:
1357c478bd9Sstevel@tonic-gate 		return (VT_EINVAL);
1367c478bd9Sstevel@tonic-gate 	}
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	/*
1397c478bd9Sstevel@tonic-gate 	 * Return partition number for this file descriptor.
1407c478bd9Sstevel@tonic-gate 	 */
1417c478bd9Sstevel@tonic-gate 	if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
1427c478bd9Sstevel@tonic-gate 		switch (errno) {
1437c478bd9Sstevel@tonic-gate 		case EIO:
1447c478bd9Sstevel@tonic-gate 			return (VT_EIO);
1457c478bd9Sstevel@tonic-gate 		case EINVAL:
1467c478bd9Sstevel@tonic-gate 			return (VT_EINVAL);
1477c478bd9Sstevel@tonic-gate 		default:
1487c478bd9Sstevel@tonic-gate 			return (VT_ERROR);
1497c478bd9Sstevel@tonic-gate 		}
1507c478bd9Sstevel@tonic-gate 	}
1517c478bd9Sstevel@tonic-gate 	if (dki_info.dki_partition > V_NUMPAR) {
1527c478bd9Sstevel@tonic-gate 		return (VT_EINVAL);
1537c478bd9Sstevel@tonic-gate 	}
1547c478bd9Sstevel@tonic-gate 	return ((int)dki_info.dki_partition);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate /*
1587c478bd9Sstevel@tonic-gate  * Write VTOC
1597c478bd9Sstevel@tonic-gate  */
1607c478bd9Sstevel@tonic-gate int
write_vtoc(int fd,struct vtoc * vtoc)1617c478bd9Sstevel@tonic-gate write_vtoc(int fd, struct vtoc *vtoc)
1627c478bd9Sstevel@tonic-gate {
1637c478bd9Sstevel@tonic-gate 	int i;
1647c478bd9Sstevel@tonic-gate 	/*
1657c478bd9Sstevel@tonic-gate 	 * Sanity-check the vtoc
1667c478bd9Sstevel@tonic-gate 	 */
1677c478bd9Sstevel@tonic-gate 	if (vtoc->v_sanity != VTOC_SANE || vtoc->v_nparts > V_NUMPAR) {
1687c478bd9Sstevel@tonic-gate 		return (-1);
1697c478bd9Sstevel@tonic-gate 	}
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 	/*
1727c478bd9Sstevel@tonic-gate 	 * since many drivers won't allow opening a device make sure
1737c478bd9Sstevel@tonic-gate 	 * all partitions aren't being set to zero. If all are zero then
1747c478bd9Sstevel@tonic-gate 	 * we have no way to set them to something else
1757c478bd9Sstevel@tonic-gate 	 */
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	for (i = 0; i < (int)vtoc->v_nparts; i++)
1787c478bd9Sstevel@tonic-gate 		if (vtoc->v_part[i].p_size > 0)
1797c478bd9Sstevel@tonic-gate 			break;
1807c478bd9Sstevel@tonic-gate 	if (i == (int)vtoc->v_nparts)
1817c478bd9Sstevel@tonic-gate 		return (-1);
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	/*
1847c478bd9Sstevel@tonic-gate 	 * Write the vtoc
1857c478bd9Sstevel@tonic-gate 	 */
1867c478bd9Sstevel@tonic-gate 	if (ioctl(fd, DKIOCSVTOC, (caddr_t)vtoc) == -1) {
187*342440ecSPrasad Singamsetty 		switch (errno) {
188*342440ecSPrasad Singamsetty 		case EIO:
189*342440ecSPrasad Singamsetty 			return (VT_EIO);
190*342440ecSPrasad Singamsetty 		case EINVAL:
191*342440ecSPrasad Singamsetty 			return (VT_EINVAL);
192*342440ecSPrasad Singamsetty 		case ENOTSUP:
193*342440ecSPrasad Singamsetty 			/* GPT labeled or disk > 1TB with no extvtoc support */
194*342440ecSPrasad Singamsetty 			return (VT_ENOTSUP);
195*342440ecSPrasad Singamsetty 		case EOVERFLOW:
196*342440ecSPrasad Singamsetty 			return (VT_EOVERFLOW);
197*342440ecSPrasad Singamsetty 		default:
198*342440ecSPrasad Singamsetty 			return (VT_ERROR);
199*342440ecSPrasad Singamsetty 		}
200*342440ecSPrasad Singamsetty 	}
201*342440ecSPrasad Singamsetty 	return (0);
202*342440ecSPrasad Singamsetty }
203*342440ecSPrasad Singamsetty 
204*342440ecSPrasad Singamsetty int
read_extvtoc(int fd,struct extvtoc * extvtoc)205*342440ecSPrasad Singamsetty read_extvtoc(int fd, struct extvtoc *extvtoc)
206*342440ecSPrasad Singamsetty {
207*342440ecSPrasad Singamsetty 	struct dk_cinfo		dki_info;
208*342440ecSPrasad Singamsetty 	struct vtoc	oldvtoc;
209*342440ecSPrasad Singamsetty 	struct vtoc *oldvtocp = &oldvtoc;
210*342440ecSPrasad Singamsetty 	int ret;
211*342440ecSPrasad Singamsetty 
212*342440ecSPrasad Singamsetty 	/*
213*342440ecSPrasad Singamsetty 	 * Read the vtoc.
214*342440ecSPrasad Singamsetty 	 */
215*342440ecSPrasad Singamsetty 	if (ioctl(fd, DKIOCGEXTVTOC, (caddr_t)extvtoc) == -1) {
2167c478bd9Sstevel@tonic-gate 		switch (errno) {
2177c478bd9Sstevel@tonic-gate 		case EIO:
2187c478bd9Sstevel@tonic-gate 			return (VT_EIO);
2197c478bd9Sstevel@tonic-gate 		case EINVAL:
2207c478bd9Sstevel@tonic-gate 			return (VT_EINVAL);
2217c478bd9Sstevel@tonic-gate 		/* for disks > 1TB */
2227c478bd9Sstevel@tonic-gate 		case ENOTSUP:
2237c478bd9Sstevel@tonic-gate 			return (VT_ENOTSUP);
224*342440ecSPrasad Singamsetty 		case EOVERFLOW:
225*342440ecSPrasad Singamsetty 			return (VT_EOVERFLOW);
226*342440ecSPrasad Singamsetty 		case ENOTTY:
227*342440ecSPrasad Singamsetty 
228*342440ecSPrasad Singamsetty 			if ((ret = read_vtoc(fd, oldvtocp)) < 0)
229*342440ecSPrasad Singamsetty 				return (ret);
230*342440ecSPrasad Singamsetty 
231*342440ecSPrasad Singamsetty #ifdef _LP64
232*342440ecSPrasad Singamsetty 			/*
233*342440ecSPrasad Singamsetty 			 * 64-bit vtoc and extvtoc have the same field sizes
234*342440ecSPrasad Singamsetty 			 * and offsets.
235*342440ecSPrasad Singamsetty 			 */
236*342440ecSPrasad Singamsetty 			bcopy(oldvtocp, extvtoc, sizeof (struct extvtoc));
237*342440ecSPrasad Singamsetty #else
238*342440ecSPrasad Singamsetty 			bzero(extvtoc, sizeof (struct extvtoc));
239*342440ecSPrasad Singamsetty 			libadm_vtoc_copy(oldvtocp, extvtoc);
240*342440ecSPrasad Singamsetty #endif
241*342440ecSPrasad Singamsetty 			return (ret);
242*342440ecSPrasad Singamsetty 
243*342440ecSPrasad Singamsetty 
2447c478bd9Sstevel@tonic-gate 		default:
2457c478bd9Sstevel@tonic-gate 			return (VT_ERROR);
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate 	}
248*342440ecSPrasad Singamsetty 
249*342440ecSPrasad Singamsetty 	/*
250*342440ecSPrasad Singamsetty 	 * Sanity-check the vtoc.
251*342440ecSPrasad Singamsetty 	 */
252*342440ecSPrasad Singamsetty 	if (extvtoc->v_sanity != VTOC_SANE) {
253*342440ecSPrasad Singamsetty 		return (VT_EINVAL);
254*342440ecSPrasad Singamsetty 	}
255*342440ecSPrasad Singamsetty 
256*342440ecSPrasad Singamsetty 	switch (extvtoc->v_version) {
257*342440ecSPrasad Singamsetty 	case 0:
258*342440ecSPrasad Singamsetty 		/*
259*342440ecSPrasad Singamsetty 		 * For pre-version 1 vtoc keep same functionality
260*342440ecSPrasad Singamsetty 		 * as read_vtoc.
261*342440ecSPrasad Singamsetty 		 */
262*342440ecSPrasad Singamsetty 
263*342440ecSPrasad Singamsetty 		extvtoc->v_version = V_VERSION;
264*342440ecSPrasad Singamsetty 		if (extvtoc->v_nparts == 0)
265*342440ecSPrasad Singamsetty 			extvtoc->v_nparts = V_NUMPAR;
266*342440ecSPrasad Singamsetty 		if (extvtoc->v_sectorsz == 0)
267*342440ecSPrasad Singamsetty 			extvtoc->v_sectorsz = DEV_BSIZE;
268*342440ecSPrasad Singamsetty 
269*342440ecSPrasad Singamsetty 		break;
270*342440ecSPrasad Singamsetty 
271*342440ecSPrasad Singamsetty 	case V_VERSION:
272*342440ecSPrasad Singamsetty 		break;
273*342440ecSPrasad Singamsetty 
274*342440ecSPrasad Singamsetty 	default:
275*342440ecSPrasad Singamsetty 		return (VT_EINVAL);
276*342440ecSPrasad Singamsetty 	}
277*342440ecSPrasad Singamsetty 
278*342440ecSPrasad Singamsetty 	/*
279*342440ecSPrasad Singamsetty 	 * Return partition number for this file descriptor.
280*342440ecSPrasad Singamsetty 	 */
281*342440ecSPrasad Singamsetty 	if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
282*342440ecSPrasad Singamsetty 		switch (errno) {
283*342440ecSPrasad Singamsetty 		case EIO:
284*342440ecSPrasad Singamsetty 			return (VT_EIO);
285*342440ecSPrasad Singamsetty 		case EINVAL:
286*342440ecSPrasad Singamsetty 			return (VT_EINVAL);
287*342440ecSPrasad Singamsetty 		default:
288*342440ecSPrasad Singamsetty 			return (VT_ERROR);
289*342440ecSPrasad Singamsetty 		}
290*342440ecSPrasad Singamsetty 	}
291*342440ecSPrasad Singamsetty 	if (dki_info.dki_partition > V_NUMPAR) {
292*342440ecSPrasad Singamsetty 		return (VT_EINVAL);
293*342440ecSPrasad Singamsetty 	}
294*342440ecSPrasad Singamsetty 	return ((int)dki_info.dki_partition);
295*342440ecSPrasad Singamsetty }
296*342440ecSPrasad Singamsetty 
297*342440ecSPrasad Singamsetty /*
298*342440ecSPrasad Singamsetty  * Write ext VTOC.
299*342440ecSPrasad Singamsetty  */
300*342440ecSPrasad Singamsetty int
write_extvtoc(int fd,struct extvtoc * extvtoc)301*342440ecSPrasad Singamsetty write_extvtoc(int fd, struct extvtoc *extvtoc)
302*342440ecSPrasad Singamsetty {
303*342440ecSPrasad Singamsetty 	int i;
304*342440ecSPrasad Singamsetty 	struct vtoc	oldvtoc;
305*342440ecSPrasad Singamsetty 	struct vtoc	*oldvtocp = &oldvtoc;
306*342440ecSPrasad Singamsetty 	/*
307*342440ecSPrasad Singamsetty 	 * Sanity-check the vtoc
308*342440ecSPrasad Singamsetty 	 */
309*342440ecSPrasad Singamsetty 	if (extvtoc->v_sanity != VTOC_SANE || extvtoc->v_nparts > V_NUMPAR) {
310*342440ecSPrasad Singamsetty 		return (-1);
311*342440ecSPrasad Singamsetty 	}
312*342440ecSPrasad Singamsetty 
313*342440ecSPrasad Singamsetty 	/*
314*342440ecSPrasad Singamsetty 	 * since many drivers won't allow opening a device make sure
315*342440ecSPrasad Singamsetty 	 * all partitions aren't being set to zero. If all are zero then
316*342440ecSPrasad Singamsetty 	 * we have no way to set them to something else
317*342440ecSPrasad Singamsetty 	 */
318*342440ecSPrasad Singamsetty 
319*342440ecSPrasad Singamsetty 	for (i = 0; i < (int)extvtoc->v_nparts; i++)
320*342440ecSPrasad Singamsetty 		if (extvtoc->v_part[i].p_size > 0)
321*342440ecSPrasad Singamsetty 			break;
322*342440ecSPrasad Singamsetty 	if (i == (int)extvtoc->v_nparts)
323*342440ecSPrasad Singamsetty 		return (-1);
324*342440ecSPrasad Singamsetty 
325*342440ecSPrasad Singamsetty 	/*
326*342440ecSPrasad Singamsetty 	 * Write the extvtoc
327*342440ecSPrasad Singamsetty 	 */
328*342440ecSPrasad Singamsetty 	if (ioctl(fd, DKIOCSEXTVTOC, (caddr_t)extvtoc) == -1) {
329*342440ecSPrasad Singamsetty 		switch (errno) {
330*342440ecSPrasad Singamsetty 		case EIO:
331*342440ecSPrasad Singamsetty 			return (VT_EIO);
332*342440ecSPrasad Singamsetty 		case EINVAL:
333*342440ecSPrasad Singamsetty 			return (VT_EINVAL);
334*342440ecSPrasad Singamsetty 		/* for disks > 1TB */
335*342440ecSPrasad Singamsetty 		case ENOTSUP:
336*342440ecSPrasad Singamsetty 			return (VT_ENOTSUP);
337*342440ecSPrasad Singamsetty 		case EOVERFLOW:
338*342440ecSPrasad Singamsetty 			return (VT_EOVERFLOW);
339*342440ecSPrasad Singamsetty 		case ENOTTY:
340*342440ecSPrasad Singamsetty #ifdef _LP64
341*342440ecSPrasad Singamsetty 			/*
342*342440ecSPrasad Singamsetty 			 * 64-bit vtoc and extvtoc have the same field sizes
343*342440ecSPrasad Singamsetty 			 * and offsets.
344*342440ecSPrasad Singamsetty 			 */
345*342440ecSPrasad Singamsetty 			bcopy(extvtoc, oldvtocp, sizeof (struct vtoc));
346*342440ecSPrasad Singamsetty #else
347*342440ecSPrasad Singamsetty 			bzero(oldvtocp, sizeof (struct vtoc));
348*342440ecSPrasad Singamsetty 			libadm_vtoc_copy(extvtoc, oldvtocp);
349*342440ecSPrasad Singamsetty 
350*342440ecSPrasad Singamsetty #endif
351*342440ecSPrasad Singamsetty 			return (write_vtoc(fd, &oldvtoc));
352*342440ecSPrasad Singamsetty 
353*342440ecSPrasad Singamsetty 		default:
354*342440ecSPrasad Singamsetty 			return (VT_ERROR);
355*342440ecSPrasad Singamsetty 		}
356*342440ecSPrasad Singamsetty 	}
357*342440ecSPrasad Singamsetty 
3587c478bd9Sstevel@tonic-gate 	return (0);
3597c478bd9Sstevel@tonic-gate }
360