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
--- 20 unchanged lines hidden (view full) ---
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
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/sys/geom/geom_disk.c 125975 2004-02-18 21:36:53Z phk $");
38
39#include "opt_geom.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/kernel.h>
44#include <sys/sysctl.h>
45#include <sys/bio.h>
--- 36 unchanged lines hidden (view full) ---
82 mtx_destroy(&g_disk_done_mtx);
83}
84
85DECLARE_GEOM_CLASS(g_disk_class, g_disk);
86
87static void __inline
88g_disk_lock_giant(struct disk *dp)
89{
90 if (dp->d_flags & DISKFLAG_NEEDSGIANT)
91 mtx_lock(&Giant);
92}
93
94static void __inline
95g_disk_unlock_giant(struct disk *dp)
96{
97 if (dp->d_flags & DISKFLAG_NEEDSGIANT)
98 mtx_unlock(&Giant);
99}
100
101static int
102g_disk_access(struct g_provider *pp, int r, int w, int e)
103{
104 struct disk *dp;
105 int error;
106
107 g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)",
108 pp->name, r, w, e);
109 g_topology_assert();
110 dp = pp->geom->softc;
111 if (dp == NULL || dp->d_destroyed) {
112 /*
113 * Allow decreasing access count even if disk is not
114 * avaliable anymore.
115 */
116 if (r <= 0 && w <= 0 && e <= 0)
117 return (0);
118 return (ENXIO);
119 }
120 r += pp->acr;
121 w += pp->acw;
122 e += pp->ace;
123 error = 0;
124 if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
125 if (dp->d_open != NULL) {
126 g_disk_lock_giant(dp);
--- 98 unchanged lines hidden (view full) ---
225g_disk_start(struct bio *bp)
226{
227 struct bio *bp2, *bp3;
228 struct disk *dp;
229 int error;
230 off_t off;
231
232 dp = bp->bio_to->geom->softc;
233 if (dp == NULL || dp->d_destroyed)
234 g_io_deliver(bp, ENXIO);
235 error = EJUSTRETURN;
236 switch(bp->bio_cmd) {
237 case BIO_DELETE:
238 if (!(dp->d_flags & DISKFLAG_CANDELETE)) {
239 error = 0;
240 break;
241 }
--- 108 unchanged lines hidden (view full) ---
350 printf("GEOM: new disk %s\n", gp->name);
351 dp->d_geom = gp;
352 g_error_provider(pp, 0);
353}
354
355static void
356g_disk_destroy(void *ptr, int flag)
357{
358 struct disk *dp;
359 struct g_geom *gp;
360
361 g_topology_assert();
362 dp = ptr;
363 gp = dp->d_geom;
364 gp->softc = NULL;
365 g_wither_geom(gp, ENXIO);
366 g_free(dp);
367}
368
369struct disk *
370disk_alloc()
371{
372 struct disk *dp;
373
374 dp = g_malloc(sizeof *dp, M_WAITOK | M_ZERO);
375 return (dp);
376}
377
378void
379disk_create(struct disk *dp, int version)
380{
381 if (version != DISK_VERSION_00) {
382 printf("WARNING: Attempt to add disk %s%d %s",
383 dp->d_name, dp->d_unit,
384 " using incompatible ABI version of disk(9)\n");
385 printf("WARNING: Ignoring disk %s%d\n",
386 dp->d_name, dp->d_unit);
387 return;
388 }
389 KASSERT(dp->d_strategy != NULL, ("disk_create need d_strategy"));
390 KASSERT(dp->d_name != NULL, ("disk_create need d_name"));
391 KASSERT(*dp->d_name != 0, ("disk_create need d_name"));
392 KASSERT(strlen(dp->d_name) < SPECNAMELEN - 4, ("disk name too long"));
393 if (dp->d_devstat == NULL)
394 dp->d_devstat = devstat_new_entry(dp->d_name, dp->d_unit,
395 dp->d_sectorsize, DEVSTAT_ALL_SUPPORTED,
396 DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX);
397 dp->d_geom = NULL;
398 g_post_event(g_disk_create, dp, M_WAITOK, dp, NULL);
399}
400
401void
402disk_destroy(struct disk *dp)
403{
404
405 g_cancel_event(dp);
406 dp->d_destroyed = 1;
407 g_post_event(g_disk_destroy, dp, M_WAITOK, NULL, NULL);
408}
409
410static void
411g_kern_disks(void *p, int flag __unused)
412{
413 struct sbuf *sb;
414 struct g_geom *gp;
415 char *sp;
--- 27 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
--- 20 unchanged lines hidden (view full) ---
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
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/sys/geom/geom_disk.c 125975 2004-02-18 21:36:53Z phk $");
38
39#include "opt_geom.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/kernel.h>
44#include <sys/sysctl.h>
45#include <sys/bio.h>
--- 36 unchanged lines hidden (view full) ---
82 mtx_destroy(&g_disk_done_mtx);
83}
84
85DECLARE_GEOM_CLASS(g_disk_class, g_disk);
86
87static void __inline
88g_disk_lock_giant(struct disk *dp)
89{
90 if (dp->d_flags & DISKFLAG_NEEDSGIANT)
91 mtx_lock(&Giant);
92}
93
94static void __inline
95g_disk_unlock_giant(struct disk *dp)
96{
97 if (dp->d_flags & DISKFLAG_NEEDSGIANT)
98 mtx_unlock(&Giant);
99}
100
101static int
102g_disk_access(struct g_provider *pp, int r, int w, int e)
103{
104 struct disk *dp;
105 int error;
106
107 g_trace(G_T_ACCESS, "g_disk_access(%s, %d, %d, %d)",
108 pp->name, r, w, e);
109 g_topology_assert();
110 dp = pp->geom->softc;
111 if (dp == NULL || dp->d_destroyed) {
112 /*
113 * Allow decreasing access count even if disk is not
114 * avaliable anymore.
115 */
116 if (r <= 0 && w <= 0 && e <= 0)
117 return (0);
118 return (ENXIO);
119 }
120 r += pp->acr;
121 w += pp->acw;
122 e += pp->ace;
123 error = 0;
124 if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
125 if (dp->d_open != NULL) {
126 g_disk_lock_giant(dp);
--- 98 unchanged lines hidden (view full) ---
225g_disk_start(struct bio *bp)
226{
227 struct bio *bp2, *bp3;
228 struct disk *dp;
229 int error;
230 off_t off;
231
232 dp = bp->bio_to->geom->softc;
233 if (dp == NULL || dp->d_destroyed)
234 g_io_deliver(bp, ENXIO);
235 error = EJUSTRETURN;
236 switch(bp->bio_cmd) {
237 case BIO_DELETE:
238 if (!(dp->d_flags & DISKFLAG_CANDELETE)) {
239 error = 0;
240 break;
241 }
--- 108 unchanged lines hidden (view full) ---
350 printf("GEOM: new disk %s\n", gp->name);
351 dp->d_geom = gp;
352 g_error_provider(pp, 0);
353}
354
355static void
356g_disk_destroy(void *ptr, int flag)
357{
358 struct disk *dp;
359 struct g_geom *gp;
360
361 g_topology_assert();
362 dp = ptr;
363 gp = dp->d_geom;
364 gp->softc = NULL;
365 g_wither_geom(gp, ENXIO);
366 g_free(dp);
367}
368
369struct disk *
370disk_alloc()
371{
372 struct disk *dp;
373
374 dp = g_malloc(sizeof *dp, M_WAITOK | M_ZERO);
375 return (dp);
376}
377
378void
379disk_create(struct disk *dp, int version)
380{
381 if (version != DISK_VERSION_00) {
382 printf("WARNING: Attempt to add disk %s%d %s",
383 dp->d_name, dp->d_unit,
384 " using incompatible ABI version of disk(9)\n");
385 printf("WARNING: Ignoring disk %s%d\n",
386 dp->d_name, dp->d_unit);
387 return;
388 }
389 KASSERT(dp->d_strategy != NULL, ("disk_create need d_strategy"));
390 KASSERT(dp->d_name != NULL, ("disk_create need d_name"));
391 KASSERT(*dp->d_name != 0, ("disk_create need d_name"));
392 KASSERT(strlen(dp->d_name) < SPECNAMELEN - 4, ("disk name too long"));
393 if (dp->d_devstat == NULL)
394 dp->d_devstat = devstat_new_entry(dp->d_name, dp->d_unit,
395 dp->d_sectorsize, DEVSTAT_ALL_SUPPORTED,
396 DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX);
397 dp->d_geom = NULL;
398 g_post_event(g_disk_create, dp, M_WAITOK, dp, NULL);
399}
400
401void
402disk_destroy(struct disk *dp)
403{
404
405 g_cancel_event(dp);
406 dp->d_destroyed = 1;
407 g_post_event(g_disk_destroy, dp, M_WAITOK, NULL, NULL);
408}
409
410static void
411g_kern_disks(void *p, int flag __unused)
412{
413 struct sbuf *sb;
414 struct g_geom *gp;
415 char *sp;
--- 27 unchanged lines hidden ---