Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DONOTMERGE: merge leveldb upstream #26

Closed
wants to merge 187 commits into from
Closed

Conversation

laanwj
Copy link
Member

@laanwj laanwj commented Nov 6, 2019

This merges the current upstream commit 0c40829 of leveldb into our tree. Closes #25.

Significant changes / points for review:

  • Hardware-accelerated crc32c handling is no longer built-in. It uses the crc32c library. See 5c39524 .

    • I reverted our changes in the affected code.

    • This is build system work for bitcoin. Are we going to subtree crc32c? I think we need to, to be self-contained, and also because there are hardly distribution packages for it.

    • cool: google's crc32 library implements CRC32C on some more platforms than just x86 as before, for ex. ARM

  • port_posix[_sse].(h|cc) is no longer used, it has been replaced by header-only port_stdcxx.h (based on C++11 threading primitives). The posix file, as well as build_detect_platform still lingers along but are not used by the CMake build system (note this is about port_ which implements threading functions, not env_ that implements file functions).

    • Need to investigate whether port_stdcxx.h is sufficient on windows. Possibly, we want to keep using port_win.h there. Selection happens in port.h. I have not tried to build for windows yet.
  • I had to re-implement two changes (see separate commits):

    • Do not crash if filesystem can't fsync
    • Increase maximum read-only mmap()s used from 1000 to 4096 on 64-bit systems
      • We might be able to drop this patch completely, if we're willing to use a test interface SetReadOnlyMMapLimit:
// A helper for the POSIX Env to facilitate testing.
class EnvPosixTestHelper {
 private:
  friend class EnvPosixTest;

  // Set the maximum number of read-only files that will be opened.
  // Must be called before creating an Env.
  static void SetReadOnlyFDLimit(int limit);

  // Set the maximum number of read-only files that will be mapped via mmap.
  // Must be called before creating an Env.
  static void SetReadOnlyMMapLimit(int limit);
};
  • There's a native env port for windows included now! util/env_windows.cc, similar to our own env_win.cc.

    • TODO: investigate the differences
  • The configuration system changed. There's now port_config.h generated by CMake that defines a few environment specific parameters:

    • HAVE_FDATASYNC Define to 1 if you have a definition for fdatasync() in <unistd.h>.
    • HAVE_FULLFSYNC Define to 1 if you have a definition for F_FULLFSYNC in <fcntl.h>.
    • HAVE_O_CLOEXEC Define to 1 if you have a definition for O_CLOEXEC in <fcntl.h>.
    • HAVE_CRC32C Define to 1 if you have Google CRC32C.
    • HAVE_SNAPPY Define to 1 if you have Google Snappy. (should be hardwired to 0, obviously)
    • LEVELDB_IS_BIG_ENDIAN Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX).

wankai and others added 30 commits January 29, 2015 14:15
This can be used to report metrics on LevelDB usage.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=156934930
BTRFS reorders rename and write operations, so it is possible that a filesystem crash and recovery results in a situation where the file pointed to by CURRENT does not exist. DB::Open currently reports an I/O error in this case. Reporting database corruption is a better hint to the caller, which can attempt to recover the database or erase it and start over.

This issue is not merely theoretical. It was reported as having showed up in the wild at google#195 and at https://crbug.com/738961. Also, asides from the BTRFS case described above, incorrect data in CURRENT seems like a possible corruption case that should be handled gracefully.

The Env API changes here can be considered backwards compatible, because an implementation that returns Status::IOError instead of Status::NotFound will still get the same functionality as before.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=161432630
Use __APPLE__ instead of OS_MACOS when testing for the Apple platform and
remove the latter symbol from the BUILD file. This fixes incompatibility issues
when using the library on an Apple device.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=162958094
The dead code has been in the codebase since the initial commit and is
generating a compiler warning when used in Xcode.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=164174594
When faced with a pointer that is misaligned by K bytes (pointer % 8 ==
K), the code previously moved forward by K bytes. In order to end up
with an aligned pointer, the code must move by 8 - K bytes.

This lands google#488

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=166295921
An Android test was occasionally crashing with a SEGV in ConsumeDecimalNumber
Switching a local variable from an int to uint64_t eliminated these crashes.
Speculating this is either a compiler, runtime library, or emulator issue.

Switching this type to uint64_t also eliminates a compiler warning
about comparing an int with a uint64_t.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=166399695
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=167303843
12 lines above, there is an "if (!s.ok()) { return s; }" block of code.
"s" is never modified between that block and the "if" removed by this
CL, so "s.ok()" must be true.

The code most likely intended to say "if (!builder->ok())", because the
builder->Add() call above can modify the TableBuilder's status, as a
side-effect. However, this approach would have required setting "s =
builder.status()" in the "else" branch, near the "builder.Abandon()"
call. So, removing the "if" outright is simpler than following that line
of thought.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=167326229
Benchmark results below. More results at
google/crc32c@354d61e.

