xref: /titanic_41/usr/src/lib/lvm/libmeta/common/meta_attach.c (revision 749f21d359d8fbd020c974a1a5227316221bfc9c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 1992-2002 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 
31 /*
32  * attach operations
33  */
34 
35 #include <meta.h>
36 
37 /*
38  * grow generic device
39  */
40 int
41 meta_concat_generic(
42 	mdsetname_t		*sp,
43 	mdname_t		*namep,
44 	u_longlong_t		big_or_little,
45 	md_error_t		*ep
46 )
47 {
48 	md_grow_params_t	mgp;
49 	char			*miscname;
50 
51 	/* should have a set */
52 	assert(sp != NULL);
53 	assert(sp->setno == MD_MIN2SET(meta_getminor(namep->dev)));
54 
55 	/* get type */
56 	if ((miscname = metagetmiscname(namep, ep)) == NULL)
57 		return (-1);
58 
59 	/* grow device */
60 	(void) memset(&mgp, 0, sizeof (mgp));
61 	if (big_or_little == MD_64BIT_META_DEV)
62 		mgp.options = MD_CRO_64BIT;
63 	else
64 		mgp.options = MD_CRO_32BIT;
65 
66 	mgp.mnum = meta_getminor(namep->dev);
67 	MD_SETDRIVERNAME(&mgp, miscname, sp->setno);
68 	if (metaioctl(MD_IOCGROW, &mgp, &mgp.mde, namep->cname) != 0)
69 		return (mdstealerror(ep, &mgp.mde));
70 
71 	/* clear cache */
72 	meta_invalidate_name(namep);
73 
74 	/* return success */
75 	return (0);
76 }
77 
78 /*
79  * grow the parent of a device
80  */
81 int
82 meta_concat_parent(
83 	mdsetname_t	*sp,
84 	mdname_t	*childnp,
85 	md_error_t	*ep
86 )
87 {
88 	md_common_t	*mdp;
89 	mdname_t	*parentnp;
90 	md_unit_t	*mup;
91 
92 	/* should have a set */
93 	assert(sp != NULL);
94 	assert(sp->setno == MD_MIN2SET(meta_getminor(childnp->dev)));
95 
96 	/* get parent */
97 	if ((mdp = meta_get_unit(sp, childnp, ep)) == NULL)
98 		return (-1);
99 	if (! MD_HAS_PARENT(mdp->parent))
100 		return (0);
101 	if (mdp->parent == MD_MULTI_PARENT)
102 		return (0);
103 
104 	/* single parent */
105 	if ((parentnp = metamnumname(&sp, mdp->parent, 0, ep)) == NULL)
106 		return (-1);
107 	/* don't grow non-metadevices or soft partitions */
108 	if (! metaismeta(parentnp) || meta_sp_issp(sp, parentnp, ep) == 0)
109 		return (0);
110 
111 	if ((mup = meta_get_mdunit(sp, childnp, ep)) == NULL)
112 		return (-1);
113 
114 	/* grow parent */
115 	if (meta_concat_generic(sp, parentnp, mup->c.un_revision, ep) != 0)
116 		return (-1);
117 
118 	/* recursively check for parents of parents */
119 	return (meta_concat_parent(sp, parentnp, ep));
120 }
121