[Midnightbsd-cvs] src [9971] trunk/sys/geom/journal: sync with freebsd
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat May 26 11:25:33 EDT 2018
Revision: 9971
http://svnweb.midnightbsd.org/src/?rev=9971
Author: laffer1
Date: 2018-05-26 11:25:32 -0400 (Sat, 26 May 2018)
Log Message:
-----------
sync with freebsd
Modified Paths:
--------------
trunk/sys/geom/journal/g_journal.c
trunk/sys/geom/journal/g_journal.h
trunk/sys/geom/journal/g_journal_ufs.c
Modified: trunk/sys/geom/journal/g_journal.c
===================================================================
--- trunk/sys/geom/journal/g_journal.c 2018-05-26 15:24:45 UTC (rev 9970)
+++ trunk/sys/geom/journal/g_journal.c 2018-05-26 15:25:32 UTC (rev 9971)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2005-2006 Pawel Jakub Dawidek <pjd at FreeBSD.org>
* All rights reserved.
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/journal/g_journal.c,v 1.13.2.2 2009/04/06 17:33:35 trasz Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/journal/g_journal.c 328948 2018-02-06 19:17:40Z mckusick $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -131,28 +132,28 @@
SYSCTL_UINT(_kern_geom_journal, OID_AUTO, optimize, CTLFLAG_RW,
&g_journal_do_optimize, 0, "Try to combine bios on flush and copy");
-static u_int g_journal_cache_used = 0;
-static u_int g_journal_cache_limit = 64 * 1024 * 1024;
-TUNABLE_INT("kern.geom.journal.cache.limit", &g_journal_cache_limit);
+static u_long g_journal_cache_used = 0;
+static u_long g_journal_cache_limit = 64 * 1024 * 1024;
+TUNABLE_LONG("kern.geom.journal.cache.limit", &g_journal_cache_limit);
static u_int g_journal_cache_divisor = 2;
TUNABLE_INT("kern.geom.journal.cache.divisor", &g_journal_cache_divisor);
static u_int g_journal_cache_switch = 90;
static u_int g_journal_cache_misses = 0;
static u_int g_journal_cache_alloc_failures = 0;
-static u_int g_journal_cache_low = 0;
+static u_long g_journal_cache_low = 0;
static SYSCTL_NODE(_kern_geom_journal, OID_AUTO, cache, CTLFLAG_RW, 0,
"GEOM_JOURNAL cache");
-SYSCTL_UINT(_kern_geom_journal_cache, OID_AUTO, used, CTLFLAG_RD,
+SYSCTL_ULONG(_kern_geom_journal_cache, OID_AUTO, used, CTLFLAG_RD,
&g_journal_cache_used, 0, "Number of allocated bytes");
static int
g_journal_cache_limit_sysctl(SYSCTL_HANDLER_ARGS)
{
- u_int limit;
+ u_long limit;
int error;
limit = g_journal_cache_limit;
- error = sysctl_handle_int(oidp, &limit, 0, req);
+ error = sysctl_handle_long(oidp, &limit, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
g_journal_cache_limit = limit;
@@ -160,7 +161,7 @@
return (0);
}
SYSCTL_PROC(_kern_geom_journal_cache, OID_AUTO, limit,
- CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, g_journal_cache_limit_sysctl, "I",
+ CTLTYPE_ULONG | CTLFLAG_RW, NULL, 0, g_journal_cache_limit_sysctl, "I",
"Maximum number of allocated bytes");
SYSCTL_UINT(_kern_geom_journal_cache, OID_AUTO, divisor, CTLFLAG_RDTUN,
&g_journal_cache_divisor, 0,
@@ -175,7 +176,7 @@
error = sysctl_handle_int(oidp, &cswitch, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
- if (cswitch < 0 || cswitch > 100)
+ if (cswitch > 100)
return (EINVAL);
g_journal_cache_switch = cswitch;
g_journal_cache_low = (g_journal_cache_limit / 100) * cswitch;
@@ -230,11 +231,14 @@
static int g_journal_destroy(struct g_journal_softc *sc);
static void g_journal_metadata_update(struct g_journal_softc *sc);
+static void g_journal_start_switcher(struct g_class *mp);
+static void g_journal_stop_switcher(void);
static void g_journal_switch_wait(struct g_journal_softc *sc);
#define GJ_SWITCHER_WORKING 0
#define GJ_SWITCHER_DIE 1
#define GJ_SWITCHER_DIED 2
+static struct proc *g_journal_switcher_proc = NULL;
static int g_journal_switcher_state = GJ_SWITCHER_WORKING;
static int g_journal_switcher_wokenup = 0;
static int g_journal_sync_requested = 0;
@@ -341,7 +345,9 @@
(sc->sc_active.jj_offset > sc->sc_inactive.jj_offset &&
sc->sc_journal_offset >= sc->sc_inactive.jj_offset &&
sc->sc_journal_offset < sc->sc_active.jj_offset)) {
- panic("Journal overflow (joffset=%jd active=%jd inactive=%jd)",
+ panic("Journal overflow "
+ "(id = %u joffset=%jd active=%jd inactive=%jd)",
+ (unsigned)sc->sc_id,
(intmax_t)sc->sc_journal_offset,
(intmax_t)sc->sc_active.jj_offset,
(intmax_t)sc->sc_inactive.jj_offset);
@@ -1234,7 +1240,7 @@
struct g_provider *pp;
struct bio **bioq;
struct bio *bp, *fbp, *pbp;
- off_t joffset, size;
+ off_t joffset;
u_char *data, hash[16];
MD5_CTX ctx;
u_int i;
@@ -1242,7 +1248,6 @@
if (sc->sc_current_count == 0)
return;
- size = 0;
pp = sc->sc_jprovider;
GJ_VALIDATE_OFFSET(sc->sc_journal_offset, sc);
joffset = sc->sc_journal_offset;
@@ -1259,7 +1264,7 @@
strlcpy(hdr.jrh_magic, GJ_RECORD_HEADER_MAGIC, sizeof(hdr.jrh_magic));
bioq = &sc->sc_active.jj_queue;
- pbp = sc->sc_flush_queue;
+ GJQ_LAST(sc->sc_flush_queue, pbp);
fbp = g_alloc_bio();
fbp->bio_parent = NULL;
@@ -1292,7 +1297,6 @@
ent->je_offset = bp->bio_offset;
ent->je_joffset = joffset;
ent->je_length = bp->bio_length;
- size += ent->je_length;
data = bp->bio_data;
if (sc->sc_flags & GJF_DEVICE_CHECKSUM)
@@ -1514,49 +1518,10 @@
}
/*
- * Try to find requested data in cache.
- */
-static struct bio *
-g_journal_read_queue_find(struct bio_queue *head, struct bio *pbp, off_t ostart,
- off_t oend)
-{
- off_t cstart, cend;
- struct bio *bp;
-
- TAILQ_FOREACH(bp, head, bio_queue) {
- cstart = MAX(ostart, bp->bio_offset);
- cend = MIN(oend, bp->bio_offset + bp->bio_length);
- if (cend <= ostart)
- continue;
- else if (cstart >= oend)
- continue;
- KASSERT(bp->bio_data != NULL,
- ("%s: bio_data == NULL", __func__));
- GJ_DEBUG(3, "READ(%p): (%jd, %jd) (bp=%p)", head, cstart, cend,
- bp);
- bcopy(bp->bio_data + cstart - bp->bio_offset,
- pbp->bio_data + cstart - pbp->bio_offset, cend - cstart);
- pbp->bio_completed += cend - cstart;
- if (pbp->bio_completed == pbp->bio_length) {
- /*
- * Cool, the whole request was in cache, deliver happy
- * message.
- */
- g_io_deliver(pbp, 0);
- return (pbp);
- }
- break;
- }
- return (bp);
-}
-
-/*
- * This function is used for colecting data on read.
+ * This function is used for collecting data on read.
* The complexity is because parts of the data can be stored in four different
* places:
- * - in delayed requests
* - in memory - the data not yet send to the active journal provider
- * - in requests which are going to be sent to the active journal
* - in the active journal
* - in the inactive journal
* - in the data provider
@@ -1574,20 +1539,14 @@
cstart = cend = -1;
bp = NULL;
head = NULL;
- for (i = 0; i <= 5; i++) {
+ for (i = 1; i <= 5; i++) {
switch (i) {
- case 0: /* Delayed requests. */
- head = NULL;
- sorted = 0;
- break;
case 1: /* Not-yet-send data. */
head = sc->sc_current_queue;
sorted = 1;
break;
- case 2: /* In-flight to the active journal. */
- head = sc->sc_flush_queue;
- sorted = 0;
- break;
+ case 2: /* Skip flush queue as they are also in active queue */
+ continue;
case 3: /* Active journal. */
head = sc->sc_active.jj_queue;
sorted = 1;
@@ -1606,10 +1565,7 @@
default:
panic("gjournal %s: i=%d", __func__, i);
}
- if (i == 0)
- bp = g_journal_read_queue_find(&sc->sc_delayed_queue.queue, pbp, ostart, oend);
- else
- bp = g_journal_read_find(head, sorted, pbp, ostart, oend);
+ bp = g_journal_read_find(head, sorted, pbp, ostart, oend);
if (bp == pbp) { /* Got the whole request. */
GJ_DEBUG(2, "Got the whole request from %u.", i);
return;
@@ -2315,7 +2271,7 @@
sc->sc_rootmount = root_mount_hold("GJOURNAL");
GJ_DEBUG(1, "root_mount_hold %p", sc->sc_rootmount);
- callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
+ callout_init(&sc->sc_callout, 1);
if (md->md_type != GJ_TYPE_COMPLETE) {
/*
* Journal and data are on separate providers.
@@ -2384,6 +2340,10 @@
sc->sc_jconsumer = cp;
}
+ /* Start switcher kproc if needed. */
+ if (g_journal_switcher_proc == NULL)
+ g_journal_start_switcher(mp);
+
if ((sc->sc_type & GJ_TYPE_COMPLETE) != GJ_TYPE_COMPLETE) {
/* Journal is not complete yet. */
return (gp);
@@ -2463,8 +2423,7 @@
GJ_DEBUG(1, "Marking %s as clean.", sc->sc_name);
g_journal_metadata_update(sc);
g_topology_lock();
- pp->flags |= G_PF_WITHER;
- g_orphan_provider(pp, ENXIO);
+ g_wither_provider(pp, ENXIO);
} else {
g_topology_lock();
}
@@ -2475,6 +2434,7 @@
sc->sc_current_count);
}
+ gp->softc = NULL;
LIST_FOREACH(cp, &gp->consumer, consumer) {
if (cp->acr + cp->acw + cp->ace > 0)
g_access(cp, -1, -1, -1);
@@ -2486,7 +2446,6 @@
*/
g_post_event(g_journal_destroy_consumer, cp, M_WAITOK, NULL);
}
- gp->softc = NULL;
g_wither_geom(gp, ENXIO);
free(sc, M_JOURNAL);
return (0);
@@ -2765,7 +2724,6 @@
static void
g_journal_init(struct g_class *mp)
{
- int error;
/* Pick a conservative value if provided value sucks. */
if (g_journal_cache_divisor <= 0 ||
@@ -2785,9 +2743,6 @@
g_journal_lowmem, mp, EVENTHANDLER_PRI_FIRST);
if (g_journal_event_lowmem == NULL)
GJ_DEBUG(0, "Warning! Cannot register lowmem event.");
- error = kproc_create(g_journal_switcher, mp, NULL, 0, 0,
- "g_journal switcher");
- KASSERT(error == 0, ("Cannot create switcher thread."));
}
static void
@@ -2800,11 +2755,7 @@
}
if (g_journal_event_lowmem != NULL)
EVENTHANDLER_DEREGISTER(vm_lowmem, g_journal_event_lowmem);
- g_journal_switcher_state = GJ_SWITCHER_DIE;
- wakeup(&g_journal_switcher_state);
- while (g_journal_switcher_state != GJ_SWITCHER_DIED)
- tsleep(&g_journal_switcher_state, PRIBIO, "jfini:wait", hz / 5);
- GJ_DEBUG(1, "Switcher died.");
+ g_journal_stop_switcher();
}
DECLARE_GEOM_CLASS(g_journal_class, g_journal);
@@ -2870,7 +2821,7 @@
struct mount *mp;
struct bintime bt;
char *mountpoint;
- int error, save, vfslocked;
+ int error, save;
DROP_GIANT();
g_topology_lock();
@@ -2922,11 +2873,8 @@
mountpoint = mp->mnt_stat.f_mntonname;
- vfslocked = VFS_LOCK_GIANT(mp);
-
error = vn_start_write(NULL, &mp, V_WAIT);
if (error != 0) {
- VFS_UNLOCK_GIANT(vfslocked);
GJ_DEBUG(0, "vn_start_write(%s) failed (error=%d).",
mountpoint, error);
goto next;
@@ -2951,10 +2899,8 @@
vn_finished_write(mp);
- if (error != 0) {
- VFS_UNLOCK_GIANT(vfslocked);
+ if (error != 0)
goto next;
- }
/*
* Send BIO_FLUSH before freezing the file system, so it can be
@@ -2965,8 +2911,7 @@
GJ_TIMER_STOP(1, &bt, "BIO_FLUSH time of %s", sc->sc_name);
GJ_TIMER_START(1, &bt);
- error = vfs_write_suspend(mp);
- VFS_UNLOCK_GIANT(vfslocked);
+ error = vfs_write_suspend(mp, VS_SKIP_UNMOUNT);
GJ_TIMER_STOP(1, &bt, "Suspend time of %s", mountpoint);
if (error != 0) {
GJ_DEBUG(0, "Cannot suspend file system %s (error=%d).",
@@ -2982,7 +2927,7 @@
g_journal_switch_wait(sc);
mtx_unlock(&sc->sc_mtx);
- vfs_write_resume(mp);
+ vfs_write_resume(mp, 0);
next:
mtx_lock(&mountlist_mtx);
vfs_unbusy(mp);
@@ -3016,9 +2961,34 @@
}
}
+static void
+g_journal_start_switcher(struct g_class *mp)
+{
+ int error;
+
+ g_topology_assert();
+ MPASS(g_journal_switcher_proc == NULL);
+ g_journal_switcher_state = GJ_SWITCHER_WORKING;
+ error = kproc_create(g_journal_switcher, mp, &g_journal_switcher_proc,
+ 0, 0, "g_journal switcher");
+ KASSERT(error == 0, ("Cannot create switcher thread."));
+}
+
+static void
+g_journal_stop_switcher(void)
+{
+ g_topology_assert();
+ MPASS(g_journal_switcher_proc != NULL);
+ g_journal_switcher_state = GJ_SWITCHER_DIE;
+ wakeup(&g_journal_switcher_state);
+ while (g_journal_switcher_state != GJ_SWITCHER_DIED)
+ tsleep(&g_journal_switcher_state, PRIBIO, "jfini:wait", hz / 5);
+ GJ_DEBUG(1, "Switcher died.");
+ g_journal_switcher_proc = NULL;
+}
+
/*
- * TODO: Switcher thread should be started on first geom creation and killed on
- * last geom destruction.
+ * TODO: Kill switcher thread on last geom destruction?
*/
static void
g_journal_switcher(void *arg)
@@ -3040,9 +3010,9 @@
kproc_exit(0);
}
if (error == 0 && g_journal_sync_requested == 0) {
- GJ_DEBUG(1, "Out of cache, force switch (used=%u "
- "limit=%u).", g_journal_cache_used,
- g_journal_cache_limit);
+ GJ_DEBUG(1, "Out of cache, force switch (used=%jd "
+ "limit=%jd).", (intmax_t)g_journal_cache_used,
+ (intmax_t)g_journal_cache_limit);
}
GJ_TIMER_START(1, &bt);
g_journal_do_switch(mp);
Modified: trunk/sys/geom/journal/g_journal.h
===================================================================
--- trunk/sys/geom/journal/g_journal.h 2018-05-26 15:24:45 UTC (rev 9970)
+++ trunk/sys/geom/journal/g_journal.h 2018-05-26 15:25:32 UTC (rev 9971)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2005-2006 Pawel Jakub Dawidek <pjd at FreeBSD.org>
* All rights reserved.
@@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/geom/journal/g_journal.h,v 1.1.2.1 2009/04/06 17:33:35 trasz Exp $
+ * $FreeBSD: stable/10/sys/geom/journal/g_journal.h 322793 2017-08-22 15:26:47Z mckusick $
*/
#ifndef _G_JOURNAL_H_
@@ -182,6 +183,17 @@
(pbp)->bio_next = (bp); \
} \
} while (0)
+#define GJQ_LAST(head, bp) do { \
+ struct bio *_bp; \
+ \
+ if ((head) == NULL) { \
+ (bp) = (head); \
+ break; \
+ } \
+ for (_bp = (head); _bp->bio_next != NULL; _bp = _bp->bio_next) \
+ continue; \
+ (bp) = (_bp); \
+} while (0)
#define GJQ_FIRST(head) (head)
#define GJQ_REMOVE(head, bp) do { \
struct bio *_bp; \
@@ -224,7 +236,7 @@
#define GJ_VALIDATE_OFFSET(offset, sc) do { \
if ((offset) + GJ_RECORD_MAX_SIZE(sc) >= (sc)->sc_jend) { \
(offset) = (sc)->sc_jstart; \
- GJ_DEBUG(2, "Starting from the begining (%s).", \
+ GJ_DEBUG(2, "Starting from the beginning (%s).", \
(sc)->sc_name); \
} \
} while (0)
Modified: trunk/sys/geom/journal/g_journal_ufs.c
===================================================================
--- trunk/sys/geom/journal/g_journal_ufs.c 2018-05-26 15:24:45 UTC (rev 9970)
+++ trunk/sys/geom/journal/g_journal_ufs.c 2018-05-26 15:25:32 UTC (rev 9971)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
/*-
* Copyright (c) 2005-2006 Pawel Jakub Dawidek <pjd at FreeBSD.org>
* All rights reserved.
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/journal/g_journal_ufs.c,v 1.1 2006/10/31 21:31:00 pjd Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/journal/g_journal_ufs.c 163837 2006-10-31 21:31:00Z pjd $");
#include <sys/param.h>
#include <sys/systm.h>
More information about the Midnightbsd-cvs
mailing list