New, MacBookPro13,3 with Core i7 6920HQ:
LevelDB:    version 1.20
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    1000000
RawSize:    110.6 MB (estimated)
FileSize:   62.9 MB (estimated)
WARNING: Snappy compression is not enabled
------------------------------------------------
fillseq      :       2.952 micros/op;   37.5 MB/s
fillsync     :      43.932 micros/op;    2.5 MB/s (1000 ops)
fillrandom   :       3.856 micros/op;   28.7 MB/s
overwrite    :       4.053 micros/op;   27.3 MB/s
readrandom   :       4.234 micros/op; (1000000 of 1000000 found)
readrandom   :       3.923 micros/op; (1000000 of 1000000 found)
readseq      :       0.201 micros/op;  550.8 MB/s
readreverse  :       0.356 micros/op;  310.6 MB/s
compact      :  436800.000 micros/op;
readrandom   :       2.375 micros/op; (1000000 of 1000000 found)
readseq      :       0.151 micros/op;  734.3 MB/s
readreverse  :       0.298 micros/op;  370.7 MB/s
fill100K     :     554.075 micros/op;  172.1 MB/s (1000 ops)
crc32c       :       1.393 micros/op; 2805.0 MB/s (4K per op)
snappycomp   :    3902.000 micros/op; (snappy failure)
snappyuncomp :    3821.000 micros/op; (snappy failure)
acquireload  :      13.088 micros/op; (each op is 1000 loads)

Baseline, MacBookPro13,3 with Core i7 6920HQ:
LevelDB:    version 1.20
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    1000000
RawSize:    110.6 MB (estimated)
FileSize:   62.9 MB (estimated)
WARNING: Snappy compression is not enabled
------------------------------------------------
fillseq      :       3.000 micros/op;   36.9 MB/s
fillsync     :      46.721 micros/op;    2.4 MB/s (1000 ops)
fillrandom   :       3.922 micros/op;   28.2 MB/s
overwrite    :       4.080 micros/op;   27.1 MB/s
readrandom   :       4.409 micros/op; (1000000 of 1000000 found)
readrandom   :       3.895 micros/op; (1000000 of 1000000 found)
readseq      :       0.190 micros/op;  582.4 MB/s
readreverse  :       0.413 micros/op;  267.6 MB/s
compact      :  441076.000 micros/op;
readrandom   :       2.308 micros/op; (1000000 of 1000000 found)
readseq      :       0.170 micros/op;  651.2 MB/s
readreverse  :       0.302 micros/op;  366.2 MB/s
fill100K     :     614.289 micros/op;  155.3 MB/s (1000 ops)
crc32c       :       3.547 micros/op; 1101.2 MB/s (4K per op)
snappycomp   :    3393.000 micros/op; (snappy failure)
snappyuncomp :    3171.000 micros/op; (snappy failure)
acquireload  :      12.761 micros/op; (each op is 1000 loads)

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170100372
env_posix.cc and concurrent application calls to fflush(NULL).

The fix is to avoid using stdio in env_posix.cc but add our own
buffering where we need it.

Added a test to reproduce the bug.

Added a test for Env reads/writes.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170738066
If leveldb::Options::block_cache is set to a cache of zero capacity
then it is possible for LRUHandle::next to be used without having been
set.

Conditional jump or move depends on uninitialised value(s):
  leveldb::(anonymous namespace)::LRUHandle::key() const (cache.cc:58)
  leveldb::(anonymous namespace)::LRUCache::Unref(leveldb::(anonymous namespace)::LRUHandle*) (cache.cc:234)
  leveldb::(anonymous namespace)::LRUCache::Release(leveldb::Cache::Handle*) (cache.cc:266)
  leveldb::(anonymous namespace)::ShardedLRUCache::Release(leveldb::Cache::Handle*) (cache.cc:375)
  leveldb::CacheTest::Insert(int, int, int) (cache_test.cc:59)

This bug forced a commit reversion in Chromium. For more information see
https://bugs.chromium.org/p/chromium/issues/detail?id=761398#c4

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170749054
If the file already existed, we should have truncated it. This was not
detected by leveldb tests since leveldb code avoids reusing same files,
but there was code elsewhere that was directly using leveldb files and
relying on this behavior.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170769101
This also removes std::unique_ptr introduced in CL 170738066, because
it's C++11-only, and the open source version still supports older
versions at the moment.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170876919
Deleting a PosixWritableFile without calling Close() leaks the file
descriptor. While the API description in include/leveldb/env.h does not
specify whether the caller is responsible for Close()ing the file before
deleting it, all other Env file implementations do release underlying
resources when destroyed, even if Close() is not called.

The leak shows up when running db_tests on Mac Travis, or on a vanilla
MacOS install.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170906843
CL 170738066 introduced std::min and std::max to env_test.cc. These
require the <algorithm> header.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171024062
gcc defaults to exporting all symbols, but other linkers do not. Adding
the LEVELDB_EXPORT macro allows a project to set LEVELDB_SHARED_LIBRARY
when building/linking with leveldb as a shared library.

This is to allow leveldb to be created as a shared library on all
platforms support by Chrome and enables a fix for
https://bugs.chromium.org/p/chromium/issues/detail?id=764810.

This also has the benefit of reducing the shared library size from
418863 to 380367 bytes (64-bit Linux).

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171037148
CL 170738066 removed all instances of fread_unlocked, fwrite_unlocked
and fflush_unlocked calls from the codebase, so the feature detection
can be removed as well.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171154269
This follows the general naming convention for preprocessor macros used
to detect feature (library / header file / symbol) presence.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171184641
Maintaining a hardware-accelerated CRC32C implementation tailored for
all modern platforms deserves a repository of its own. We extracted the
implementation here into https://github.com/google/crc32c and improved
it in that repository. This CL removes the SSE-optimized implementation
from this codebase, and adds the ability to use the google/crc32c
library, if it is present on the system.

