summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2014-07-01 06:59:23 +0000
committerscottl <scottl@FreeBSD.org>2014-07-01 06:59:23 +0000
commita79b0da86bae072e2bc32c6dd62a668b35e0fd52 (patch)
tree082c3721d0a546f2cd171ca6046bf387f6bd283f /sys/ufs/ffs
parentd13d12a6a26e418df2db142c316803da69b8230f (diff)
downloadFreeBSD-src-a79b0da86bae072e2bc32c6dd62a668b35e0fd52.zip
FreeBSD-src-a79b0da86bae072e2bc32c6dd62a668b35e0fd52.tar.gz
Merge r265463:
Due to reasons unknown at this time, the system can be forced to write a journal block even when there are no journal entries to be written. Until the root cause is found, handle this case by ensuring that a valid journal segment is always written. Second, the data buffer used for writing journal entries was never being scrubbed of old data. Fix this. Submitted by: Takehara Mikihito Obtained from: Netflix, Inc.
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index d65554b..2e0adb0 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -1275,6 +1275,7 @@ static int stat_cleanup_blkrequests; /* Number of block cleanup requests */
static int stat_cleanup_inorequests; /* Number of inode cleanup requests */
static int stat_cleanup_retries; /* Number of cleanups that needed to flush */
static int stat_cleanup_failures; /* Number of cleanup requests that failed */
+static int stat_emptyjblocks; /* Number of potentially empty journal blocks */
SYSCTL_INT(_debug_softdep, OID_AUTO, max_softdeps, CTLFLAG_RW,
&max_softdeps, 0, "");
@@ -1334,6 +1335,8 @@ SYSCTL_INT(_debug_softdep, OID_AUTO, cleanup_failures, CTLFLAG_RW,
&stat_cleanup_failures, 0, "");
SYSCTL_INT(_debug_softdep, OID_AUTO, flushcache, CTLFLAG_RW,
&softdep_flushcache, 0, "");
+SYSCTL_INT(_debug_softdep, OID_AUTO, emptyjblocks, CTLFLAG_RD,
+ &stat_emptyjblocks, 0, "");
SYSCTL_DECL(_vfs_ffs);
@@ -3328,6 +3331,24 @@ softdep_process_journal(mp, needwk, flags)
*/
data = bp->b_data;
off = 0;
+
+ /*
+ * Always put a header on the first block.
+ * XXX As with below, there might not be a chance to get
+ * into the loop. Ensure that something valid is written.
+ */
+ jseg_write(ump, jseg, data);
+ off += JREC_SIZE;
+ data = bp->b_data + off;
+
+ /*
+ * XXX Something is wrong here. There's no work to do,
+ * but we need to perform and I/O and allow it to complete
+ * anyways.
+ */
+ if (LIST_EMPTY(&ump->softdep_journal_pending))
+ stat_emptyjblocks++;
+
while ((wk = LIST_FIRST(&ump->softdep_journal_pending))
!= NULL) {
if (cnt == 0)
@@ -3377,6 +3398,11 @@ softdep_process_journal(mp, needwk, flags)
data = bp->b_data + off;
cnt--;
}
+
+ /* Clear any remaining space so we don't leak kernel data */
+ if (size > off)
+ bzero(data, size - off);
+
/*
* Write this one buffer and continue.
*/
OpenPOWER on IntegriCloud