1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
--- 18 unchanged lines hidden (view full) ---
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * $FreeBSD: head/sys/geom/geom_disk.c 111668 2003-02-28 10:02:02Z phk $
36 */
37
38#include "opt_geom.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43#include <sys/sysctl.h>
--- 47 unchanged lines hidden (view full) ---
91 return;
92 mtx_unlock(&Giant);
93}
94
95static int
96g_disk_access(struct g_provider *pp, int r, int w, int e)
97{
98 struct disk *dp;
99 int error;
100
101 g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)",
102 pp->name, r, w, e);
103 g_topology_assert();
104 r += pp->acr;
105 w += pp->acw;
106 e += pp->ace;
107 dp = pp->geom->softc;
108 error = 0;
109 if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
110 if (dp->d_open != NULL) {
111 g_disk_lock_giant(dp);
112 error = dp->d_open(dp);
113 if (error != 0)
114 printf("Opened disk %s -> %d\n",
115 pp->name, error);
116 g_disk_unlock_giant(dp);
117 }
118 pp->mediasize = dp->d_mediasize;
119 pp->sectorsize = dp->d_sectorsize;
120 dp->d_flags |= DISKFLAG_OPEN;
121 if (dp->d_maxsize == 0) {
122 printf("WARNING: Disk drive %s%d has no d_maxsize\n",
123 dp->d_name, dp->d_unit);
124 dp->d_maxsize = DFLTPHYS;
125 }
126 } else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) == 0) {
127 if (dp->d_close != NULL) {
128 g_disk_lock_giant(dp);
129 error = dp->d_close(dp);
130 if (error != 0)
131 printf("Closed disk %s -> %d\n",
132 pp->name, error);
133 g_disk_unlock_giant(dp);
134 }
135 dp->d_flags &= ~DISKFLAG_OPEN;
136 }
137 return (error);
--- 31 unchanged lines hidden (view full) ---
169 g_std_done(bp);
170 mtx_unlock(&g_disk_done_mtx);
171}
172
173static void
174g_disk_start(struct bio *bp)
175{
176 struct bio *bp2, *bp3;
177 struct disk *dp;
178 struct g_ioctl *gio;
179 int error;
180 off_t off;
181
182 dp = bp->bio_to->geom->softc;
183 error = EJUSTRETURN;
184 switch(bp->bio_cmd) {
185 case BIO_DELETE:
186 if (!(dp->d_flags & DISKFLAG_CANDELETE)) {
187 error = 0;
188 break;
189 }
190 /* fall-through */
--- 24 unchanged lines hidden (view full) ---
215 bp3 = g_clone_bio(bp);
216 if (bp3 == NULL)
217 bp->bio_error = ENOMEM;
218 }
219 bp2->bio_done = g_disk_done;
220 bp2->bio_blkno = bp2->bio_offset >> DEV_BSHIFT;
221 bp2->bio_pblkno = bp2->bio_offset / dp->d_sectorsize;
222 bp2->bio_bcount = bp2->bio_length;
223 bp2->bio_disk = dp;
224 g_disk_lock_giant(dp);
225 dp->d_strategy(bp2);
226 g_disk_unlock_giant(dp);
227 bp2 = bp3;
228 bp3 = NULL;
229 } while (bp2 != NULL);
230 break;
231 case BIO_GETATTR:
232 if (g_handleattr_int(bp, "GEOM::fwsectors", dp->d_fwsectors))
233 break;
234 else if (g_handleattr_int(bp, "GEOM::fwheads", dp->d_fwheads))
235 break;
236 else if (g_handleattr_off_t(bp, "GEOM::frontstuff", 0))
237 break;
238 else if (!strcmp(bp->bio_attribute, "GEOM::kerneldump"))
239 g_disk_kerneldump(bp, dp);
240 else if ((dp->d_ioctl != NULL) &&
241 !strcmp(bp->bio_attribute, "GEOM::ioctl") &&
242 bp->bio_length == sizeof *gio) {
243 gio = (struct g_ioctl *)bp->bio_data;
244 gio->dev = dp;
245 gio->func = (d_ioctl_t *)(dp->d_ioctl);
246 error = EDIRIOCTL;
247 } else
248 error = ENOIOCTL;
249 break;
250 case BIO_SETATTR:
251 error = ENOIOCTL;
252 break;
253 default:
254 error = EOPNOTSUPP;
255 break;
256 }
257 if (error != EJUSTRETURN)
258 g_io_deliver(bp, error);
259 return;
--- 42 unchanged lines hidden (view full) ---
302 pp->stripesize = dp->d_stripesize;
303 g_error_provider(pp, 0);
304 if (bootverbose)
305 printf("GEOM: new disk %s\n", gp->name);
306}
307
308
309
310void
311disk_create(int unit, struct disk *dp, int flags, void *unused __unused, void * unused2 __unused)
312{
313
314 dp->d_unit = unit;
315 dp->d_flags = flags;
316 KASSERT(dp->d_strategy != NULL, ("disk_create need d_strategy"));
317 KASSERT(dp->d_name != NULL, ("disk_create need d_name"));
318 KASSERT(*dp->d_name != 0, ("disk_create need d_name"));
319 KASSERT(strlen(dp->d_name) < SPECNAMELEN - 4, ("disk name too long"));
320 g_call_me(g_disk_create, dp);
321}
322
323void
324disk_destroy(struct disk *dp)
325{
326 struct g_geom *gp;
327
328 gp = dp->d_geom;
329 gp->flags |= G_GEOM_WITHER;
330 gp->softc = NULL;
331 g_orphan_provider(LIST_FIRST(&gp->provider), ENXIO);
332}
333
334static void
335g_kern_disks(void *p)
336{
--- 35 unchanged lines hidden ---
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
--- 18 unchanged lines hidden (view full) ---
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * $FreeBSD: head/sys/geom/geom_disk.c 111668 2003-02-28 10:02:02Z phk $
36 */
37
38#include "opt_geom.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43#include <sys/sysctl.h>
--- 47 unchanged lines hidden (view full) ---
91 return;
92 mtx_unlock(&Giant);
93}
94
95static int
96g_disk_access(struct g_provider *pp, int r, int w, int e)
97{
98 struct disk *dp;
99 int error;
100
101 g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)",
102 pp->name, r, w, e);
103 g_topology_assert();
104 r += pp->acr;
105 w += pp->acw;
106 e += pp->ace;
107 dp = pp->geom->softc;
108 error = 0;
109 if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
110 if (dp->d_open != NULL) {
111 g_disk_lock_giant(dp);
112 error = dp->d_open(dp);
113 if (error != 0)
114 printf("Opened disk %s -> %d\n",
115 pp->name, error);
116 g_disk_unlock_giant(dp);
117 }
118 pp->mediasize = dp->d_mediasize;
119 pp->sectorsize = dp->d_sectorsize;
120 dp->d_flags |= DISKFLAG_OPEN;
121 if (dp->d_maxsize == 0) {
122 printf("WARNING: Disk drive %s%d has no d_maxsize\n",
123 dp->d_name, dp->d_unit);
124 dp->d_maxsize = DFLTPHYS;
125 }
126 } else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) == 0) {
127 if (dp->d_close != NULL) {
128 g_disk_lock_giant(dp);
129 error = dp->d_close(dp);
130 if (error != 0)
131 printf("Closed disk %s -> %d\n",
132 pp->name, error);
133 g_disk_unlock_giant(dp);
134 }
135 dp->d_flags &= ~DISKFLAG_OPEN;
136 }
137 return (error);
--- 31 unchanged lines hidden (view full) ---
169 g_std_done(bp);
170 mtx_unlock(&g_disk_done_mtx);
171}
172
173static void
174g_disk_start(struct bio *bp)
175{
176 struct bio *bp2, *bp3;
177 struct disk *dp;
178 struct g_ioctl *gio;
179 int error;
180 off_t off;
181
182 dp = bp->bio_to->geom->softc;
183 error = EJUSTRETURN;
184 switch(bp->bio_cmd) {
185 case BIO_DELETE:
186 if (!(dp->d_flags & DISKFLAG_CANDELETE)) {
187 error = 0;
188 break;
189 }
190 /* fall-through */
--- 24 unchanged lines hidden (view full) ---
215 bp3 = g_clone_bio(bp);
216 if (bp3 == NULL)
217 bp->bio_error = ENOMEM;
218 }
219 bp2->bio_done = g_disk_done;
220 bp2->bio_blkno = bp2->bio_offset >> DEV_BSHIFT;
221 bp2->bio_pblkno = bp2->bio_offset / dp->d_sectorsize;
222 bp2->bio_bcount = bp2->bio_length;
223 bp2->bio_disk = dp;
224 g_disk_lock_giant(dp);
225 dp->d_strategy(bp2);
226 g_disk_unlock_giant(dp);
227 bp2 = bp3;
228 bp3 = NULL;
229 } while (bp2 != NULL);
230 break;
231 case BIO_GETATTR:
232 if (g_handleattr_int(bp, "GEOM::fwsectors", dp->d_fwsectors))
233 break;
234 else if (g_handleattr_int(bp, "GEOM::fwheads", dp->d_fwheads))
235 break;
236 else if (g_handleattr_off_t(bp, "GEOM::frontstuff", 0))
237 break;
238 else if (!strcmp(bp->bio_attribute, "GEOM::kerneldump"))
239 g_disk_kerneldump(bp, dp);
240 else if ((dp->d_ioctl != NULL) &&
241 !strcmp(bp->bio_attribute, "GEOM::ioctl") &&
242 bp->bio_length == sizeof *gio) {
243 gio = (struct g_ioctl *)bp->bio_data;
244 gio->dev = dp;
245 gio->func = (d_ioctl_t *)(dp->d_ioctl);
246 error = EDIRIOCTL;
247 } else
248 error = ENOIOCTL;
249 break;
250 case BIO_SETATTR:
251 error = ENOIOCTL;
252 break;
253 default:
254 error = EOPNOTSUPP;
255 break;
256 }
257 if (error != EJUSTRETURN)
258 g_io_deliver(bp, error);
259 return;
--- 42 unchanged lines hidden (view full) ---
302 pp->stripesize = dp->d_stripesize;
303 g_error_provider(pp, 0);
304 if (bootverbose)
305 printf("GEOM: new disk %s\n", gp->name);
306}
307
308
309
310void
311disk_create(int unit, struct disk *dp, int flags, void *unused __unused, void * unused2 __unused)
312{
313
314 dp->d_unit = unit;
315 dp->d_flags = flags;
316 KASSERT(dp->d_strategy != NULL, ("disk_create need d_strategy"));
317 KASSERT(dp->d_name != NULL, ("disk_create need d_name"));
318 KASSERT(*dp->d_name != 0, ("disk_create need d_name"));
319 KASSERT(strlen(dp->d_name) < SPECNAMELEN - 4, ("disk name too long"));
320 g_call_me(g_disk_create, dp);
321}
322
323void
324disk_destroy(struct disk *dp)
325{
326 struct g_geom *gp;
327
328 gp = dp->d_geom;
329 gp->flags |= G_GEOM_WITHER;
330 gp->softc = NULL;
331 g_orphan_provider(LIST_FIRST(&gp->provider), ENXIO);
332}
333
334static void
335g_kern_disks(void *p)
336{
--- 35 unchanged lines hidden ---