author | Chris Kirby <Chris.Kirby@oracle.com> |
Thu, 10 Jun 2010 15:46:47 -0600 | |
changeset 12605 | 6790e683d5a5 |
parent 12247 | 5bcd281629f8 |
child 13570 | 3411fd5f1589 |
permissions | -rw-r--r-- |
789 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
1544 | 5 |
* Common Development and Distribution License (the "License"). |
6 |
* You may not use this file except in compliance with the License. |
|
789 | 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 |
/* |
|
12247
5bcd281629f8
6911420 ZFS device removal detection should work with SCSAv3
George Wilson <George.Wilson@Sun.COM>
parents:
11958
diff
changeset
|
22 |
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
789 | 23 |
*/ |
24 |
||
25 |
#include <sys/zfs_context.h> |
|
26 |
#include <sys/spa.h> |
|
27 |
#include <sys/vdev_file.h> |
|
28 |
#include <sys/vdev_impl.h> |
|
29 |
#include <sys/zio.h> |
|
30 |
#include <sys/fs/zfs.h> |
|
6976
cae5f06df471
PSARC 2008/388 Short circuit for vdev probe failure
eschrock
parents:
6523
diff
changeset
|
31 |
#include <sys/fm/fs/zfs.h> |
789 | 32 |
|
33 |
/* |
|
34 |
* Virtual device vector for files. |
|
35 |
*/ |
|
36 |
||
11958
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
37 |
static void |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
38 |
vdev_file_hold(vdev_t *vd) |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
39 |
{ |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
40 |
ASSERT(vd->vdev_path != NULL); |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
41 |
} |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
42 |
|
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
43 |
static void |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
44 |
vdev_file_rele(vdev_t *vd) |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
45 |
{ |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
46 |
ASSERT(vd->vdev_path != NULL); |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
47 |
} |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
48 |
|
789 | 49 |
static int |
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
6976
diff
changeset
|
50 |
vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) |
789 | 51 |
{ |
52 |
vdev_file_t *vf; |
|
53 |
vnode_t *vp; |
|
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
6976
diff
changeset
|
54 |
vattr_t vattr; |
789 | 55 |
int error; |
56 |
||
57 |
/* |
|
58 |
* We must have a pathname, and it must be absolute. |
|
59 |
*/ |
|
60 |
if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') { |
|
61 |
vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; |
|
62 |
return (EINVAL); |
|
63 |
} |
|
64 |
||
10850
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
65 |
/* |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
66 |
* Reopen the device if it's not currently open. Otherwise, |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
67 |
* just update the physical size of the device. |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
68 |
*/ |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
69 |
if (vd->vdev_tsd != NULL) { |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
70 |
ASSERT(vd->vdev_reopening); |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
71 |
vf = vd->vdev_tsd; |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
72 |
goto skip_open; |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
73 |
} |
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
74 |
|
789 | 75 |
vf = vd->vdev_tsd = kmem_zalloc(sizeof (vdev_file_t), KM_SLEEP); |
76 |
||
77 |
/* |
|
78 |
* We always open the files from the root of the global zone, even if |
|
79 |
* we're in a local zone. If the user has gotten to this point, the |
|
80 |
* administrator has already decided that the pool should be available |
|
81 |
* to local zone users, so the underlying devices should be as well. |
|
82 |
*/ |
|
83 |
ASSERT(vd->vdev_path != NULL && vd->vdev_path[0] == '/'); |
|
5329 | 84 |
error = vn_openat(vd->vdev_path + 1, UIO_SYSSPACE, |
8241
5a60f16123ba
6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
7754
diff
changeset
|
85 |
spa_mode(vd->vdev_spa) | FOFFMAX, 0, &vp, 0, 0, rootdir, -1); |
789 | 86 |
|
87 |
if (error) { |
|
88 |
vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; |
|
89 |
return (error); |
|
90 |
} |
|
91 |
||
92 |
vf->vf_vnode = vp; |
|
93 |
||
94 |
#ifdef _KERNEL |
|
95 |
/* |
|
96 |
* Make sure it's a regular file. |
|
97 |
*/ |
|
98 |
if (vp->v_type != VREG) { |
|
99 |
vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; |
|
100 |
return (ENODEV); |
|
101 |
} |
|
102 |
#endif |
|
10850
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
103 |
|
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
104 |
skip_open: |
789 | 105 |
/* |
106 |
* Determine the physical size of the file. |
|
107 |
*/ |
|
108 |
vattr.va_mask = AT_SIZE; |
|
5331 | 109 |
error = VOP_GETATTR(vf->vf_vnode, &vattr, 0, kcred, NULL); |
789 | 110 |
if (error) { |
111 |
vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; |
|
112 |
return (error); |
|
113 |
} |
|
114 |
||
115 |
*psize = vattr.va_size; |
|
116 |
*ashift = SPA_MINBLOCKSHIFT; |
|
117 |
||
118 |
return (0); |
|
119 |
} |
|
120 |
||
121 |
static void |
|
122 |
vdev_file_close(vdev_t *vd) |
|
123 |
{ |
|
124 |
vdev_file_t *vf = vd->vdev_tsd; |
|
125 |
||
10850
bb29ac73664d
6840704 osol_0906 PV guests sometimes hang at login prompt
George Wilson <George.Wilson@Sun.COM>
parents:
8241
diff
changeset
|
126 |
if (vd->vdev_reopening || vf == NULL) |
789 | 127 |
return; |
128 |
||
129 |
if (vf->vf_vnode != NULL) { |
|
5331 | 130 |
(void) VOP_PUTPAGE(vf->vf_vnode, 0, 0, B_INVAL, kcred, NULL); |
8241
5a60f16123ba
6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
7754
diff
changeset
|
131 |
(void) VOP_CLOSE(vf->vf_vnode, spa_mode(vd->vdev_spa), 1, 0, |
5a60f16123ba
6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
7754
diff
changeset
|
132 |
kcred, NULL); |
789 | 133 |
VN_RELE(vf->vf_vnode); |
134 |
} |
|
135 |
||
12247
5bcd281629f8
6911420 ZFS device removal detection should work with SCSAv3
George Wilson <George.Wilson@Sun.COM>
parents:
11958
diff
changeset
|
136 |
vd->vdev_delayed_close = B_FALSE; |
789 | 137 |
kmem_free(vf, sizeof (vdev_file_t)); |
138 |
vd->vdev_tsd = NULL; |
|
139 |
} |
|
140 |
||
5329 | 141 |
static int |
789 | 142 |
vdev_file_io_start(zio_t *zio) |
143 |
{ |
|
144 |
vdev_t *vd = zio->io_vd; |
|
145 |
vdev_file_t *vf = vd->vdev_tsd; |
|
146 |
ssize_t resid; |
|
147 |
||
148 |
if (zio->io_type == ZIO_TYPE_IOCTL) { |
|
149 |
/* XXPOLICY */ |
|
5329 | 150 |
if (!vdev_readable(vd)) { |
789 | 151 |
zio->io_error = ENXIO; |
5530 | 152 |
return (ZIO_PIPELINE_CONTINUE); |
789 | 153 |
} |
154 |
||
155 |
switch (zio->io_cmd) { |
|
156 |
case DKIOCFLUSHWRITECACHE: |
|
157 |
zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC, |
|
5331 | 158 |
kcred, NULL); |
789 | 159 |
break; |
160 |
default: |
|
161 |
zio->io_error = ENOTSUP; |
|
162 |
} |
|
163 |
||
5530 | 164 |
return (ZIO_PIPELINE_CONTINUE); |
789 | 165 |
} |
166 |
||
167 |
zio->io_error = vn_rdwr(zio->io_type == ZIO_TYPE_READ ? |
|
168 |
UIO_READ : UIO_WRITE, vf->vf_vnode, zio->io_data, |
|
169 |
zio->io_size, zio->io_offset, UIO_SYSSPACE, |
|
170 |
0, RLIM64_INFINITY, kcred, &resid); |
|
171 |
||
172 |
if (resid != 0 && zio->io_error == 0) |
|
173 |
zio->io_error = ENOSPC; |
|
174 |
||
5530 | 175 |
zio_interrupt(zio); |
176 |
||
177 |
return (ZIO_PIPELINE_STOP); |
|
789 | 178 |
} |
179 |
||
7754
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
6976
diff
changeset
|
180 |
/* ARGSUSED */ |
b80e4842ad54
6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
6976
diff
changeset
|
181 |
static void |
789 | 182 |
vdev_file_io_done(zio_t *zio) |
183 |
{ |
|
184 |
} |
|
185 |
||
186 |
vdev_ops_t vdev_file_ops = { |
|
187 |
vdev_file_open, |
|
188 |
vdev_file_close, |
|
189 |
vdev_default_asize, |
|
190 |
vdev_file_io_start, |
|
191 |
vdev_file_io_done, |
|
192 |
NULL, |
|
11958
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
193 |
vdev_file_hold, |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
194 |
vdev_file_rele, |
789 | 195 |
VDEV_TYPE_FILE, /* name of this vdev type */ |
196 |
B_TRUE /* leaf vdev */ |
|
197 |
}; |
|
198 |
||
199 |
/* |
|
200 |
* From userland we access disks just like files. |
|
201 |
*/ |
|
202 |
#ifndef _KERNEL |
|
203 |
||
204 |
vdev_ops_t vdev_disk_ops = { |
|
205 |
vdev_file_open, |
|
206 |
vdev_file_close, |
|
207 |
vdev_default_asize, |
|
208 |
vdev_file_io_start, |
|
209 |
vdev_file_io_done, |
|
210 |
NULL, |
|
11958
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
211 |
vdev_file_hold, |
575ffe1e978d
6923585 deadlock while booting OpenSolaris build 132 from mirrored rpool with removed submirror
George Wilson <George.Wilson@Sun.COM>
parents:
10850
diff
changeset
|
212 |
vdev_file_rele, |
789 | 213 |
VDEV_TYPE_DISK, /* name of this vdev type */ |
214 |
B_TRUE /* leaf vdev */ |
|
215 |
}; |
|
216 |
||
217 |
#endif |