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