PERFORCE change 122670 for review
Sonja Milicic
smilicic at FreeBSD.org
Sun Jul 1 21:14:19 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=122670
Change 122670 by smilicic at tanarri_marilith on 2007/07/01 21:13:45
added and tested class methods(orphan, access etc), event queue and worker thread. also fixed some bugs with accidental null pointers.
Affected files ...
.. //depot/projects/soc2007/smilicic_glog/sys/geom/log/glog.c#3 edit
Differences ...
==== //depot/projects/soc2007/smilicic_glog/sys/geom/log/glog.c#3 (text+ko) ====
@@ -1,272 +1,567 @@
-/*-
- * Copyright (c) 2007 Sonja Milicic <tanarri at geri.cc.fer.hr>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/vnode.h>
-#include <sys/mutex.h>
-#include <sys/sx.h>
-#include <sys/bio.h>
-#include <sys/sysctl.h>
-#include <sys/malloc.h>
-#include <sys/time.h>
-#include <vm/uma.h>
-#include <sys/proc.h>
-#include <sys/kthread.h>
-#include <geom/geom.h>
-#include <sys/fcntl.h>
-#include <sys/namei.h>
-
-#include "glog.h"
-#include "glog_fileops.h"
-
-static MALLOC_DEFINE(M_GLOG, "glog", "GEOM_LOG Data");
-
-static uma_zone_t g_log_io_zone;
-/*static uma_zone_t g_log_hl_zone;*/
-
-static void g_log_ctlreq (struct gctl_req *req, struct g_class *mp, const char
- *verb);
-static enum gctl_verb g_log_verb_id(const char* verb);
-static char *g_log_create_geom(const char *prov, const char *file,
- struct g_class *mp);
-static void g_log_start(struct bio *bp);
-static int g_log_event_sink_init(struct g_log_softc *sc,
- struct g_log_event_sink *es, void (*func)(void*), char* name);
-static void g_log_worker(void *args);
-
-/*static g_ctl_destroy_geom_t g_log_destroy_geom;*/
-static g_init_t g_log_init;
-static g_fini_t g_log_fini;
-
-SYSCTL_DECL(_kern_geom);
-SYSCTL_NODE(_kern_geom, OID_AUTO, log, CTLFLAG_RW, 0, "GEOM_LOG information");
-
-static u_int g_log_debug = 2; /* XXX: lower when released to public */
-TUNABLE_INT("kern.geom.log.debug", &g_log_debug);
-SYSCTL_UINT(_kern_geom_log, OID_AUTO, debug, CTLFLAG_RW, &g_log_debug, 0,
- "Debug level");
-
-static u_int g_log_maxrecsector = 64;
-TUNABLE_INT("kern.geom.log.maxrecsector", &g_log_maxrecsector);
-SYSCTL_UINT(_kern_geom_log, OID_AUTO, maxrecsector, CTLFLAG_RD,
- &g_log_maxrecsector, 0, "Maximum records in log descriptor sector");
-
-static u_int g_log_maxmem = MAXPHYS * 100;
-TUNABLE_INT("kern.geom.log.maxmem", &g_log_maxmem);
-SYSCTL_UINT(_kern_geom_log, OID_AUTO, maxmem, CTLFLAG_RD, &g_log_maxmem,
- 0, "Maximum memory that can be allocated for I/O (in bytes)");
-/*
-extern u_int _hl_stat_hinted_lookups;
-SYSCTL_UINT(_kern_geom_log, OID_AUTO, hl_hinted_lookups,
- CTLFLAG_RD, &_hl_stat_hinted_lookups, 0,
- "Number of hint cache hits for hinted interval list");
-*/
-static u_int g_log_alloc_failed = 0;
-SYSCTL_UINT(_kern_geom_log, OID_AUTO, alloc_failed, CTLFLAG_RD,
- &g_log_alloc_failed, 0, "How many times I/O allocation failed");
-
-
-struct g_class g_log_class = {
- .name = G_LOG_CLASS_NAME,
- .version = G_VERSION,
- //.destroy_geom = g_log_destroy_geom,
- .ctlreq = g_log_ctlreq,
- .init = g_log_init,
- .fini = g_log_fini
-};
-
-/*static int g_log_destroy_geom(struct g_log_softc *sc, boolean_t force);
-static void g_log_collect_children(struct bio *bp);
-static void g_log_commit(struct g_log_softc *sc);
-static int g_log_rollback(struct g_log_softc *sc);
-static int g_log_write(struct g_log_softc *sc);
-static int g_log_read(struct g_log_softc *sc);*/
-
-/* gctl verb IDs */
-enum gctl_verb { GCTL_INVALID, GCTL_COMMIT, GCTL_ROLLBACK, GCTL_START,
- GCTL_STOP};
-
-static void
-g_log_init(struct g_class *mp __unused)
-{
- g_log_io_zone = uma_zcreate("glog.io", MAXPHYS, NULL, NULL, NULL, NULL,
- 0, UMA_ALIGN_CACHE);
- g_log_maxmem -= g_log_maxmem % MAXPHYS;
- uma_zone_set_max(g_log_io_zone, g_log_maxmem / MAXPHYS);
- /* g_log_hl_zone = uma_zcreate("glog.hl", sizeof(struct hl_entry), NULL, NULL,
- NULL, NULL, UMA_ALIGN_PTR, 0);*/
- G_LOG_DEBUG(DBG_NOTICE, "%s", __func__);
-}
-
-static void
-g_log_fini(struct g_class *mp __unused)
-{
- uma_zdestroy(g_log_io_zone);
- /*uma_zdestroy(g_log_hl_zone);*/
- G_LOG_DEBUG(DBG_NOTICE, "%s", __func__);
-}
-/*
-static void
-g_log_orphan(struct g_consumer *cp)
-{
- struct g_log_softc *sc;
- struct g_geom *gp;
-
- G_LOG_DEBUG(0, "%s", __func__);
-
- g_topology_assert();
- gp = cp->geom;
- sc = gp->softc;
- if (sc == NULL)
- return;
-
- g_log_remove_disk(cp);
-
- if (g_log_nvalid(sc) == 0)
- g_log_destroy(sc, 1);
-}
-*/
-
-static char *
-g_log_create_geom(const char *prov, const char *file, struct g_class *mp)
-{
- struct g_geom *gp;
- struct g_provider *pp;
- struct g_log_softc *sc;
- char *err_msg = NULL;
-
- /* create provider*/
- if (strncmp(prov, "/dev/", strlen("/dev/")) == 0)
- prov += strlen("/dev/");
-
- pp = g_provider_by_name(prov);
- if (pp == NULL)
- err_msg = "Provider doesn't exist.";
- /*create geom*/
- gp = g_new_geomf(mp, "%s.log", prov);
- if (gp == NULL)
- err_msg = "Can not create geom.";
- gp->start = g_log_start;
-
- sc = malloc(sizeof(*sc), M_GLOG, M_WAITOK | M_ZERO);
- sc->sc_geom = gp;
- sc->sc_provider = pp;
-
- if (g_log_event_sink_init(sc, &sc->sc_events, g_log_worker, "events") !=0)
- err_msg = "Can not initialize worker thread.";
-
- /*open file*/
- sc->sc_vn = glog_open_file(file, FWRITE | O_TRUNC | O_CREAT);
-
- gp->softc = sc;
- return err_msg;
-}
-
-static int
-g_log_event_sink_init(struct g_log_softc *sc, struct g_log_event_sink *es,
- void (*func)(void*), char* name)
-{
- int err;
- es->sc = sc;
- mtx_init(&es->eventq_mtx, "glog:event_sink", NULL, MTX_DEF);
- TAILQ_INIT(&es->eventq);
- if ((err = kthread_create(func, es, &es->worker_thread, 0, 0, "g_log %s",
- name)) != 0)
- return err;
- es->flags = 0;
-
- return 0;
-}
-
-static void
-g_log_ctlreq (struct gctl_req *req, struct g_class *mp, const char *verb)
-{
- int *num_arg;
- const char *prov, *file;
- char *err;
-
- g_topology_assert();
-
- switch (g_log_verb_id(verb)) {
- case GCTL_START:
- num_arg = gctl_get_paraml(req, "nargs", sizeof(*num_arg));
- if (*num_arg == 2) {
- prov = gctl_get_asciiparam(req, "arg0");
- file = gctl_get_asciiparam(req, "arg1");
- err = g_log_create_geom(prov, file, mp);
- if (err != NULL)
- gctl_error(req, "Error creating geom: %s", err);
- } else
- gctl_error(req,"Wrong number of parameters.");
- break;
- case GCTL_COMMIT:
- break;
- case GCTL_ROLLBACK:
- break;
- case GCTL_STOP:
- break;
- default:
- panic("Unknown verb!");
- }
-}
-
-static void
-g_log_start(struct bio *bp)
-{
- g_io_deliver(bp, ENOMEM);
- return;
-}
-
-static void
-g_log_worker(void *args)
-{
-}
-
-/* Convert verb to number */
-static enum gctl_verb
-g_log_verb_id(const char* verb)
-{
- if (strcmp(verb, "commit") == 0)
- return GCTL_COMMIT;
- else if (strcmp(verb, "rollback") == 0)
- return GCTL_ROLLBACK;
- else if (strcmp(verb, "start") == 0)
- return GCTL_START;
- else if (strcmp(verb, "stop") == 0)
- return GCTL_STOP;
- else
- return GCTL_INVALID;
-};
-
-DECLARE_GEOM_CLASS(g_log_class, g_log);
-
+/*-
+ * Copyright (c) 2007 Sonja Milicic <tanarri at geri.cc.fer.hr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/vnode.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
+#include <sys/bio.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/time.h>
+#include <vm/uma.h>
+#include <sys/proc.h>
+#include <sys/kthread.h>
+#include <geom/geom.h>
+#include <sys/fcntl.h>
+#include <sys/namei.h>
+
+#include "glog.h"
+#include "glog_fileops.h"
+
+static MALLOC_DEFINE(M_GLOG, "glog", "GEOM_LOG Data");
+
+static uma_zone_t g_log_io_zone;
+/*static uma_zone_t g_log_hl_zone;*/
+
+static void g_log_ctlreq(struct gctl_req *req, struct g_class *mp, const char
+ *verb);
+static enum gctl_verb g_log_verb_id(const char* verb);
+static struct g_geom * g_log_create_geom(const char *prov, const char *file,
+ struct g_class *mp, int *err);
+static int g_log_destroy_geom(struct gctl_req *req __unused,
+ struct g_class *mp __unused, struct g_geom *gp);
+static void g_log_start(struct bio *bp);
+static void g_log_stop(struct g_geom *gp, int force);
+static int g_log_access(struct g_provider *pp, int dr, int dw, int de);
+static int g_log_event_sink_init(struct g_log_softc *sc,
+ struct g_log_event_sink *es, void (*func)(void*), char* name);
+static void g_log_worker(void *args);
+static int g_log_post_event(struct g_log_event_sink *es, u_int type,
+ u_int flags, void* data1, int data2);
+static struct g_log_event* g_log_get_event(struct g_log_event_sink *es);
+static int g_log_no_events(struct g_log_event_sink *es);
+static void g_log_write(struct bio *bp);
+static void g_log_read(struct bio *bp);
+static void g_log_dumpconf(struct sbuf *sb, const char *indent,
+ struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp);
+static void g_log_ctl_destroy(struct gctl_req *req, struct g_class *mp);
+static g_init_t g_log_init;
+static g_fini_t g_log_fini;
+
+SYSCTL_DECL(_kern_geom);
+SYSCTL_NODE(_kern_geom, OID_AUTO, log, CTLFLAG_RW, 0, "GEOM_LOG information");
+
+static u_int g_log_debug = 10; /* XXX: lower when released to public */
+TUNABLE_INT("kern.geom.log.debug", &g_log_debug);
+SYSCTL_UINT(_kern_geom_log, OID_AUTO, debug, CTLFLAG_RW, &g_log_debug, 0,
+ "Debug level");
+
+static u_int g_log_maxrecsector = 64;
+TUNABLE_INT("kern.geom.log.maxrecsector", &g_log_maxrecsector);
+SYSCTL_UINT(_kern_geom_log, OID_AUTO, maxrecsector, CTLFLAG_RD,
+ &g_log_maxrecsector, 0, "Maximum records in log descriptor sector");
+
+static u_int g_log_maxmem = MAXPHYS * 100;
+TUNABLE_INT("kern.geom.log.maxmem", &g_log_maxmem);
+SYSCTL_UINT(_kern_geom_log, OID_AUTO, maxmem, CTLFLAG_RD, &g_log_maxmem,
+ 0, "Maximum memory that can be allocated for I/O (in bytes)");
+/*
+extern u_int _hl_stat_hinted_lookups;
+SYSCTL_UINT(_kern_geom_log, OID_AUTO, hl_hinted_lookups,
+ CTLFLAG_RD, &_hl_stat_hinted_lookups, 0,
+ "Number of hint cache hits for hinted interval list");
+*/
+static u_int g_log_alloc_failed = 0;
+SYSCTL_UINT(_kern_geom_log, OID_AUTO, alloc_failed, CTLFLAG_RD,
+ &g_log_alloc_failed, 0, "How many times I/O allocation failed");
+
+
+struct g_class g_log_class = {
+ .name = G_LOG_CLASS_NAME,
+ .version = G_VERSION,
+ .destroy_geom = g_log_destroy_geom,
+ .ctlreq = g_log_ctlreq,
+ .init = g_log_init,
+ .fini = g_log_fini
+};
+
+/* gctl verb IDs */
+enum gctl_verb { GCTL_INVALID, GCTL_COMMIT, GCTL_ROLLBACK, GCTL_START,
+ GCTL_STOP};
+
+static void
+g_log_init(struct g_class *mp __unused)
+{
+ g_log_io_zone = uma_zcreate("glog.io", MAXPHYS, NULL, NULL, NULL, NULL,
+ 0, UMA_ALIGN_CACHE);
+ g_log_maxmem -= g_log_maxmem % MAXPHYS;
+ uma_zone_set_max(g_log_io_zone, g_log_maxmem / MAXPHYS);
+ /* g_log_hl_zone = uma_zcreate("glog.hl", sizeof(struct hl_entry), NULL, NULL,
+ NULL, NULL, UMA_ALIGN_PTR, 0);*/
+ G_LOG_DEBUG(DBG_NOTICE, "%s", __func__);
+}
+
+static void
+g_log_fini(struct g_class *mp __unused)
+{
+ uma_zdestroy(g_log_io_zone);
+ /*uma_zdestroy(g_log_hl_zone);*/
+ G_LOG_DEBUG(DBG_NOTICE, "%s", __func__);
+}
+
+static void
+g_log_orphan(struct g_consumer *cp)
+{
+ struct g_log_softc *sc;
+ struct g_geom *gp;
+
+ g_topology_assert();
+ gp = cp->geom;
+ sc = gp->softc;
+ if (sc == NULL)
+ return;
+ g_log_stop(gp, 1);
+}
+
+static struct g_geom *
+g_log_create_geom(const char *prov, const char *file, struct g_class *mp, int *err)
+{
+ struct g_geom *gp;
+ struct g_provider *pp_log, *pp_disk;
+ struct g_log_softc *sc;
+ struct g_consumer *cp_disk;
+
+ /*initialize softc*/
+ sc = malloc(sizeof(*sc), M_GLOG, M_WAITOK | M_ZERO);
+
+ /*create geom and provider for log*/
+ gp = g_new_geomf(mp, "%s.log", prov);
+ gp->softc = sc;
+ gp->start = g_log_start;
+ gp->spoiled = g_log_orphan;
+ gp->orphan = g_log_orphan;
+ gp->access = g_log_access;
+ gp->dumpconf = g_log_dumpconf;
+ if (gp == NULL)
+ *err=3;
+ pp_log = g_new_providerf(gp, "%s.log", prov);
+ sc->sc_geom_log = gp;
+ sc->sc_prov_log = pp_log;
+
+ if (g_log_event_sink_init(sc, &sc->sc_events, g_log_worker, "events") !=0)
+ *err=4;
+
+ /* create provider and consumer for disk*/
+ if (strncmp(prov, "/dev/", strlen("/dev/")) == 0)
+ prov += strlen("/dev/");
+ pp_disk = g_provider_by_name(prov);
+ if (pp_disk == NULL)
+ *err = 1;
+ cp_disk = g_new_consumer(gp);
+ if (g_attach(cp_disk, pp_disk) != 0)
+ *err = 2;
+ sc->sc_prov_disk = pp_disk;
+ sc->sc_cons_disk = cp_disk;
+
+ /*open file*/
+ sc->sc_vn = glog_open_file(file, FWRITE | O_TRUNC | O_CREAT);
+
+
+ return gp;
+}
+
+static int
+g_log_event_sink_init(struct g_log_softc *sc, struct g_log_event_sink *es,
+ void (*func)(void*), char* name)
+{
+ int err;
+ es->sc = sc;
+ mtx_init(&es->eventq_mtx, "glog:event_sink", NULL, MTX_DEF);
+ TAILQ_INIT(&es->eventq);
+ if ((err = kthread_create(func, es, &es->worker_thread, 0, 0, "g_log %s",
+ name)) != 0)
+ return err;
+ es->flags = 0;
+
+ return 0;
+}
+
+static void
+g_log_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
+{
+ struct g_geom *gp=NULL;
+ const char *prov, *file;
+ int *num_arg;
+ int err = 0;
+ char *err_text=NULL;
+
+ g_topology_assert();
+ num_arg = gctl_get_paraml(req, "nargs", sizeof(*num_arg));
+ switch (g_log_verb_id(verb)) {
+ case GCTL_START:
+ if (*num_arg == 2) {
+ prov = gctl_get_asciiparam(req, "arg0");
+ file = gctl_get_asciiparam(req, "arg1");
+ gp = g_log_create_geom(prov, file, mp, &err);
+ if (err != 0){
+ switch (err){
+ case 1:
+ err_text="Cannot open provider";
+ break;
+ case 2:
+ err_text="Cannot attach consumer to provider";
+ break;
+ case 3:
+ err_text="Can not create geom";
+ break;
+ case 4:
+ err_text="Can not start worker thread";
+ break;
+ }
+ gctl_error(req, "Error starting geom log: %s", err_text);
+ }
+ } else
+ gctl_error(req, "Wrong number of parameters.");
+ break;
+ case GCTL_COMMIT:
+ if (*num_arg == 1) {
+ prov = gctl_get_asciiparam(req, "arg0");
+ g_log_stop(gp,0);
+
+ } else
+ gctl_error(req, "Wrong number of parameters.");
+ break;
+ case GCTL_ROLLBACK:
+ break;
+ case GCTL_STOP:
+ if (*num_arg == 1) {
+ g_log_ctl_destroy(req, mp);
+ } else
+ gctl_error(req, "Wrong number of parameters.");
+ break;
+ default:
+ panic("Unknown verb!");
+ }
+}
+
+/*start geom*/
+static void
+g_log_start(struct bio *bp)
+{
+ struct g_log_softc *sc;
+ sc = bp->bio_to->geom->softc;
+ KASSERT(sc != NULL,
+ ("Provider's error should be set (error=%d)(device=%s).",
+ bp->bio_to->error, bp->bio_to->name));
+
+ G_LOG_LOGREQ(DBG_NOTICE, bp, "Request received.");
+
+ switch(bp->bio_cmd) {
+ case BIO_WRITE:
+ g_log_post_event(&sc->sc_events, GLOG_EVWRITE, GLOG_FLAG_WAKEUP_SC, bp, 0);
+ break;
+ case BIO_READ:
+ g_log_post_event(&sc->sc_events, GLOG_EVREAD, GLOG_FLAG_WAKEUP_SC, bp, 0);
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+/*stop geom*/
+static void
+g_log_stop(struct g_geom *gp, int force)
+{
+ struct g_log_softc *sc;
+ sc=gp->softc;
+
+ /*close log file*/
+ glog_close_file(sc->sc_vn, FWRITE);
+
+ /*clean up memory*/
+ g_detach(sc->sc_cons_disk);
+ g_destroy_consumer(sc->sc_cons_disk);
+ gp->softc = NULL;
+ free(sc, M_GLOG);
+
+ /*destroy geom*/
+ g_topology_assert();
+ g_wither_geom(gp, ENXIO);
+}
+
+static int
+g_log_access(struct g_provider *pp, int dr, int dw, int de)
+{
+ struct g_consumer *cp;
+ struct g_log_softc *sc;
+ struct g_geom *gp;
+ int err = 0;
+
+ gp = pp->geom;
+ sc = gp->softc;
+ G_LOG_DEBUG(DBG_IMPORTANT, "%s: %d %d %d", __func__, dr, dw, de);
+
+ if (sc == NULL) {
+ /*
+ * It looks like geom is being withered.
+ * In that case we allow only negative requests.
+ */
+ KASSERT(dr <= 0 && dw <= 0 && de <= 0,
+ ("Positive access request (device=%s).", pp->name));
+ if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 &&
+ (pp->ace + de) == 0) {
+ G_LOG_DEBUG(0, "Device %s definitely destroyed.", gp->name);
+ }
+ return (0);
+ }
+
+ LIST_FOREACH(cp, &gp->consumer, consumer){
+ err = g_access(cp, dr ,dw, de);
+ if (err == 0)
+ continue;
+ }
+ return err;
+}
+
+/*puts worker thread to sleep if there's nothing for it to do*/
+static void
+g_log_worker_sleep(struct g_log_softc *sc)
+{
+ if (g_log_no_events(&sc->sc_events))
+ tsleep(sc, PRIBIO, "glogidle", hz);
+}
+
+/*worker thread*/
+static void
+g_log_worker(void *args)
+{
+ struct g_log_event_sink *es;
+ struct g_log_softc *sc;
+ struct g_log_event *ev;
+ struct bio *bp;
+ es = args;
+
+ if (es == NULL)
+ panic("No event sink!");
+ sc = es->sc;
+ if (sc == NULL)
+ panic("No softc!");
+
+ while (1){
+ ev = g_log_get_event(&sc->sc_events);
+ while (ev == NULL)
+ g_log_worker_sleep(sc);
+ bp = ev->data1;
+ switch (ev->type) {
+ case GLOG_EVCOMMIT:
+ break;
+ case GLOG_EVROLLBACK:
+ break;
+ case GLOG_EVREAD:
+ g_log_read(bp);
+ break;
+ case GLOG_EVWRITE:
+ g_log_write(bp);
+ break;
+ case GLOG_EVSTOP:
+ break;
+ }
+ free(ev,M_GLOG);
+ }
+}
+/* adds event to event queue */
+static int
+g_log_post_event(struct g_log_event_sink *es, u_int type, u_int flags,
+ void* data1, int data2)
+{
+ struct g_log_softc *sc;
+ struct g_log_event *ev;
+
+ KASSERT(es != NULL, ("%s: event_sink is null", __func__));
+ sc = es->sc;
+ KASSERT(sc != NULL, ("%s: softc is null", __func__));
+
+ ev = malloc(sizeof(*ev), M_GLOG, M_NOWAIT);
+ if (ev == NULL)
+ return ENOMEM;
+
+ ev->type = type;
+ ev->flags = flags;
+ ev->data1 = data1;
+ ev->data2 = data2;
+
+ mtx_lock(&es->eventq_mtx);
+ TAILQ_INSERT_TAIL(&es->eventq, ev, linkage);
+ mtx_unlock(&es->eventq_mtx);
+
+ if ( (flags & GLOG_FLAG_WAKEUP_SC) != 0)
+ wakeup(es);
+
+ return 0;
+}
+
+/*gets next event from event queue*/
+static struct g_log_event*
+g_log_get_event(struct g_log_event_sink *es)
+{
+ struct g_log_softc *sc;
+ struct g_log_event *ev;
+
+ KASSERT(es != NULL, ("%s: event_sink is null", __func__));
+ sc = es->sc;
+ KASSERT(sc != NULL, ("%s: softc is null", __func__));
+
+ mtx_lock(&es->eventq_mtx);
+ ev = TAILQ_FIRST(&es->eventq);
+ if (ev != NULL)
+ TAILQ_REMOVE(&es->eventq, ev, linkage);
+ mtx_unlock(&es->eventq_mtx);
+
+ return ev;
+}
+
+/*is the event queue empty?*/
+static int
+g_log_no_events(struct g_log_event_sink *es)
+{
+ return TAILQ_EMPTY(&es->eventq);
+}
+
+/*writes data to log file*/
+static void
+g_log_write(struct bio *bp)
+{
+ struct g_log_softc *sc;
+ void *data;
+ int err;
+ uprintf("Got a write request.");
+ sc = bp->bio_to->geom->softc;
+ data = bp->bio_data;
+ err = glog_write_file(sc->sc_vn, data, sizeof(data), 0);
+ if (err != 0)
+ printf ("Error writing to file");
+
+}
+
+/*reads data*/
+static void
+g_log_read(struct bio *bp)
+{
+ uprintf("Got a read request.");
+
+}
+
+/*commits the log file*/
+/*static void
+g_log_commit(struct g_log_softc *sc)
+{
+}*/
+
+/*deletes the log file*/
+/*static void
+g_log_rollback(struct g_log_softc *sc)
+{
+}
+*/
+
+static int
+g_log_destroy_geom(struct gctl_req *req __unused, struct g_class *mp __unused,
+ struct g_geom *gp)
+{
+ g_log_stop(gp, 0);
+ return 0;
+}
+
+static void
+g_log_ctl_destroy(struct gctl_req *req, struct g_class *mp)
+{
+ struct g_geom *gp;
+ int *num_args, *force;
+ const char *prov;
+
+ g_topology_assert();
+
+ num_args = gctl_get_paraml(req, "nargs", sizeof(int));
+ if (*num_args != 1){
+ gctl_error(req, "Wrong number of arguments.");
+ return;
+ }
+ prov = gctl_get_asciiparam(req, "arg0");
+
+ force = gctl_get_paraml(req, "force", sizeof(int));
+ gp = LIST_FIRST(&mp->geom);
+ g_log_stop(gp, *force);
+
+
+}
+/*XML*/
+static void
+g_log_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
+ struct g_consumer *cp, struct g_provider *pp)
+{
+ struct g_log_softc *sc;
+
+ sc = gp->softc;
+ if (sc == NULL)
+ return;
+ if (pp != NULL) {
+ /* Nothing here. */
+ } else if (cp != NULL) {
+ sbuf_printf(sb, "%s<Number>%u</Number>\n", indent,
+ (u_int)cp->index);
+ } else {
+
+
+ }
+}
+
+/* Convert verb to number */
+static enum gctl_verb
+g_log_verb_id(const char* verb)
+{
+ if (strcmp(verb, "commit") == 0)
+ return GCTL_COMMIT;
+ else if (strcmp(verb, "rollback") == 0)
+ return GCTL_ROLLBACK;
+ else if (strcmp(verb, "start") == 0)
+ return GCTL_START;
+ else if (strcmp(verb, "stop") == 0)
+ return GCTL_STOP;
+ else
+ return GCTL_INVALID;
+};
+
+DECLARE_GEOM_CLASS(g_log_class, g_log);
+
More information about the p4-projects
mailing list