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