diff options
author | mckusick <mckusick@FreeBSD.org> | 2017-08-22 15:26:47 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2017-08-22 15:26:47 +0000 |
commit | cf7edb6f8a8bfa0757ee645985341e7298d5dd40 (patch) | |
tree | ff1f74cd8cda822d1a4ececa3191b9d015f2a3c2 | |
parent | 52f2fa0c0098861f3094865083aa0200af927b1b (diff) | |
download | FreeBSD-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.c | 66 | ||||
-rw-r--r-- | sys/geom/journal/g_journal.h | 11 |
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; \ |