diff options
Diffstat (limited to 'sys/geom')
30 files changed, 218 insertions, 138 deletions
diff --git a/sys/geom/cache/g_cache.c b/sys/geom/cache/g_cache.c index 9d0b10f4192e..c6b80786ade5 100644 --- a/sys/geom/cache/g_cache.c +++ b/sys/geom/cache/g_cache.c @@ -504,7 +504,7 @@ g_cache_create(struct g_class *mp, struct g_provider *pp, return (NULL); } - gp = g_new_geomf(mp, "%s", md->md_name); + gp = g_new_geom(mp, md->md_name); sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); sc->sc_type = type; sc->sc_bshift = bshift; @@ -665,7 +665,7 @@ g_cache_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) G_CACHE_DEBUG(3, "Tasting %s.", pp->name); - gp = g_new_geomf(mp, "cache:taste"); + gp = g_new_geom(mp, "cache:taste"); gp->start = g_cache_start; gp->orphan = g_cache_orphan; gp->access = g_cache_access; diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c index 2b1cb575cac8..5461c6dd73d3 100644 --- a/sys/geom/concat/g_concat.c +++ b/sys/geom/concat/g_concat.c @@ -590,6 +590,7 @@ g_concat_add_disk(struct g_concat_softc *sc, struct g_provider *pp, u_int no) strcmp(md.md_name, sc->sc_name) != 0 || md.md_id != sc->sc_id) { G_CONCAT_DEBUG(0, "Metadata on %s changed.", pp->name); + error = EINVAL; goto fail; } @@ -645,7 +646,7 @@ g_concat_create(struct g_class *mp, const struct g_concat_metadata *md, return (NULL); } } - gp = g_new_geomf(mp, "%s", md->md_name); + gp = g_new_geom(mp, md->md_name); sc = malloc(sizeof(*sc), M_CONCAT, M_WAITOK | M_ZERO); gp->start = g_concat_start; gp->spoiled = g_concat_orphan; @@ -752,7 +753,7 @@ g_concat_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) G_CONCAT_DEBUG(3, "Tasting %s.", pp->name); - gp = g_new_geomf(mp, "concat:taste"); + gp = g_new_geom(mp, "concat:taste"); gp->start = g_concat_start; gp->access = g_concat_access; gp->orphan = g_concat_orphan; @@ -1106,8 +1107,6 @@ g_concat_ctl_append(struct gctl_req *req, struct g_class *mp) gctl_error(req, "No 'arg%u' argument.", 1); goto fail; } - if (strncmp(name, "/dev/", strlen("/dev/")) == 0) - name += strlen("/dev/"); pp = g_provider_by_name(name); if (pp == NULL) { G_CONCAT_DEBUG(1, "Disk %s is invalid.", name); diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 5bd2d465183e..7fca50e7635c 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -769,7 +769,7 @@ g_eli_read_metadata_offset(struct g_class *mp, struct g_provider *pp, g_topology_assert(); - gp = g_new_geomf(mp, "eli:taste"); + gp = g_new_geom(mp, "eli:taste"); gp->start = g_eli_start; gp->access = g_std_access; /* diff --git a/sys/geom/gate/g_gate.c b/sys/geom/gate/g_gate.c index ecdcacff6707..76a4328227dd 100644 --- a/sys/geom/gate/g_gate.c +++ b/sys/geom/gate/g_gate.c @@ -571,7 +571,7 @@ g_gate_create(struct g_gate_ctl_create *ggio) } } - gp = g_new_geomf(&g_gate_class, "%s", name); + gp = g_new_geom(&g_gate_class, name); gp->start = g_gate_start; gp->access = g_gate_access; gp->orphan = g_gate_orphan; diff --git a/sys/geom/geom.h b/sys/geom/geom.h index dcd6f793f9f7..50e6627b0157 100644 --- a/sys/geom/geom.h +++ b/sys/geom/geom.h @@ -282,15 +282,16 @@ void g_detach(struct g_consumer *cp); void g_error_provider(struct g_provider *pp, int error); struct g_provider *g_provider_by_name(char const *arg); int g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len); -#define g_getattr(a, c, v) g_getattr__((a), (c), (v), sizeof *(v)) +#define g_getattr(a, c, v) g_getattr__((a), (c), (v), sizeof(*(v))) int g_handleattr(struct bio *bp, const char *attribute, const void *val, int len); int g_handleattr_int(struct bio *bp, const char *attribute, int val); int g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val); int g_handleattr_uint16_t(struct bio *bp, const char *attribute, uint16_t val); int g_handleattr_str(struct bio *bp, const char *attribute, const char *str); -struct g_consumer * g_new_consumer(struct g_geom *gp); -struct g_geom * g_new_geomf(struct g_class *mp, const char *fmt, ...) +struct g_consumer *g_new_consumer(struct g_geom *gp); +struct g_geom *g_new_geom(struct g_class *mp, const char *name); +struct g_geom *g_new_geomf(struct g_class *mp, const char *fmt, ...) __printflike(2, 3); struct g_provider * g_new_providerf(struct g_geom *gp, const char *fmt, ...) __printflike(2, 3); diff --git a/sys/geom/geom_ccd.c b/sys/geom/geom_ccd.c index 5700399ee5d1..2140d005160e 100644 --- a/sys/geom/geom_ccd.c +++ b/sys/geom/geom_ccd.c @@ -730,17 +730,17 @@ g_ccd_create(struct gctl_req *req, struct g_class *mp) int i, error; g_topology_assert(); - unit = gctl_get_paraml(req, "unit", sizeof (*unit)); + unit = gctl_get_paraml(req, "unit", sizeof(*unit)); if (unit == NULL) { gctl_error(req, "unit parameter not given"); return; } - ileave = gctl_get_paraml(req, "ileave", sizeof (*ileave)); + ileave = gctl_get_paraml(req, "ileave", sizeof(*ileave)); if (ileave == NULL) { gctl_error(req, "ileave parameter not given"); return; } - nprovider = gctl_get_paraml(req, "nprovider", sizeof (*nprovider)); + nprovider = gctl_get_paraml(req, "nprovider", sizeof(*nprovider)); if (nprovider == NULL) { gctl_error(req, "nprovider parameter not given"); return; @@ -769,7 +769,7 @@ g_ccd_create(struct gctl_req *req, struct g_class *mp) } gp = g_new_geomf(mp, "ccd%d", *unit); - sc = g_malloc(sizeof *sc, M_WAITOK | M_ZERO); + sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); gp->softc = sc; sc->sc_ndisks = *nprovider; @@ -872,7 +872,7 @@ g_ccd_list(struct gctl_req *req, struct g_class *mp) struct g_geom *gp; int i, unit, *up; - up = gctl_get_paraml(req, "unit", sizeof (*up)); + up = gctl_get_paraml(req, "unit", sizeof(*up)); if (up == NULL) { gctl_error(req, "unit parameter not given"); return; diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index 4a2a850c2eab..a723d06334a0 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -82,6 +82,7 @@ static const struct filterops gdev_filterops_vnode = { .f_isfd = 1, .f_detach = gdev_filter_detach, .f_event = gdev_filter_vnode, + .f_copy = knote_triv_copy, }; static struct cdevsw g_dev_cdevsw = { @@ -355,7 +356,7 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused) g_trace(G_T_TOPOLOGY, "dev_taste(%s,%s)", mp->name, pp->name); g_topology_assert(); - gp = g_new_geomf(mp, "%s", pp->name); + gp = g_new_geom(mp, pp->name); sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); mtx_init(&sc->sc_mtx, "g_dev", NULL, MTX_DEF); cp = g_new_consumer(gp); @@ -733,6 +734,10 @@ g_dev_done(struct bio *bp2) g_trace(G_T_BIO, "g_dev_done(%p) had error %d", bp2, bp2->bio_error); bp->bio_flags |= BIO_ERROR; + if ((bp2->bio_flags & BIO_EXTERR) != 0) { + bp->bio_flags |= BIO_EXTERR; + bp->bio_exterr = bp2->bio_exterr; + } } else { if (bp->bio_cmd == BIO_READ) KNOTE_UNLOCKED(&sc->sc_selinfo.si_note, NOTE_READ); diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c index 9dbf00371dba..b267130d1e0c 100644 --- a/sys/geom/geom_disk.c +++ b/sys/geom/geom_disk.c @@ -235,8 +235,14 @@ g_disk_done(struct bio *bp) bp2 = bp->bio_parent; binuptime(&now); mtx_lock(&sc->done_mtx); - if (bp2->bio_error == 0) - bp2->bio_error = bp->bio_error; + if (bp2->bio_error == 0) { + if ((bp->bio_flags & BIO_EXTERR) != 0) { + bp2->bio_flags |= BIO_EXTERR; + bp2->bio_exterr = bp->bio_exterr; + } else { + bp2->bio_error = bp->bio_error; + } + } bp2->bio_completed += bp->bio_length - bp->bio_resid; if (bp->bio_cmd == BIO_READ) diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c index 0a76fd6c6f57..ffd46db55416 100644 --- a/sys/geom/geom_event.c +++ b/sys/geom/geom_event.c @@ -145,7 +145,7 @@ g_attr_changed(struct g_provider *pp, const char *attr, int flag) struct g_attrchanged_args *args; int error; - args = g_malloc(sizeof *args, flag); + args = g_malloc(sizeof(*args), flag); if (args == NULL) return (ENOMEM); args->pp = pp; @@ -347,6 +347,7 @@ static void g_post_event_ep_va(g_event_t *func, void *arg, int wuflag, struct g_event *ep, va_list ap) { + struct thread *td; void *p; u_int n; @@ -366,8 +367,12 @@ g_post_event_ep_va(g_event_t *func, void *arg, int wuflag, TAILQ_INSERT_TAIL(&g_events, ep, events); mtx_unlock(&g_eventlock); wakeup(&g_wait_event); - curthread->td_pflags |= TDP_GEOM; - ast_sched(curthread, TDA_GEOM); + + td = curthread; + if ((td->td_pflags & TDP_KTHREAD) == 0) { + td->td_pflags |= TDP_GEOM; + ast_sched(td, TDA_GEOM); + } } void diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index 8d6b9a926e1d..247a623bf1bf 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -278,7 +278,7 @@ g_io_init(void) g_bioq_init(&g_bio_run_down); g_bioq_init(&g_bio_run_up); - biozone = uma_zcreate("g_bio", sizeof (struct bio), + biozone = uma_zcreate("g_bio", sizeof(struct bio), NULL, NULL, NULL, NULL, 0, 0); diff --git a/sys/geom/geom_slice.c b/sys/geom/geom_slice.c index 8cfffc478849..935293950c37 100644 --- a/sys/geom/geom_slice.c +++ b/sys/geom/geom_slice.c @@ -57,7 +57,7 @@ g_slice_alloc(unsigned nslice, unsigned scsize) { struct g_slicer *gsp; - gsp = g_malloc(sizeof *gsp, M_WAITOK | M_ZERO); + gsp = g_malloc(sizeof(*gsp), M_WAITOK | M_ZERO); if (scsize > 0) gsp->softc = g_malloc(scsize, M_WAITOK | M_ZERO); else @@ -463,9 +463,9 @@ g_slice_conf_hot(struct g_geom *gp, u_int idx, off_t offset, off_t length, int r } gsl = gsp->hotspot; if(idx >= gsp->nhotspot) { - gsl2 = g_malloc((idx + 1) * sizeof *gsl2, M_WAITOK | M_ZERO); + gsl2 = g_malloc((idx + 1) * sizeof(*gsl2), M_WAITOK | M_ZERO); if (gsp->hotspot != NULL) - bcopy(gsp->hotspot, gsl2, gsp->nhotspot * sizeof *gsl2); + bcopy(gsp->hotspot, gsl2, gsp->nhotspot * sizeof(*gsl2)); gsp->hotspot = gsl2; if (gsp->hotspot != NULL) g_free(gsl); @@ -529,7 +529,7 @@ g_slice_new(struct g_class *mp, u_int slices, struct g_provider *pp, struct g_co g_topology_assert(); vp = (void **)extrap; - gp = g_new_geomf(mp, "%s", pp->name); + gp = g_new_geom(mp, pp->name); gsp = g_slice_alloc(slices, extra); gsp->start = start; gp->softc = gsp; diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index 41cc115225f9..c5dce730da79 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -38,9 +38,11 @@ #include <sys/cdefs.h> #include "opt_ddb.h" +#define EXTERR_CATEGORY EXTERR_CAT_GEOM #include <sys/param.h> #include <sys/systm.h> #include <sys/devicestat.h> +#include <sys/exterrvar.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/bio.h> @@ -267,7 +269,7 @@ g_modevent(module_t mod, int type, void *data) switch (type) { case MOD_LOAD: g_trace(G_T_TOPOLOGY, "g_modevent(%s, LOAD)", mp->name); - hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO); + hh = g_malloc(sizeof(*hh), M_WAITOK | M_ZERO); hh->mp = mp; /* * Once the system is not cold, MOD_LOAD calls will be @@ -351,7 +353,7 @@ g_retaste(struct g_class *mp) if (mp->taste == NULL) return (EINVAL); - hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO); + hh = g_malloc(sizeof(*hh), M_WAITOK | M_ZERO); hh->mp = mp; if (cold) { @@ -368,29 +370,23 @@ g_retaste(struct g_class *mp) } struct g_geom * -g_new_geomf(struct g_class *mp, const char *fmt, ...) +g_new_geom(struct g_class *mp, const char *name) { + int len; struct g_geom *gp; - va_list ap; - struct sbuf *sb; g_topology_assert(); G_VALID_CLASS(mp); - sb = sbuf_new_auto(); - va_start(ap, fmt); - sbuf_vprintf(sb, fmt, ap); - va_end(ap); - sbuf_finish(sb); - gp = g_malloc(sizeof *gp, M_WAITOK | M_ZERO); - gp->name = g_malloc(sbuf_len(sb) + 1, M_WAITOK | M_ZERO); + len = strlen(name); + gp = g_malloc(sizeof(*gp) + len + 1, M_WAITOK | M_ZERO); + gp->name = (char *)(gp + 1); gp->class = mp; gp->rank = 1; LIST_INIT(&gp->consumer); LIST_INIT(&gp->provider); LIST_INSERT_HEAD(&mp->geom, gp, geom); TAILQ_INSERT_HEAD(&geoms, gp, geoms); - strcpy(gp->name, sbuf_data(sb)); - sbuf_delete(sb); + memcpy(gp->name, name, len); /* Fill in defaults from class */ gp->start = mp->start; gp->spoiled = mp->spoiled; @@ -404,6 +400,23 @@ g_new_geomf(struct g_class *mp, const char *fmt, ...) return (gp); } +struct g_geom * +g_new_geomf(struct g_class *mp, const char *fmt, ...) +{ + struct g_geom *gp; + va_list ap; + struct sbuf *sb; + + sb = sbuf_new_auto(); + va_start(ap, fmt); + sbuf_vprintf(sb, fmt, ap); + va_end(ap); + sbuf_finish(sb); + gp = g_new_geom(mp, sbuf_data(sb)); + sbuf_delete(sb); + return (gp); +} + void g_destroy_geom(struct g_geom *gp) { @@ -420,7 +433,6 @@ g_destroy_geom(struct g_geom *gp) g_cancel_event(gp); LIST_REMOVE(gp, geom); TAILQ_REMOVE(&geoms, gp, geoms); - g_free(gp->name); g_free(gp); } @@ -528,7 +540,7 @@ g_new_consumer(struct g_geom *gp) ("g_new_consumer on geom(%s) (class %s) without orphan", gp->name, gp->class->name)); - cp = g_malloc(sizeof *cp, M_WAITOK | M_ZERO); + cp = g_malloc(sizeof(*cp), M_WAITOK | M_ZERO); cp->geom = gp; cp->stat = devstat_new_entry(cp, -1, 0, DEVSTAT_ALL_SUPPORTED, DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX); @@ -617,7 +629,7 @@ g_new_providerf(struct g_geom *gp, const char *fmt, ...) sbuf_vprintf(sb, fmt, ap); va_end(ap); sbuf_finish(sb); - pp = g_malloc(sizeof *pp + sbuf_len(sb) + 1, M_WAITOK | M_ZERO); + pp = g_malloc(sizeof(*pp) + sbuf_len(sb) + 1, M_WAITOK | M_ZERO); pp->name = (char *)(pp + 1); strcpy(pp->name, sbuf_data(sb)); sbuf_delete(sb); @@ -749,7 +761,7 @@ g_resize_provider(struct g_provider *pp, off_t size) if (size == pp->mediasize) return; - hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO); + hh = g_malloc(sizeof(*hh), M_WAITOK | M_ZERO); hh->pp = pp; hh->size = size; g_post_event(g_resize_provider_event, hh, M_WAITOK, NULL); @@ -1083,21 +1095,21 @@ int g_handleattr_int(struct bio *bp, const char *attribute, int val) { - return (g_handleattr(bp, attribute, &val, sizeof val)); + return (g_handleattr(bp, attribute, &val, sizeof(val))); } int g_handleattr_uint16_t(struct bio *bp, const char *attribute, uint16_t val) { - return (g_handleattr(bp, attribute, &val, sizeof val)); + return (g_handleattr(bp, attribute, &val, sizeof(val))); } int g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val) { - return (g_handleattr(bp, attribute, &val, sizeof val)); + return (g_handleattr(bp, attribute, &val, sizeof(val))); } int @@ -1152,8 +1164,14 @@ g_std_done(struct bio *bp) struct bio *bp2; bp2 = bp->bio_parent; - if (bp2->bio_error == 0) - bp2->bio_error = bp->bio_error; + if (bp2->bio_error == 0) { + if ((bp->bio_flags & BIO_EXTERR) != 0) { + bp2->bio_flags |= BIO_EXTERR; + bp2->bio_exterr = bp->bio_exterr; + } else { + bp2->bio_error = bp->bio_error; + } + } bp2->bio_completed += bp->bio_completed; g_destroy_bio(bp); bp2->bio_inbed++; @@ -1658,6 +1676,8 @@ DB_SHOW_COMMAND(bio, db_show_bio) db_printf(" caller2: %p\n", bp->bio_caller2); db_printf(" bio_from: %p\n", bp->bio_from); db_printf(" bio_to: %p\n", bp->bio_to); + if ((bp->bio_flags & BIO_EXTERR) != 0) + exterr_db_print(&bp->bio_exterr); #if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING) db_printf(" bio_track_bp: %p\n", bp->bio_track_bp); diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c index d9e9a6c82da1..122e2f6a02ec 100644 --- a/sys/geom/geom_vfs.c +++ b/sys/geom/geom_vfs.c @@ -26,9 +26,11 @@ * SUCH DAMAGE. */ +#define EXTERR_CATEGORY EXTERR_CAT_GEOMVFS #include <sys/param.h> #include <sys/systm.h> #include <sys/bio.h> +#include <sys/exterrvar.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -153,13 +155,16 @@ g_vfs_done(struct bio *bip) g_print_bio("g_vfs_done():", bip, "error = %d%s", bip->bio_error, bip->bio_error != ENXIO ? "" : - " supressing further ENXIO"); + " suppressing further ENXIO"); } } - bp->b_error = bip->bio_error; bp->b_ioflags = bip->bio_flags; if (bip->bio_error) bp->b_ioflags |= BIO_ERROR; + if ((bp->b_ioflags & BIO_EXTERR) != 0) + bp->b_exterr = bip->bio_exterr; + else + bp->b_error = bip->bio_error; bp->b_resid = bp->b_bcount - bip->bio_completed; g_destroy_bio(bip); @@ -195,6 +200,8 @@ g_vfs_strategy(struct bufobj *bo, struct buf *bp) mtx_unlock(&sc->sc_mtx); bp->b_error = ENXIO; bp->b_ioflags |= BIO_ERROR; + EXTERROR_KE(&bp->b_exterr, ENXIO, + "orphaned or enxio active"); bufdone(bp); return; } diff --git a/sys/geom/journal/g_journal.c b/sys/geom/journal/g_journal.c index 6d9f6239e632..b520194b7d7c 100644 --- a/sys/geom/journal/g_journal.c +++ b/sys/geom/journal/g_journal.c @@ -2477,7 +2477,7 @@ g_journal_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) if (pp->geom->class == mp) return (NULL); - gp = g_new_geomf(mp, "journal:taste"); + gp = g_new_geom(mp, "journal:taste"); /* This orphan function should be never called. */ gp->orphan = g_journal_taste_orphan; cp = g_new_consumer(gp); diff --git a/sys/geom/label/g_label.c b/sys/geom/label/g_label.c index acb17d40914e..faefbd7c2ef6 100644 --- a/sys/geom/label/g_label.c +++ b/sys/geom/label/g_label.c @@ -399,7 +399,7 @@ g_label_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) if (strcmp(pp->geom->class->name, mp->name) == 0) return (NULL); - gp = g_new_geomf(mp, "label:taste"); + gp = g_new_geom(mp, "label:taste"); gp->start = g_label_start_taste; gp->access = g_label_access_taste; gp->orphan = g_label_orphan_taste; diff --git a/sys/geom/linux_lvm/g_linux_lvm.c b/sys/geom/linux_lvm/g_linux_lvm.c index c63318fed729..f333c08f45d9 100644 --- a/sys/geom/linux_lvm/g_linux_lvm.c +++ b/sys/geom/linux_lvm/g_linux_lvm.c @@ -537,7 +537,7 @@ g_llvm_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_topology_assert(); g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); - gp = g_new_geomf(mp, "linux_lvm:taste"); + gp = g_new_geom(mp, "linux_lvm:taste"); /* This orphan function should be never called. */ gp->orphan = g_llvm_taste_orphan; cp = g_new_consumer(gp); @@ -557,7 +557,7 @@ g_llvm_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) vg = md.md_vg; if (vg->vg_geom == NULL) { /* new volume group */ - gp = g_new_geomf(mp, "%s", vg->vg_name); + gp = g_new_geom(mp, vg->vg_name); gp->start = g_llvm_start; gp->spoiled = g_llvm_orphan; gp->orphan = g_llvm_orphan; diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 25c0490938ef..03902a2f2491 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -3149,7 +3149,7 @@ g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md, /* * Action geom. */ - gp = g_new_geomf(mp, "%s", md->md_name); + gp = g_new_geom(mp, md->md_name); sc = malloc(sizeof(*sc), M_MIRROR, M_WAITOK | M_ZERO); gp->start = g_mirror_start; gp->orphan = g_mirror_orphan; @@ -3290,7 +3290,7 @@ g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); G_MIRROR_DEBUG(2, "Tasting %s.", pp->name); - gp = g_new_geomf(mp, "mirror:taste"); + gp = g_new_geom(mp, "mirror:taste"); /* * This orphan function should be never called. */ diff --git a/sys/geom/mirror/g_mirror_ctl.c b/sys/geom/mirror/g_mirror_ctl.c index 82bc05a142c0..b31bf098ac4b 100644 --- a/sys/geom/mirror/g_mirror_ctl.c +++ b/sys/geom/mirror/g_mirror_ctl.c @@ -433,7 +433,7 @@ g_mirror_ctl_create(struct gctl_req *req, struct g_class *mp) g_topology_lock(); mediasize = OFF_MAX; sectorsize = 0; - gp = g_new_geomf(mp, "%s", md.md_name); + gp = g_new_geom(mp, md.md_name); gp->orphan = g_mirror_create_orphan; cp = g_new_consumer(gp); for (no = 1; no < *nargs; no++) { diff --git a/sys/geom/mountver/g_mountver.c b/sys/geom/mountver/g_mountver.c index de3a298735d4..c7d55c4734a2 100644 --- a/sys/geom/mountver/g_mountver.c +++ b/sys/geom/mountver/g_mountver.c @@ -291,7 +291,7 @@ g_mountver_create(struct gctl_req *req, struct g_class *mp, struct g_provider *p return (EEXIST); } } - gp = g_new_geomf(mp, "%s", name); + gp = g_new_geom(mp, name); sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); mtx_init(&sc->sc_mtx, "gmountver", NULL, MTX_DEF | MTX_RECURSE); TAILQ_INIT(&sc->sc_queue); diff --git a/sys/geom/multipath/g_multipath.c b/sys/geom/multipath/g_multipath.c index 23088c895541..4459bd9f03f5 100644 --- a/sys/geom/multipath/g_multipath.c +++ b/sys/geom/multipath/g_multipath.c @@ -321,7 +321,7 @@ g_multipath_resize(struct g_consumer *cp) if (sc->sc_uuid[0] != 0) { pp = cp->provider; strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic)); - memcpy(md.md_uuid, sc->sc_uuid, sizeof (sc->sc_uuid)); + memcpy(md.md_uuid, sc->sc_uuid, sizeof(sc->sc_uuid)); strlcpy(md.md_name, sc->sc_name, sizeof(md.md_name)); md.md_version = G_MULTIPATH_VERSION; md.md_size = size; @@ -549,11 +549,11 @@ g_multipath_create(struct g_class *mp, struct g_multipath_metadata *md) } } - gp = g_new_geomf(mp, "%s", md->md_name); + gp = g_new_geom(mp, md->md_name); sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); mtx_init(&sc->sc_mtx, "multipath", NULL, MTX_DEF); - memcpy(sc->sc_uuid, md->md_uuid, sizeof (sc->sc_uuid)); - memcpy(sc->sc_name, md->md_name, sizeof (sc->sc_name)); + memcpy(sc->sc_uuid, md->md_uuid, sizeof(sc->sc_uuid)); + memcpy(sc->sc_name, md->md_name, sizeof(sc->sc_name)); sc->sc_active_active = md->md_active_active; sc->sc_size = md->md_size; gp->softc = sc; @@ -821,7 +821,7 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_topology_assert(); - gp = g_new_geomf(mp, "multipath:taste"); + gp = g_new_geom(mp, "multipath:taste"); gp->start = g_multipath_start; gp->access = g_multipath_access; gp->orphan = g_multipath_orphan; @@ -906,7 +906,7 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) char buf[16]; u_long rand = random(); - snprintf(buf, sizeof (buf), "%s-%lu", md.md_name, rand); + snprintf(buf, sizeof(buf), "%s-%lu", md.md_name, rand); printf("GEOM_MULTIPATH: geom %s/%s exists already\n", sc->sc_name, sc->sc_uuid); printf("GEOM_MULTIPATH: %s will be (temporarily) %s\n", @@ -949,7 +949,6 @@ g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp, struct g_consumer *cp; struct g_provider *pp; const char *mpname; - static const char devpf[6] = _PATH_DEV; int error; g_topology_assert(); @@ -966,8 +965,6 @@ g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp, } sc = gp->softc; - if (strncmp(name, devpf, 5) == 0) - name += 5; pp = g_provider_by_name(name); if (pp == NULL) { gctl_error(req, "Provider %s is invalid", name); @@ -1200,7 +1197,7 @@ g_multipath_ctl_configure(struct gctl_req *req, struct g_class *mp) cp = sc->sc_active; pp = cp->provider; strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic)); - memcpy(md.md_uuid, sc->sc_uuid, sizeof (sc->sc_uuid)); + memcpy(md.md_uuid, sc->sc_uuid, sizeof(sc->sc_uuid)); strlcpy(md.md_name, name, sizeof(md.md_name)); md.md_version = G_MULTIPATH_VERSION; md.md_size = pp->mediasize; diff --git a/sys/geom/nop/g_nop.c b/sys/geom/nop/g_nop.c index a32111e3a29a..1fb99f4a0a5b 100644 --- a/sys/geom/nop/g_nop.c +++ b/sys/geom/nop/g_nop.c @@ -416,7 +416,7 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, return (EEXIST); } } - gp = g_new_geomf(mp, "%s", name); + gp = g_new_geom(mp, name); sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); sc->sc_offset = offset; sc->sc_explicitsize = explicitsize; diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c index 41125f6478ac..1e4236507fa4 100644 --- a/sys/geom/part/g_part.c +++ b/sys/geom/part/g_part.c @@ -122,13 +122,13 @@ struct g_part_alias_list { { "ntfs", G_PART_ALIAS_MS_NTFS }, { "openbsd-data", G_PART_ALIAS_OPENBSD_DATA }, { "prep-boot", G_PART_ALIAS_PREP_BOOT }, - { "solaris-boot", G_PART_ALIAS_SOLARIS_BOOT }, - { "solaris-root", G_PART_ALIAS_SOLARIS_ROOT }, - { "solaris-swap", G_PART_ALIAS_SOLARIS_SWAP }, - { "solaris-backup", G_PART_ALIAS_SOLARIS_BACKUP }, - { "solaris-var", G_PART_ALIAS_SOLARIS_VAR }, - { "solaris-home", G_PART_ALIAS_SOLARIS_HOME }, - { "solaris-altsec", G_PART_ALIAS_SOLARIS_ALTSEC }, + { "solaris-boot", G_PART_ALIAS_SOLARIS_BOOT }, + { "solaris-root", G_PART_ALIAS_SOLARIS_ROOT }, + { "solaris-swap", G_PART_ALIAS_SOLARIS_SWAP }, + { "solaris-backup", G_PART_ALIAS_SOLARIS_BACKUP }, + { "solaris-var", G_PART_ALIAS_SOLARIS_VAR }, + { "solaris-home", G_PART_ALIAS_SOLARIS_HOME }, + { "solaris-altsec", G_PART_ALIAS_SOLARIS_ALTSEC }, { "solaris-reserved", G_PART_ALIAS_SOLARIS_RESERVED }, { "u-boot-env", G_PART_ALIAS_U_BOOT_ENV }, { "vmware-reserved", G_PART_ALIAS_VMRESERVED }, @@ -552,8 +552,6 @@ g_part_parm_provider(struct gctl_req *req, const char *name, pname = gctl_get_asciiparam(req, name); if (pname == NULL) return (ENOATTR); - if (strncmp(pname, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) - pname += sizeof(_PATH_DEV) - 1; pp = g_provider_by_name(pname); if (pp == NULL) { gctl_error(req, "%d %s '%s'", EINVAL, name, pname); @@ -998,7 +996,7 @@ g_part_ctl_create(struct gctl_req *req, struct g_part_parms *gpp) } if (null == NULL) - gp = g_new_geomf(&g_part_class, "%s", pp->name); + gp = g_new_geom(&g_part_class, pp->name); gp->softc = kobj_create((kobj_class_t)gpp->gpp_scheme, M_GEOM, M_WAITOK); table = gp->softc; @@ -1046,7 +1044,7 @@ g_part_ctl_create(struct gctl_req *req, struct g_part_parms *gpp) /* * Synthesize a disk geometry. Some partitioning schemes * depend on it and since some file systems need it even - * when the partitition scheme doesn't, we do it here in + * when the partition scheme doesn't, we do it here in * scheme-independent code. */ g_part_geometry(table, cp, pp->mediasize / pp->sectorsize); @@ -1539,7 +1537,7 @@ g_part_ctl_undo(struct gctl_req *req, struct g_part_parms *gpp) /* * Synthesize a disk geometry. Some partitioning schemes * depend on it and since some file systems need it even - * when the partitition scheme doesn't, we do it here in + * when the partition scheme doesn't, we do it here in * scheme-independent code. */ pp = cp->provider; @@ -1979,7 +1977,7 @@ g_part_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) * With that we become part of the topology. Obtain read access * to the provider. */ - gp = g_new_geomf(mp, "%s", pp->name); + gp = g_new_geom(mp, pp->name); cp = g_new_consumer(gp); cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; error = g_attach(cp, pp); @@ -2023,7 +2021,7 @@ g_part_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) /* * Synthesize a disk geometry. Some partitioning schemes * depend on it and since some file systems need it even - * when the partitition scheme doesn't, we do it here in + * when the partition scheme doesn't, we do it here in * scheme-independent code. */ g_part_geometry(table, cp, pp->mediasize / pp->sectorsize); diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c index a483622d14a5..d35695482eea 100644 --- a/sys/geom/raid/g_raid.c +++ b/sys/geom/raid/g_raid.c @@ -775,8 +775,6 @@ g_raid_open_consumer(struct g_raid_softc *sc, const char *name) g_topology_assert(); - if (strncmp(name, _PATH_DEV, 5) == 0) - name += 5; pp = g_provider_by_name(name); if (pp == NULL) return (NULL); @@ -1876,7 +1874,7 @@ g_raid_create_node(struct g_class *mp, g_topology_assert(); G_RAID_DEBUG(1, "Creating array %s.", name); - gp = g_new_geomf(mp, "%s", name); + gp = g_new_geom(mp, name); sc = malloc(sizeof(*sc), M_RAID, M_WAITOK | M_ZERO); gp->start = g_raid_start; gp->orphan = g_raid_orphan; @@ -2217,7 +2215,7 @@ g_raid_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) geom = NULL; status = G_RAID_MD_TASTE_FAIL; - gp = g_new_geomf(mp, "raid:taste"); + gp = g_new_geom(mp, "raid:taste"); /* * This orphan function should be never called. */ diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c index c2d05b48d80d..64951bd01deb 100644 --- a/sys/geom/raid3/g_raid3.c +++ b/sys/geom/raid3/g_raid3.c @@ -3164,7 +3164,7 @@ g_raid3_create(struct g_class *mp, const struct g_raid3_metadata *md) /* * Action geom. */ - gp = g_new_geomf(mp, "%s", md->md_name); + gp = g_new_geom(mp, md->md_name); sc = malloc(sizeof(*sc), M_RAID3, M_WAITOK | M_ZERO); sc->sc_disks = malloc(sizeof(struct g_raid3_disk) * md->md_all, M_RAID3, M_WAITOK | M_ZERO); @@ -3338,7 +3338,7 @@ g_raid3_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); G_RAID3_DEBUG(2, "Tasting %s.", pp->name); - gp = g_new_geomf(mp, "raid3:taste"); + gp = g_new_geom(mp, "raid3:taste"); /* This orphan function should be never called. */ gp->orphan = g_raid3_taste_orphan; cp = g_new_consumer(gp); diff --git a/sys/geom/raid3/g_raid3_ctl.c b/sys/geom/raid3/g_raid3_ctl.c index 824de07e4836..5eafcce917cf 100644 --- a/sys/geom/raid3/g_raid3_ctl.c +++ b/sys/geom/raid3/g_raid3_ctl.c @@ -425,7 +425,7 @@ g_raid3_ctl_insert(struct gctl_req *req, struct g_class *mp) no = gctl_get_paraml(req, "number", sizeof(*no)); else no = NULL; - gp = g_new_geomf(mp, "raid3:insert"); + gp = g_new_geom(mp, "raid3:insert"); gp->orphan = g_raid3_ctl_insert_orphan; cp = g_new_consumer(gp); error = g_attach(cp, pp); diff --git a/sys/geom/shsec/g_shsec.c b/sys/geom/shsec/g_shsec.c index 3ccc23e7eb8b..9da814e5eb34 100644 --- a/sys/geom/shsec/g_shsec.c +++ b/sys/geom/shsec/g_shsec.c @@ -545,7 +545,7 @@ g_shsec_create(struct g_class *mp, const struct g_shsec_metadata *md) return (NULL); } } - gp = g_new_geomf(mp, "%s", md->md_name); + gp = g_new_geom(mp, md->md_name); sc = malloc(sizeof(*sc), M_SHSEC, M_WAITOK | M_ZERO); gp->start = g_shsec_start; gp->spoiled = g_shsec_orphan; @@ -643,7 +643,7 @@ g_shsec_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) G_SHSEC_DEBUG(3, "Tasting %s.", pp->name); - gp = g_new_geomf(mp, "shsec:taste"); + gp = g_new_geom(mp, "shsec:taste"); gp->start = g_shsec_start; gp->access = g_shsec_access; gp->orphan = g_shsec_orphan; diff --git a/sys/geom/stripe/g_stripe.c b/sys/geom/stripe/g_stripe.c index 6f336c18c8e6..ba1953f036d3 100644 --- a/sys/geom/stripe/g_stripe.c +++ b/sys/geom/stripe/g_stripe.c @@ -454,11 +454,9 @@ g_stripe_start_economic(struct bio *bp, u_int no, off_t offset, off_t length) cbp->bio_done = g_stripe_done; cbp->bio_offset = offset; cbp->bio_length = length; - if ((bp->bio_flags & BIO_UNMAPPED) != 0) { - bp->bio_ma_n = round_page(bp->bio_ma_offset + - bp->bio_length) / PAGE_SIZE; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) addr = NULL; - } else + else addr = bp->bio_data; cbp->bio_caller2 = sc->sc_disks[no]; @@ -864,7 +862,7 @@ g_stripe_create(struct g_class *mp, const struct g_stripe_metadata *md, return (NULL); } } - gp = g_new_geomf(mp, "%s", md->md_name); + gp = g_new_geom(mp, md->md_name); sc = malloc(sizeof(*sc), M_STRIPE, M_WAITOK | M_ZERO); gp->start = g_stripe_start; gp->spoiled = g_stripe_orphan; @@ -965,7 +963,7 @@ g_stripe_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) G_STRIPE_DEBUG(3, "Tasting %s.", pp->name); - gp = g_new_geomf(mp, "stripe:taste"); + gp = g_new_geom(mp, "stripe:taste"); gp->start = g_stripe_start; gp->access = g_stripe_access; gp->orphan = g_stripe_orphan; diff --git a/sys/geom/union/g_union.c b/sys/geom/union/g_union.c index 9734fc1bcfe3..43c16c86e5a8 100644 --- a/sys/geom/union/g_union.c +++ b/sys/geom/union/g_union.c @@ -246,7 +246,7 @@ g_union_ctl_create(struct gctl_req *req, struct g_class *mp, bool verbose) return; } } - gp = g_new_geomf(mp, "%s", name); + gp = g_new_geom(mp, name); sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); rw_init(&sc->sc_rwlock, "gunion"); TAILQ_INIT(&sc->sc_wiplist); @@ -358,6 +358,8 @@ fail2: fail1: g_destroy_consumer(lowercp); g_destroy_provider(newpp); + rw_destroy(&sc->sc_rwlock); + g_free(sc); g_destroy_geom(gp); } diff --git a/sys/geom/virstor/g_virstor.c b/sys/geom/virstor/g_virstor.c index b8cf32875660..1490ed103329 100644 --- a/sys/geom/virstor/g_virstor.c +++ b/sys/geom/virstor/g_virstor.c @@ -202,7 +202,7 @@ virstor_ctl_stop(struct gctl_req *req, struct g_class *cp) int *force, *nargs; int i; - nargs = gctl_get_paraml(req, "nargs", sizeof *nargs); + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); if (nargs == NULL) { gctl_error(req, "Error fetching argument '%s'", "nargs"); return; @@ -211,7 +211,7 @@ virstor_ctl_stop(struct gctl_req *req, struct g_class *cp) gctl_error(req, "Invalid number of arguments"); return; } - force = gctl_get_paraml(req, "force", sizeof *force); + force = gctl_get_paraml(req, "force", sizeof(*force)); if (force == NULL) { gctl_error(req, "Error fetching argument '%s'", "force"); return; @@ -315,7 +315,7 @@ virstor_ctl_add(struct gctl_req *req, struct g_class *cp) u_int nc; u_int j; - snprintf(aname, sizeof aname, "arg%d", i); + snprintf(aname, sizeof(aname), "arg%d", i); pp = gctl_get_provider(req, aname); if (pp == NULL) { /* This is the most common error so be verbose about it */ @@ -487,12 +487,12 @@ fill_metadata(struct g_virstor_softc *sc, struct g_virstor_metadata *md, { struct g_virstor_component *c; - bzero(md, sizeof *md); + bzero(md, sizeof(*md)); c = &sc->components[nc]; - strncpy(md->md_magic, G_VIRSTOR_MAGIC, sizeof md->md_magic); + strncpy(md->md_magic, G_VIRSTOR_MAGIC, sizeof(md->md_magic)); md->md_version = G_VIRSTOR_VERSION; - strncpy(md->md_name, sc->geom->name, sizeof md->md_name); + strncpy(md->md_name, sc->geom->name, sizeof(md->md_name)); md->md_id = sc->id; md->md_virsize = sc->virsize; md->md_chunk_size = sc->chunk_size; @@ -500,7 +500,7 @@ fill_metadata(struct g_virstor_softc *sc, struct g_virstor_metadata *md, if (hardcode) { strncpy(md->provider, c->gcons->provider->name, - sizeof md->provider); + sizeof(md->provider)); } md->no = nc; md->provsize = c->gcons->provider->mediasize; @@ -589,7 +589,7 @@ virstor_ctl_remove(struct gctl_req *req, struct g_class *cp) M_GVIRSTOR, M_WAITOK | M_ZERO); bcopy(sc->components, newcomp, found * sizeof(*sc->components)); bcopy(&sc->components[found + 1], newcomp + found, - found * sizeof(*sc->components)); + (sc->n_components - (found + 1)) * sizeof(*sc->components)); if ((sc->components[j].flags & VIRSTOR_PROVIDER_ALLOCATED) != 0) { LOG_MSG(LVL_ERROR, "Allocated provider %s cannot be " "removed from %s", @@ -771,7 +771,7 @@ g_virstor_taste(struct g_class *mp, struct g_provider *pp, int flags) LOG_MSG(LVL_DEBUG, "Tasting %s", pp->name); /* We need a dummy geom to attach a consumer to the given provider */ - gp = g_new_geomf(mp, "virstor:taste.helper"); + gp = g_new_geom(mp, "virstor:taste.helper"); gp->start = (void *)invalid_call; /* XXX: hacked up so the */ gp->access = (void *)invalid_call; /* compiler doesn't complain. */ gp->orphan = (void *)invalid_call; /* I really want these to fail. */ @@ -959,7 +959,7 @@ virstor_geom_destroy(struct g_virstor_softc *sc, boolean_t force, free(sc->map, M_GVIRSTOR); free(sc->components, M_GVIRSTOR); - bzero(sc, sizeof *sc); + bzero(sc, sizeof(*sc)); free(sc, M_GVIRSTOR); pp = LIST_FIRST(&gp->provider); /* We only offer one provider */ @@ -1085,7 +1085,7 @@ create_virstor_geom(struct g_class *mp, struct g_virstor_metadata *md) return (NULL); } } - gp = g_new_geomf(mp, "%s", md->md_name); + gp = g_new_geom(mp, md->md_name); gp->softc = NULL; /* to circumevent races that test softc */ gp->start = g_virstor_start; @@ -1213,7 +1213,7 @@ virstor_check_and_run(struct g_virstor_softc *sc) sc->provider->name, sc->chunk_count * (off_t)sc->chunk_size); } - sc->map_size = sc->chunk_count * sizeof *(sc->map); + sc->map_size = sc->chunk_count * sizeof(*(sc->map)); /* The following allocation is in order of 4MB - 8MB */ sc->map = malloc(sc->map_size, M_GVIRSTOR, M_WAITOK); KASSERT(sc->map != NULL, ("%s: Memory allocation error (%zu bytes) for %s", @@ -1267,7 +1267,7 @@ virstor_check_and_run(struct g_virstor_softc *sc) bcopy(mapbuf, &sc->map[n], bs); off += bs; count += bs; - n += bs / sizeof *(sc->map); + n += bs / sizeof(*(sc->map)); g_free(mapbuf); } g_access(sc->components[0].gcons, -1, 0, 0); @@ -1306,8 +1306,8 @@ virstor_check_and_run(struct g_virstor_softc *sc) sc->components[index].chunk_next); } - sc->me_per_sector = sc->sectorsize / sizeof *(sc->map); - if (sc->sectorsize % sizeof *(sc->map) != 0) { + sc->me_per_sector = sc->sectorsize / sizeof(*(sc->map)); + if (sc->sectorsize % sizeof(*(sc->map)) != 0) { LOG_MSG(LVL_ERROR, "%s: Map entries don't fit exactly in a sector (%s)", __func__, sc->geom->name); @@ -1653,7 +1653,7 @@ g_virstor_start(struct bio *b) * XXX: this will prevent the fs from * being umounted! */ struct g_virstor_bio_q *biq; - biq = malloc(sizeof *biq, M_GVIRSTOR, + biq = malloc(sizeof(*biq), M_GVIRSTOR, M_NOWAIT); if (biq == NULL) { bioq_dismantle(&bq); @@ -1703,7 +1703,7 @@ g_virstor_start(struct bio *b) * map array. * sc_offset will end up pointing to the drive * sector. */ - s_offset = chunk_index * sizeof *me; + s_offset = chunk_index * sizeof(*me); s_offset = rounddown(s_offset, sc->sectorsize); /* data_me points to map entry sector diff --git a/sys/geom/zero/g_zero.c b/sys/geom/zero/g_zero.c index 91ef0fb1ef95..25d462a9f918 100644 --- a/sys/geom/zero/g_zero.c +++ b/sys/geom/zero/g_zero.c @@ -3,6 +3,7 @@ * * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> * All rights reserved. + * Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,53 +35,97 @@ #include <sys/queue.h> #include <sys/sysctl.h> #include <sys/systm.h> +#include <sys/uio.h> +#include <sys/types.h> #include <geom/geom.h> #define G_ZERO_CLASS_NAME "ZERO" -static int g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS); +static int g_zero_byte_sysctl(SYSCTL_HANDLER_ARGS); SYSCTL_DECL(_kern_geom); static SYSCTL_NODE(_kern_geom, OID_AUTO, zero, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "GEOM_ZERO stuff"); static int g_zero_clear = 1; -SYSCTL_PROC(_kern_geom_zero, OID_AUTO, clear, - CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &g_zero_clear, 0, - g_zero_clear_sysctl, "I", +SYSCTL_INT(_kern_geom_zero, OID_AUTO, clear, + CTLFLAG_RWTUN, &g_zero_clear, 0, "Clear read data buffer"); static int g_zero_byte = 0; -SYSCTL_INT(_kern_geom_zero, OID_AUTO, byte, CTLFLAG_RW, &g_zero_byte, 0, +static uint8_t g_zero_buffer[PAGE_SIZE]; +SYSCTL_PROC(_kern_geom_zero, OID_AUTO, byte, + CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, &g_zero_byte, 0, + g_zero_byte_sysctl, "I", "Byte (octet) value to clear the buffers with"); static struct g_provider *gpp; static int -g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS) +g_zero_byte_sysctl(SYSCTL_HANDLER_ARGS) { int error; - error = sysctl_handle_int(oidp, &g_zero_clear, 0, req); + // XXX: Confirm that this is called on module load as well. + // XXX: Shouldn't we lock here to avoid changing the byte value if the + // driver is in the process of handling I/O? + error = sysctl_handle_int(oidp, &g_zero_byte, 0, req); if (error != 0 || req->newptr == NULL) return (error); - if (gpp == NULL) - return (ENXIO); - if (g_zero_clear) - gpp->flags &= ~G_PF_ACCEPT_UNMAPPED; - else - gpp->flags |= G_PF_ACCEPT_UNMAPPED; + memset(g_zero_buffer, g_zero_byte, PAGE_SIZE); return (0); } static void +g_zero_fill_pages(struct bio *bp) +{ + struct iovec aiovec; + struct uio auio; + size_t length; + vm_offset_t offset; + + aiovec.iov_base = g_zero_buffer; + aiovec.iov_len = PAGE_SIZE; + auio.uio_iov = &aiovec; + auio.uio_iovcnt = 1; + auio.uio_offset = 0; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_rw = UIO_WRITE; + auio.uio_td = curthread; + + /* + * To handle the unmapped I/O request, we need to fill the pages in the + * bp->bio_ma array with the g_zero_byte value. However, instead of + * setting every byte individually, we use uiomove_fromphys() to fill a + * page at a time with g_zero_buffer. + */ + bp->bio_resid = bp->bio_length; + offset = bp->bio_ma_offset & PAGE_MASK; + for (int i = 0; i < bp->bio_ma_n && bp->bio_resid > 0; i++) { + length = MIN(PAGE_SIZE - offset, bp->bio_resid); + auio.uio_resid = length; + + (void)uiomove_fromphys(&bp->bio_ma[i], offset, length, &auio); + + offset = 0; + bp->bio_resid -= length; + } +} + + +static void g_zero_start(struct bio *bp) { - int error = ENXIO; + int error; switch (bp->bio_cmd) { case BIO_READ: - if (g_zero_clear && (bp->bio_flags & BIO_UNMAPPED) == 0) - memset(bp->bio_data, g_zero_byte, bp->bio_length); + if (g_zero_clear) { + if ((bp->bio_flags & BIO_UNMAPPED) != 0) + g_zero_fill_pages(bp); + else + memset(bp->bio_data, g_zero_byte, + bp->bio_length); + } /* FALLTHROUGH */ case BIO_DELETE: case BIO_WRITE: @@ -102,13 +147,12 @@ g_zero_init(struct g_class *mp) struct g_provider *pp; g_topology_assert(); - gp = g_new_geomf(mp, "gzero"); + gp = g_new_geom(mp, "gzero"); gp->start = g_zero_start; gp->access = g_std_access; gpp = pp = g_new_providerf(gp, "%s", gp->name); - pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE; - if (!g_zero_clear) - pp->flags |= G_PF_ACCEPT_UNMAPPED; + pp->flags |= G_PF_ACCEPT_UNMAPPED | G_PF_DIRECT_SEND | + G_PF_DIRECT_RECEIVE; pp->mediasize = 1152921504606846976LLU; pp->sectorsize = 512; g_error_provider(pp, 0); |