The benchmarks below show the performance impact of the change. In
summary, open source builds that use the google/crc32c library can
expect a 3x improvement in CRC32C throughput, whereas builds that do not
use the library will see a 50% drop in CRC32C throughput. This
translates in much smaller changes in overall leveldb performance.

Baseline, MacBookPro13,3 with Core i7 6920HQ:
LevelDB:    version 1.20
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    1000000
RawSize:    110.6 MB (estimated)
FileSize:   62.9 MB (estimated)
------------------------------------------------
fillseq      :       3.064 micros/op;   36.1 MB/s
fillsync     :      57.861 micros/op;    1.9 MB/s (1000 ops)
fillrandom   :       3.887 micros/op;   28.5 MB/s
overwrite    :       4.140 micros/op;   26.7 MB/s
readrandom   :       7.433 micros/op; (1000000 of 1000000 found)
readrandom   :       6.825 micros/op; (1000000 of 1000000 found)
readseq      :       0.244 micros/op;  453.4 MB/s
readreverse  :       0.387 micros/op;  285.8 MB/s
compact      :  449707.000 micros/op;
readrandom   :       4.196 micros/op; (1000000 of 1000000 found)
readseq      :       0.228 micros/op;  485.8 MB/s
readreverse  :       0.320 micros/op;  345.2 MB/s
fill100K     :     562.556 micros/op;  169.6 MB/s (1000 ops)
crc32c       :       0.768 micros/op; 5085.0 MB/s (4K per op)
snappycomp   :       4.220 micros/op;  925.7 MB/s (output: 55.1%)
snappyuncomp :       0.635 micros/op; 6155.7 MB/s
acquireload  :      13.054 micros/op; (each op is 1000 loads)

New with crc32c, MacBookPro13,3 with Core i7 6920HQ:
LevelDB:    version 1.20
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    1000000
RawSize:    110.6 MB (estimated)
FileSize:   62.9 MB (estimated)
------------------------------------------------
fillseq      :       2.820 micros/op;   39.2 MB/s
fillsync     :      51.988 micros/op;    2.1 MB/s (1000 ops)
fillrandom   :       3.747 micros/op;   29.5 MB/s
overwrite    :       4.047 micros/op;   27.3 MB/s
readrandom   :       7.287 micros/op; (1000000 of 1000000 found)
readrandom   :       6.927 micros/op; (1000000 of 1000000 found)
readseq      :       0.253 micros/op;  437.5 MB/s
readreverse  :       0.411 micros/op;  269.2 MB/s
compact      :  440405.000 micros/op;
readrandom   :       4.159 micros/op; (1000000 of 1000000 found)
readseq      :       0.230 micros/op;  481.1 MB/s
readreverse  :       0.320 micros/op;  345.9 MB/s
fill100K     :     558.222 micros/op;  170.9 MB/s (1000 ops)
crc32c       :       0.214 micros/op; 18263.5 MB/s (4K per op)
snappycomp   :       4.471 micros/op;  873.7 MB/s (output: 55.1%)
snappyuncomp :       0.833 micros/op; 4688.5 MB/s
acquireload  :      13.289 micros/op; (each op is 1000 loads)

New without crc32c, MacBookPro13,3 with Core i7 6920HQ
LevelDB:    version 1.20
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    1000000
RawSize:    110.6 MB (estimated)
FileSize:   62.9 MB (estimated)
------------------------------------------------
fillseq      :       3.094 micros/op;   35.8 MB/s
fillsync     :      52.160 micros/op;    2.1 MB/s (1000 ops)
fillrandom   :       4.090 micros/op;   27.0 MB/s
overwrite    :       4.006 micros/op;   27.6 MB/s
readrandom   :       6.584 micros/op; (1000000 of 1000000 found)
readrandom   :       6.676 micros/op; (1000000 of 1000000 found)
readseq      :       0.280 micros/op;  395.2 MB/s
readreverse  :       0.391 micros/op;  283.2 MB/s
compact      :  433911.000 micros/op;
readrandom   :       4.261 micros/op; (1000000 of 1000000 found)
readseq      :       0.251 micros/op;  440.5 MB/s
readreverse  :       0.356 micros/op;  310.9 MB/s
fill100K     :     584.023 micros/op;  163.3 MB/s (1000 ops)
crc32c       :       1.384 micros/op; 2822.3 MB/s (4K per op)
snappycomp   :       4.763 micros/op;  820.1 MB/s (output: 55.1%)
snappyuncomp :       0.766 micros/op; 5098.6 MB/s
acquireload  :      12.931 micros/op; (each op is 1000 loads)

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171667771
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171708408
Env's that filtered out dot files ("." and "..") would return an
empty vector of children causing DestroyDB to do nothing. This fixes
google#215

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=172501335
Deleted two unused assignments:

1. offset_in_block in Reader::SkipToInitialBlock().
2. in_fragmented_record in Reader::ReadRecord().

