meta_attach.c revision 1623:7bac4a816ebe
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 */
38int
39meta_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 */
79int
80meta_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