]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
os/bluestore/BlueFS: pre-extend file size for WAL (.log) files
authorSage Weil <sage@redhat.com>
Thu, 1 Dec 2016 19:36:37 +0000 (14:36 -0500)
committerSage Weil <sage@redhat.com>
Mon, 5 Dec 2016 18:46:52 +0000 (13:46 -0500)
When rocksdb has log recycling on (this is required!), it will
do robust checksums on log records and change playback behavior
to tolerate trailing garbage in the log file.  This normally
allows it to overwrite previous log files, but it can also let
us overwrite arbitrary garbage on the device.

If we allocate some new space for a .log file (already indicated
by the WRITER_WAL hint), extend the size immediately so that each
subsequent append doesn't have to (unless/until we do another
allocation).

This is safe as long as rocksdb recycling is enabled (which it is
by default).

This is faster because we don't have to flush the bluefs log on
every log append during the period after startup before rocksdb
starts recycling log files.

Signed-off-by: Sage Weil <sage@redhat.com>
src/common/config_opts.h
src/os/bluestore/BlueFS.cc

index b9b7b57c1beac6ff2f249d748e9efae75aa6d76b..5695823ef315cc9a498fa6d281f52850434497de 100644 (file)
@@ -982,6 +982,7 @@ OPTION(bluefs_min_flush_size, OPT_U64, 65536)  // ignore flush until its this bi
 OPTION(bluefs_compact_log_sync, OPT_BOOL, false)  // sync or async log compaction?
 OPTION(bluefs_buffered_io, OPT_BOOL, false)
 OPTION(bluefs_allocator, OPT_STR, "bitmap")     // stupid | bitmap
+OPTION(bluefs_preextend_wal_files, OPT_BOOL, true)  // this *requires* that rocksdb has recycling enabled
 
 OPTION(bluestore_bluefs, OPT_BOOL, true)
 OPTION(bluestore_bluefs_env_mirror, OPT_BOOL, false) // mirror to normal Env for debug
index 130fb16bfe6f72120bdf3e01aaefb03979708f44..3706d2d8e2542676edcb196ffa237d4b2fff9385 100644 (file)
@@ -1444,6 +1444,17 @@ int BlueFS::_flush_range(FileWriter *h, uint64_t offset, uint64_t length)
            << dendl;
       return r;
     }
+    if (g_conf->bluefs_preextend_wal_files &&
+       h->writer_type == WRITER_WAL) {
+      // NOTE: this *requires* that rocksdb also has log recycling
+      // enabled and is therefore doing robust CRCs on the log
+      // records.  otherwise, we will fail to reply the rocksdb log
+      // properly due to garbage on the device.
+      h->file->fnode.size = h->file->fnode.get_allocated();
+      dout(10) << __func__ << " extending WAL size to 0x" << std::hex
+              << h->file->fnode.size << std::dec << " to include allocated"
+              << dendl;
+    }
     must_dirty = true;
   }
   if (h->file->fnode.size < offset + length) {