Reasons for the change:
1. offset_in_block is not read again after the if condition.
2. The kFullRecordType switch branch returns, so
   in_fragmented_record isn't read again.
3. The kFirstType switch branch sets in_fragmented_record to
   true after the if, so the write in the if is ignored.

Change contributed by @C0deAi on GitHub.

This fixes google#517

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=172763897
The C++ style guide URL was wrong.

This fixes issue google#394. Reported by GitHub user @Loki-Astari.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=173188573
cmumford and others added 6 commits October 28, 2019 13:23
Added unreached return at the end of Version::Get::State::Match
to stop this _incorrect_ warning:

    version_set.cc:376:5: warning: control reaches end of
    non-void function [-Wreturn-type]

This warning was being emitted when building with clang 6.0.1-10
and also emitted by lgtm.com when statically analyzing leveldb even
though all SaverState enumeration values were handled.

PiperOrigin-RevId: 272455474
The local variable `updates` in DBImpl::Write was hiding the
`updates` parameter. Renamed to avoid this conflict.

PiperOrigin-RevId: 277089971
PiperOrigin-RevId: 278300591
Using CMAKE_INSTALL_INCLUDEDIR before including GNUINstallDirs results
in a broken installation when CMAKE_INSTALL_PREFIX is a non-standard
directory.

Inspired from google/crc32c#39

PiperOrigin-RevId: 278427974
@sipa
Copy link

sipa commented Nov 6, 2019

Thanks for working on this. I suspect that port_stdcxx.h is actually sufficient on Windows.

@maflcko
Copy link

maflcko commented Nov 6, 2019

Thanks! Concept ACK

@laanwj
Copy link
Member Author

laanwj commented Nov 6, 2019

After some discussion on IRC I'm thinking of re-starting as a patch stack on upstream. It looks like pretty much all our changes have been subsumed, apart from the things I've already had to locate and reimplement 😄

@laanwj
Copy link
Member Author

laanwj commented Nov 6, 2019

I pushed a series of reverts. The diff with upstream is only 336 lines now: I'll just post it here:

Diff
diff --git a/db/db_impl.cc b/db/db_impl.cc
index 95e2bb4107d03a77c58c72af3659aafabeb3b4db..65e31724bcec1b6e80480d928f129b21be59fba1 100644
--- a/db/db_impl.cc
+++ b/db/db_impl.cc
@@ -428,7 +428,7 @@ Status DBImpl::RecoverLogFile(uint64_t log_number, bool last_log,
   while (reader.ReadRecord(&record, &scratch) && status.ok()) {
     if (record.size() < 12) {
       reporter.Corruption(record.size(),
-                          Status::Corruption("log record too small"));
+                          Status::Corruption("log record too small", fname));
       continue;
     }
     WriteBatchInternal::SetContents(&batch, record);
diff --git a/db/db_test.cc b/db/db_test.cc
index 9a8faf100672edb816f6d94251ee7c8039c7f559..beb1d3bdef61d6a885061c8eb95f1c2d13dd0d2a 100644
--- a/db/db_test.cc
+++ b/db/db_test.cc
@@ -158,6 +158,7 @@ class SpecialEnv : public EnvWrapper {
         }
         return base_->Sync();
       }
+      std::string GetName() const override { return ""; }
     };
     class ManifestFile : public WritableFile {
      private:
@@ -183,6 +184,7 @@ class SpecialEnv : public EnvWrapper {
           return base_->Sync();
         }
       }
+      std::string GetName() const override { return ""; }
     };
 
     if (non_writable_.load(std::memory_order_acquire)) {
@@ -216,6 +218,7 @@ class SpecialEnv : public EnvWrapper {
         counter_->Increment();
         return target_->Read(offset, n, result, scratch);
       }
+      std::string GetName() const override { return ""; }
     };
 
     Status s = target()->NewRandomAccessFile(f, r);
