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