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