diff --git a/db/fault_injection_test.cc b/db/fault_injection_test.cc
index 5b31bb8053f2650c213b2152d0d78551dc86e613..bf705cb60f2431f8b6d163a5fd94656b47eda431 100644
--- a/db/fault_injection_test.cc
+++ b/db/fault_injection_test.cc
@@ -114,6 +114,7 @@ class TestWritableFile : public WritableFile {
   Status Close() override;
   Status Flush() override;
   Status Sync() override;
+  std::string GetName() const override { return ""; }
 
  private:
   FileState state_;
diff --git a/db/leveldbutil.cc b/db/leveldbutil.cc
index 55cdcc5772236a042a63a25fd260fcc1e412ec69..f4ecbc7ab4cec715b5d391994492b17452c4386c 100644
--- a/db/leveldbutil.cc
+++ b/db/leveldbutil.cc
@@ -17,9 +17,10 @@ class StdoutPrinter : public WritableFile {
     fwrite(data.data(), 1, data.size(), stdout);
     return Status::OK();
   }
-  Status Close() override { return Status::OK(); }
-  Status Flush() override { return Status::OK(); }
-  Status Sync() override { return Status::OK(); }
+  Status Close() { return Status::OK(); }
+  Status Flush() { return Status::OK(); }
+  Status Sync() { return Status::OK(); }
+  std::string GetName() const override { return "[stdout]"; }
 };
 
 bool HandleDumpCommand(Env* env, char** files, int num) {
diff --git a/db/log_reader.cc b/db/log_reader.cc
index b770fee1a0de25d64e180620bf7d15fc2d770394..1ccfb7b34aa85a6f37b5e515ff10e09b786c642a 100644
--- a/db/log_reader.cc
+++ b/db/log_reader.cc
@@ -176,7 +176,7 @@ bool Reader::ReadRecord(Slice* record, std::string* scratch) {
 uint64_t Reader::LastRecordOffset() { return last_record_offset_; }
 
 void Reader::ReportCorruption(uint64_t bytes, const char* reason) {
-  ReportDrop(bytes, Status::Corruption(reason));
+  ReportDrop(bytes, Status::Corruption(reason, file_->GetName()));
 }
 
 void Reader::ReportDrop(uint64_t bytes, const Status& reason) {
diff --git a/db/log_test.cc b/db/log_test.cc
index 0e31648cc8ffcd2e3d8ff4e3abd4917bfe401c32..41fc043068dcec4d587f36d80bff5013761e1149 100644
--- a/db/log_test.cc
+++ b/db/log_test.cc
@@ -168,6 +168,7 @@ class LogTest {
       contents_.append(slice.data(), slice.size());
       return Status::OK();
     }
+    std::string GetName() const override { return ""; }
 
     std::string contents_;
   };
@@ -204,6 +205,7 @@ class LogTest {
 
       return Status::OK();
     }
+    std::string GetName() const { return ""; }
 
     Slice contents_;
     bool force_error_;
diff --git a/db/repair.cc b/db/repair.cc
index d9d12ba556f0e78bd50218c4f9b06c9283fdd0a8..04847c3bbfb73d40f3c2ebb90ef701fd957ea3b1 100644
--- a/db/repair.cc
+++ b/db/repair.cc
@@ -183,7 +183,7 @@ class Repairer {
     while (reader.ReadRecord(&record, &scratch)) {
       if (record.size() < 12) {
         reporter.Corruption(record.size(),
-                            Status::Corruption("log record too small"));
+                            Status::Corruption("log record too small", logname));
         continue;
       }
       WriteBatchInternal::SetContents(&batch, record);
diff --git a/helpers/memenv/memenv.cc b/helpers/memenv/memenv.cc
index 31d2bc0f6f63a159ad30b129603716f35336cd79..95fa4ae8beacee380c2a851942029bf10b057b2a 100644
--- a/helpers/memenv/memenv.cc
+++ b/helpers/memenv/memenv.cc
@@ -178,6 +178,7 @@ class SequentialFileImpl : public SequentialFile {
     return Status::OK();
   }
 
+  virtual std::string GetName() const { return "[memenv]"; }
  private:
   FileState* file_;
   uint64_t pos_;
@@ -194,6 +195,7 @@ class RandomAccessFileImpl : public RandomAccessFile {
     return file_->Read(offset, n, result, scratch);
   }
 
+  virtual std::string GetName() const { return "[memenv]"; }
  private:
   FileState* file_;
 };
@@ -210,6 +212,7 @@ class WritableFileImpl : public WritableFile {
   Status Flush() override { return Status::OK(); }
   Status Sync() override { return Status::OK(); }
 
+  virtual std::string GetName() const { return "[memenv]"; }
  private:
   FileState* file_;
 };
diff --git a/include/leveldb/env.h b/include/leveldb/env.h
index 112fe964fb1cb2ce3e208ba64b92a82147279266..96c21b3966c4c35a6012450474f12868dc4e006b 100644
--- a/include/leveldb/env.h
+++ b/include/leveldb/env.h
@@ -217,6 +217,9 @@ class LEVELDB_EXPORT SequentialFile {
   //
   // REQUIRES: External synchronization
   virtual Status Skip(uint64_t n) = 0;
+
+  // Get a name for the file, only for error reporting
+  virtual std::string GetName() const = 0;
 };
 
 // A file abstraction for randomly reading the contents of a file.
@@ -240,6 +243,9 @@ class LEVELDB_EXPORT RandomAccessFile {
   // Safe for concurrent use by multiple threads.
   virtual Status Read(uint64_t offset, size_t n, Slice* result,
                       char* scratch) const = 0;
+
+  // Get a name for the file, only for error reporting
+  virtual std::string GetName() const = 0;
 };
 
 // A file abstraction for sequential writing.  The implementation
@@ -258,6 +264,9 @@ class LEVELDB_EXPORT WritableFile {
   virtual Status Close() = 0;
   virtual Status Flush() = 0;
   virtual Status Sync() = 0;
+
+  // Get a name for the file, only for error reporting
+  virtual std::string GetName() const = 0;
 };
 
 // An interface for writing log messages.
diff --git a/table/format.cc b/table/format.cc
index e1839779e4bab2d595fd996241da4a4184db2f2b..a3d67de2e41d4ffa16e927432ee389568cfda32f 100644
--- a/table/format.cc
+++ b/table/format.cc
@@ -79,7 +79,7 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
   }
   if (contents.size() != n + kBlockTrailerSize) {
     delete[] buf;
-    return Status::Corruption("truncated block read");
+    return Status::Corruption("truncated block read", file->GetName());
   }
 
   // Check the crc of the type and the block contents
@@ -89,7 +89,7 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
     const uint32_t actual = crc32c::Value(data, n + 1);
     if (actual != crc) {
       delete[] buf;
-      s = Status::Corruption("block checksum mismatch");
+      s = Status::Corruption("block checksum mismatch", file->GetName());
       return s;
     }
   }
