xref: /illumos-gate/usr/src/uts/common/fs/zfs/vdev_root.c (revision a07094369b21309434206d9b3601d162693466fc)
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  * Copyright 2005 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 #include <sys/zfs_context.h>
30 #include <sys/spa.h>
31 #include <sys/vdev_impl.h>
32 #include <sys/zio.h>
33 #include <sys/fs/zfs.h>
34 
35 /*
36  * Virtual device vector for the pool's root vdev.
37  */
38 
39 static int
40 vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
41 {
42 	vdev_t *cvd;
43 	int c, error;
44 	int lasterror = 0;
45 
46 	if (vd->vdev_children == 0) {
47 		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
48 		return (EINVAL);
49 	}
50 
51 	for (c = 0; c < vd->vdev_children; c++) {
52 		cvd = vd->vdev_child[c];
53 
54 		if ((error = vdev_open(cvd)) != 0) {
55 			lasterror = error;
56 			continue;
57 		}
58 
59 		*asize += cvd->vdev_asize;
60 		*ashift = MAX(*ashift, cvd->vdev_ashift);
61 	}
62 
63 	if (lasterror)
64 		vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;
65 
66 	return (lasterror);
67 }
68 
69 static void
70 vdev_root_close(vdev_t *vd)
71 {
72 	int c;
73 
74 	for (c = 0; c < vd->vdev_children; c++)
75 		vdev_close(vd->vdev_child[c]);
76 }
77 
78 static void
79 vdev_root_state_change(vdev_t *vd, int faulted, int degraded)
80 {
81 	if (faulted > 0)
82 		vdev_set_state(vd, VDEV_STATE_CANT_OPEN, VDEV_AUX_NO_REPLICAS);
83 	else if (degraded != 0)
84 		vdev_set_state(vd, VDEV_STATE_DEGRADED, VDEV_AUX_NONE);
85 	else
86 		vdev_set_state(vd, VDEV_STATE_HEALTHY, VDEV_AUX_NONE);
87 }
88 
89 vdev_ops_t vdev_root_ops = {
90 	vdev_root_open,
91 	vdev_root_close,
92 	vdev_default_asize,
93 	NULL,			/* io_start - not applicable to the root */
94 	NULL,			/* io_done - not applicable to the root */
95 	vdev_root_state_change,
96 	VDEV_TYPE_ROOT,		/* name of this vdev type */
97 	B_FALSE			/* not a leaf vdev */
98 };
99