From owner-svn-src-all@freebsd.org Mon Aug 7 19:40:04 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 62395DC4070; Mon, 7 Aug 2017 19:40:04 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 315BD7F332; Mon, 7 Aug 2017 19:40:04 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v77Je3Kl060493; Mon, 7 Aug 2017 19:40:03 GMT (envelope-from mckusick@FreeBSD.org) Received: (from mckusick@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v77Je3g3060491; Mon, 7 Aug 2017 19:40:03 GMT (envelope-from mckusick@FreeBSD.org) Message-Id: <201708071940.v77Je3g3060491@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mckusick set sender to mckusick@FreeBSD.org using -f From: Kirk McKusick Date: Mon, 7 Aug 2017 19:40:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r322179 - head/sys/geom/journal X-SVN-Group: head X-SVN-Commit-Author: mckusick X-SVN-Commit-Paths: head/sys/geom/journal X-SVN-Commit-Revision: 322179 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Aug 2017 19:40:04 -0000 Author: mckusick Date: Mon Aug 7 19:40:03 2017 New Revision: 322179 URL: https://svnweb.freebsd.org/changeset/base/322179 Log: gjournal is broken in handling its flush_queue. If we have 10 bio's in the flush_queue: 1 2 3 4 5 6 7 8 9 10 and another 10 bio's go into the flush queue after only the first five bio's are removed from the flush queue, the queue should look like: 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20, but because of the bug we end up with 6 11 12 13 14 15 16 17 18 19 20 7 8 9 10. So the sequence of the bio's is damaged in the flush queue (and therefore in the journal on disk !). This error can be triggered by ffs_snapshot() when a block is read with readblock() and gjournal finds this block in the broken flush queue before it goes to the correct active queue. The fix is to place all new blocks at the end of the queue. Submitted by: Dr. Andreas Longwitz Discussed with: kib MFC after: 1 week Modified: head/sys/geom/journal/g_journal.c head/sys/geom/journal/g_journal.h Modified: head/sys/geom/journal/g_journal.c ============================================================================== --- head/sys/geom/journal/g_journal.c Mon Aug 7 19:18:27 2017 (r322178) +++ head/sys/geom/journal/g_journal.c Mon Aug 7 19:40:03 2017 (r322179) @@ -1261,7 +1261,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; Modified: head/sys/geom/journal/g_journal.h ============================================================================== --- head/sys/geom/journal/g_journal.h Mon Aug 7 19:18:27 2017 (r322178) +++ head/sys/geom/journal/g_journal.h Mon Aug 7 19:40:03 2017 (r322179) @@ -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; \