@@ -116,13 +116,13 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
       size_t ulength = 0;
       if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
         delete[] buf;
-        return Status::Corruption("corrupted compressed block contents");
+        return Status::Corruption("corrupted compressed block contents", file->GetName());
       }
       char* ubuf = new char[ulength];
       if (!port::Snappy_Uncompress(data, n, ubuf)) {
         delete[] buf;
         delete[] ubuf;
-        return Status::Corruption("corrupted compressed block contents");
+        return Status::Corruption("corrupted compressed block contents", file->GetName());
       }
       delete[] buf;
       result->data = Slice(ubuf, ulength);
@@ -132,7 +132,7 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
     }
     default:
       delete[] buf;
-      return Status::Corruption("bad block type");
+      return Status::Corruption("bad block type", file->GetName());
   }
 
   return Status::OK();
diff --git a/table/table_test.cc b/table/table_test.cc
index f689a276577e02c86c1579dd772ecbe4aa932e9a..17aaea2f9e8b48484c4ba129a656854e4681596d 100644
--- a/table/table_test.cc
+++ b/table/table_test.cc
@@ -102,6 +102,7 @@ class StringSink : public WritableFile {
     return Status::OK();
   }
 
+  std::string GetName() const override { return ""; }
  private:
   std::string contents_;
 };
@@ -128,6 +129,7 @@ class StringSource : public RandomAccessFile {
     return Status::OK();
   }
 
+  std::string GetName() const { return ""; }
  private:
   std::string contents_;
 };
diff --git a/util/env_posix.cc b/util/env_posix.cc
index 00ca9aedef58b2bd6e2439cc52dee37fffb67c97..9f5863a0f35abdfe5c702fd0df2100dcab0ce70a 100644
--- a/util/env_posix.cc
+++ b/util/env_posix.cc
@@ -42,8 +42,8 @@ namespace {
 // Set by EnvPosixTestHelper::SetReadOnlyMMapLimit() and MaxOpenFiles().
 int g_open_read_only_file_limit = -1;
 
-// Up to 1000 mmap regions for 64-bit binaries; none for 32-bit.
-constexpr const int kDefaultMmapLimit = (sizeof(void*) >= 8) ? 1000 : 0;
+// Up to 4096 mmap regions for 64-bit binaries; none for 32-bit.
+constexpr const int kDefaultMmapLimit = (sizeof(void*) >= 8) ? 4096 : 0;
 
 // Can be set using EnvPosixTestHelper::SetReadOnlyMMapLimit().
 int g_mmap_limit = kDefaultMmapLimit;
@@ -135,6 +135,8 @@ class PosixSequentialFile final : public SequentialFile {
     return Status::OK();
   }
 
+  virtual std::string GetName() const override { return filename_; }
+
  private:
   const int fd_;
   const std::string filename_;
@@ -195,6 +197,8 @@ class PosixRandomAccessFile final : public RandomAccessFile {
     return status;
   }
 
+  virtual std::string GetName() const override { return filename_; }
+
  private:
   const bool has_permanent_fd_;  // If false, the file is opened on every read.
   const int fd_;                 // -1 if has_permanent_fd_ is false.
@@ -239,6 +243,8 @@ class PosixMmapReadableFile final : public RandomAccessFile {
     return Status::OK();
   }
 
+  virtual std::string GetName() const override { return filename_; }
+
  private:
   char* const mmap_base_;
   const size_t length_;
@@ -319,7 +325,7 @@ class PosixWritableFile final : public WritableFile {
       return status;
     }
 
-    return SyncFd(fd_, filename_);
+    return SyncFd(fd_, filename_, false);
   }
 
  private:
