summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2017-08-22 15:26:47 +0000
committermckusick <mckusick@FreeBSD.org>2017-08-22 15:26:47 +0000
commitcf7edb6f8a8bfa0757ee645985341e7298d5dd40 (patch)
treeff1f74cd8cda822d1a4ececa3191b9d015f2a3c2
parent52f2fa0c0098861f3094865083aa0200af927b1b (diff)
downloadFreeBSD-src-cf7edb6f8a8bfa0757ee645985341e7298d5dd40.zip
FreeBSD-src-cf7edb6f8a8bfa0757ee645985341e7298d5dd40.tar.gz
MFC of 269692, 322179, 322463, and 322464:
269692: cswitch is unsigned, so don't compare it < 0 322179: Correct ordering of bio's in gjournal queue 322463: Eliminate a variable that is set-only in g_journal.c 322464: Correct check for reads in gjournal Submitted by: Dr. Andreas Longwitz <longwitz@incore.de> Discussed with: kib Approved by: re (marius)
-rw-r--r--sys/geom/journal/g_journal.c66
-rw-r--r--sys/geom/journal/g_journal.h11
2 files changed, 19 insertions, 58 deletions
diff --git a/sys/geom/journal/g_journal.c b/sys/geom/journal/g_journal.c
index eeae2d1..853312c 100644
--- a/sys/geom/journal/g_journal.c
+++ b/sys/geom/journal/g_journal.c
@@ -175,7 +175,7 @@ g_journal_cache_switch_sysctl(SYSCTL_HANDLER_ARGS)
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;
@@ -1239,7 +1239,7 @@ g_journal_flush(struct g_journal_softc *sc)
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;
@@ -1247,7 +1247,6 @@ g_journal_flush(struct g_journal_softc *sc)
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;
@@ -1264,7 +1263,7 @@ g_journal_flush(struct g_journal_softc *sc)
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;
@@ -1297,7 +1296,6 @@ g_journal_flush(struct g_journal_softc *sc)
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)
@@ -1519,49 +1517,10 @@ g_journal_read_find(struct bio *head, int sorted, struct bio *pbp, off_t ostart,
}
/*
- * 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
@@ -1579,20 +1538,14 @@ g_journal_read(struct g_journal_softc *sc, struct bio *pbp, off_t ostart,
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;
@@ -1611,10 +1564,7 @@ g_journal_read(struct g_journal_softc *sc, struct bio *pbp, off_t ostart,
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;
diff --git a/sys/geom/journal/g_journal.h b/sys/geom/journal/g_journal.h
index 392dc77..d0991d9 100644
--- a/sys/geom/journal/g_journal.h
+++ b/sys/geom/journal/g_journal.h
@@ -182,6 +182,17 @@ struct g_journal_softc {
(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; \
OpenPOWER on IntegriCloud