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 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 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