@@ -354,7 +360,7 @@ class PosixWritableFile final : public WritableFile {
     if (fd < 0) {
       status = PosixError(dirname_, errno);
     } else {
-      status = SyncFd(fd, dirname_);
+      status = SyncFd(fd, dirname_, true);
       ::close(fd);
     }
     return status;
@@ -366,7 +372,7 @@ class PosixWritableFile final : public WritableFile {
   //
   // The path argument is only used to populate the description string in the
   // returned Status if an error occurs.
-  static Status SyncFd(int fd, const std::string& fd_path) {
+  static Status SyncFd(int fd, const std::string& fd_path, bool syncing_dir) {
 #if HAVE_FULLFSYNC
     // On macOS and iOS, fsync() doesn't guarantee durability past power
     // failures. fcntl(F_FULLFSYNC) is required for that purpose. Some
@@ -386,6 +392,11 @@ class PosixWritableFile final : public WritableFile {
     if (sync_success) {
       return Status::OK();
     }
+    // Do not crash if filesystem can't fsync directories
+    // (see https://github.com/bitcoin/bitcoin/pull/10000)
+    if (syncing_dir && errno == EINVAL) {
+      return Status::OK();
+    }
     return PosixError(fd_path, errno);
   }
 
@@ -426,6 +437,8 @@ class PosixWritableFile final : public WritableFile {
     return Basename(filename).starts_with("MANIFEST");
   }
 
+  virtual std::string GetName() const override { return filename_; }
+
   // buf_[0, pos_ - 1] contains data to be written to fd_.
   char buf_[kWritableFileBufferSize];
   size_t pos_;

This is only the following patches:

  • re-apply: Add filename to corruption errors
  • re-apply: Do not crash if filesystem can't fsync
  • re-apply: Increase maximum read-only mmap()s used from 1000 to 4096 on 64-bit systems

I'll need to patch env_windows.cpp for the GetName so it's expected to grow by another three lines or so.

laanwj added 11 commits November 6, 2019 23:17
This reverts commit 77cfbfd.

CRC32C handling has been taken over by the `crc32c` library upstream, so
revert our helper changes.
No longer necessary.
Part of the old build system.
Isn't part of upstream anymore.
When a corruption happens, report the filename of the file where
corruptions happens.  This will aid in diagnosing database corruption
issues.

Adds a GetName() to all the environment file classes to make it possible
to report a filename downstream.
This code moved, re-apply the fix elsewhere.

See
- bitcoin/bitcoin#10000
- bitcoin-core/leveldb-old#16

Original change by Nicolas Dorier.
…n 64-bit systems

This code moved, re-apply it elsewhere.

See #19.

Original change by Clem Taylor.
@laanwj
Copy link
Member Author

laanwj commented Nov 6, 2019

This PR is no longer relevant, except for discussion, I started over at: https://github.com/bitcoin-core/leveldb/tree/bitcoin-fork-new

@laanwj laanwj changed the title WIP: merge leveldb upstream DONOTMERGE: merge leveldb upstream Nov 6, 2019
@laanwj laanwj closed this Nov 20, 2019
laanwj added a commit to bitcoin/bitcoin that referenced this pull request Feb 10, 2020
677fb8e test: Add ubsan surpression for crc32c (Wladimir J. van der Laan)
8e68bb1 build: Disable msvc warning 4722 for leveldb build (Aaron Clauson)
be23949 build: MSVC changes for leveldb update (Aaron Clauson)
9ebdf04 build: CRC32C build system integration (Wladimir J. van der Laan)
402252a build: Add LCOV exception for crc32c (Wladimir J. van der Laan)
3a037d0 test: Add crc32c exception to various linters and generation scripts (Wladimir J. van der Laan)
84ff1b2 test: Add crc32c to subtree check linter (Wladimir J. van der Laan)
7cf13a5 doc: Add crc32c subtree to developer notes (Wladimir J. van der Laan)
24d02a9 build: Update build system for new leveldb (Wladimir J. van der Laan)
2e18193 Squashed 'src/crc32c/' content from commit 224988680f7673cd7c769963d4035cb315aa3388 (Wladimir J. van der Laan)
6648082 Squashed 'src/leveldb/' changes from f545dfa..f8ae182c1e5176d12e816fb2217ae33a5472fdd7 (Wladimir J. van der Laan)

Pull request description:

  This updates leveldb to currently newest upstream commit bitcoin-core/leveldb-subtree@0c40829:

  - CRC32C hardware acceleration is now an external library [crc32c](https://github.com/google/crc32c). This adds acceleration on ARM, and should be faster on x86 because of using prefetch. It also makes it easy to support similar instruction sets on other platforms in the future.
  - Thread handling uses C++11, instead of platform specific code.
  - Native windows environment was added. No need to maintain our own hacky one, anymore.
  - Upstream now builds using CMake. This doesn't mean we need to use that (phew), but internal configuration changed to a a series of checks, instead of OS profiles. This means the blanket error "Cannot build leveldb for $host. Please file a bug report' is removed.

  All changes: google/leveldb@a53934a...0c40829

  Pretty much all our changes have been subsumed by upstream, so we figured it was cleaner to start over with a new branch from upstream with the still-relevant patches applied: https://github.com/bitcoin-core/leveldb/tree/bitcoin-fork-new

  There's quite some testing to be done (see below). See bitcoin-core/leveldb-subtree#25 and bitcoin-core/leveldb-subtree#26 for more history and context.

  TODO:
  - [x] Subtree `crc32c`
  - [x] Make linters happy about crc32 subtree
  - [x] Integrate `crc32c` library into build system
  - [x] MSVC build system

ACKs for top commit:
  sipa:
    ACK 677fb8e

Tree-SHA512: 37ee92a750e053e924bc4626b12bb3fd81faa9f8c5ebaa343931fee810c45ba05aa6051fdea82535fa351bf2be7297801b98af9469865fc5ead771650a5d6240
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Feb 18, 2020
677fb8e test: Add ubsan surpression for crc32c (Wladimir J. van der Laan)
8e68bb1 build: Disable msvc warning 4722 for leveldb build (Aaron Clauson)
be23949 build: MSVC changes for leveldb update (Aaron Clauson)
9ebdf04 build: CRC32C build system integration (Wladimir J. van der Laan)
402252a build: Add LCOV exception for crc32c (Wladimir J. van der Laan)
3a037d0 test: Add crc32c exception to various linters and generation scripts (Wladimir J. van der Laan)
84ff1b2 test: Add crc32c to subtree check linter (Wladimir J. van der Laan)
7cf13a5 doc: Add crc32c subtree to developer notes (Wladimir J. van der Laan)
24d02a9 build: Update build system for new leveldb (Wladimir J. van der Laan)
2e18193 Squashed 'src/crc32c/' content from commit 224988680f7673cd7c769963d4035cb315aa3388 (Wladimir J. van der Laan)
6648082 Squashed 'src/leveldb/' changes from f545dfa..f8ae182c1e5176d12e816fb2217ae33a5472fdd7 (Wladimir J. van der Laan)

Pull request description:

  This updates leveldb to currently newest upstream commit bitcoin-core/leveldb-subtree@0c40829:

  - CRC32C hardware acceleration is now an external library [crc32c](https://github.com/google/crc32c). This adds acceleration on ARM, and should be faster on x86 because of using prefetch. It also makes it easy to support similar instruction sets on other platforms in the future.
  - Thread handling uses C++11, instead of platform specific code.
  - Native windows environment was added. No need to maintain our own hacky one, anymore.
  - Upstream now builds using CMake. This doesn't mean we need to use that (phew), but internal configuration changed to a a series of checks, instead of OS profiles. This means the blanket error "Cannot build leveldb for $host. Please file a bug report' is removed.

  All changes: google/leveldb@a53934a...0c40829

  Pretty much all our changes have been subsumed by upstream, so we figured it was cleaner to start over with a new branch from upstream with the still-relevant patches applied: https://github.com/bitcoin-core/leveldb/tree/bitcoin-fork-new

  There's quite some testing to be done (see below). See bitcoin-core/leveldb-subtree#25 and bitcoin-core/leveldb-subtree#26 for more history and context.

  TODO:
  - [x] Subtree `crc32c`
  - [x] Make linters happy about crc32 subtree
  - [x] Integrate `crc32c` library into build system
  - [x] MSVC build system

ACKs for top commit:
  sipa:
    ACK 677fb8e

Tree-SHA512: 37ee92a750e053e924bc4626b12bb3fd81faa9f8c5ebaa343931fee810c45ba05aa6051fdea82535fa351bf2be7297801b98af9469865fc5ead771650a5d6240
sidhujag pushed a commit to syscoin-core/syscoin that referenced this pull request Nov 10, 2020
677fb8e test: Add ubsan surpression for crc32c (Wladimir J. van der Laan)
8e68bb1 build: Disable msvc warning 4722 for leveldb build (Aaron Clauson)
be23949 build: MSVC changes for leveldb update (Aaron Clauson)
9ebdf04 build: CRC32C build system integration (Wladimir J. van der Laan)
402252a build: Add LCOV exception for crc32c (Wladimir J. van der Laan)
3a037d0 test: Add crc32c exception to various linters and generation scripts (Wladimir J. van der Laan)
84ff1b2 test: Add crc32c to subtree check linter (Wladimir J. van der Laan)
7cf13a5 doc: Add crc32c subtree to developer notes (Wladimir J. van der Laan)
24d02a9 build: Update build system for new leveldb (Wladimir J. van der Laan)
2e18193 Squashed 'src/crc32c/' content from commit 224988680f7673cd7c769963d4035cb315aa3388 (Wladimir J. van der Laan)
6648082 Squashed 'src/leveldb/' changes from f545dfa..f8ae182c1e5176d12e816fb2217ae33a5472fdd7 (Wladimir J. van der Laan)

Pull request description:

  This updates leveldb to currently newest upstream commit bitcoin-core/leveldb-subtree@0c40829:

  - CRC32C hardware acceleration is now an external library [crc32c](https://github.com/google/crc32c). This adds acceleration on ARM, and should be faster on x86 because of using prefetch. It also makes it easy to support similar instruction sets on other platforms in the future.
  - Thread handling uses C++11, instead of platform specific code.
  - Native windows environment was added. No need to maintain our own hacky one, anymore.
  - Upstream now builds using CMake. This doesn't mean we need to use that (phew), but internal configuration changed to a a series of checks, instead of OS profiles. This means the blanket error "Cannot build leveldb for $host. Please file a bug report' is removed.

  All changes: google/leveldb@a53934a...0c40829

  Pretty much all our changes have been subsumed by upstream, so we figured it was cleaner to start over with a new branch from upstream with the still-relevant patches applied: https://github.com/bitcoin-core/leveldb/tree/bitcoin-fork-new

  There's quite some testing to be done (see below). See bitcoin-core/leveldb-subtree#25 and bitcoin-core/leveldb-subtree#26 for more history and context.

  TODO:
  - [x] Subtree `crc32c`
  - [x] Make linters happy about crc32 subtree
  - [x] Integrate `crc32c` library into build system
  - [x] MSVC build system

ACKs for top commit:
  sipa:
    ACK 677fb8e

Tree-SHA512: 37ee92a750e053e924bc4626b12bb3fd81faa9f8c5ebaa343931fee810c45ba05aa6051fdea82535fa351bf2be7297801b98af9469865fc5ead771650a5d6240
@laanwj laanwj deleted the 2019_11_merge_upstream branch February 3, 2021 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update to upstream (1.22+)