Skip to content

Commit 840fad9

Browse files
committed
Change PosixWritableFile Truncate to reseek to new end of file (facebook#14088)
Summary: Change PosixWritableFile's Truncate to the new end offset. This ensures that future appends are written with no holes or overwrites. RocksDB doesn't guarantee this in the FileSystem contract, and its left up to the specific implementation. Pull Request resolved: facebook#14088 Reviewed By: cbi42 Differential Revision: D85786398 Pulled By: anand1976 fbshipit-source-id: 3520d9d6336362f5128a17bbf396297d821a5da3
1 parent 2db3301 commit 840fad9

4 files changed

Lines changed: 49 additions & 2 deletions

File tree

env/io_posix.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,7 @@ IOStatus PosixWritableFile::Truncate(uint64_t size, const IOOptions& /*opts*/,
14061406
filename_, errno);
14071407
} else {
14081408
filesize_ = size;
1409+
lseek(fd_, filesize_, SEEK_SET);
14091410
}
14101411
return s;
14111412
}

env/io_posix_test.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// (found in the LICENSE.Apache file in the root directory).
55

66
#include "test_util/testharness.h"
7+
#include "util/random.h"
78

89
#ifdef ROCKSDB_LIB_IO_POSIX
910
#include "env/io_posix.h"
@@ -131,6 +132,48 @@ TEST_F(LogicalBlockSizeCacheTest, Ref) {
131132
}
132133
#endif
133134

135+
class PosixWritableFileTest : public testing::Test {};
136+
137+
TEST_F(PosixWritableFileTest, SeekAfterTruncate) {
138+
std::shared_ptr<FileSystem> fs = FileSystem::Default();
139+
std::string path =
140+
test::PerThreadDBPath("PosixWritableFileTest_SeekAfterTruncate");
141+
Random rnd(300);
142+
std::unique_ptr<FSWritableFile> wfile;
143+
144+
ASSERT_OK(fs->NewWritableFile(path, FileOptions(), &wfile, nullptr));
145+
ASSERT_OK(wfile->Append(rnd.RandomString(16384), IOOptions(), nullptr));
146+
ASSERT_OK(wfile->Truncate(4096, IOOptions(), nullptr));
147+
ASSERT_OK(wfile->Append(rnd.RandomString(4096), IOOptions(), nullptr));
148+
ASSERT_OK(wfile->Close(IOOptions(), nullptr));
149+
wfile.reset();
150+
151+
uint64_t size = 0;
152+
ASSERT_OK(fs->GetFileSize(path, IOOptions(), &size, nullptr));
153+
ASSERT_EQ(size, 8192);
154+
ASSERT_OK(fs->DeleteFile(path, IOOptions(), nullptr));
155+
}
156+
157+
TEST_F(PosixWritableFileTest, SeekAfterExtend) {
158+
std::shared_ptr<FileSystem> fs = FileSystem::Default();
159+
std::string path =
160+
test::PerThreadDBPath("PosixWritableFileTest_SeekAfterTruncate");
161+
Random rnd(300);
162+
std::unique_ptr<FSWritableFile> wfile;
163+
164+
ASSERT_OK(fs->NewWritableFile(path, FileOptions(), &wfile, nullptr));
165+
ASSERT_OK(wfile->Append(rnd.RandomString(4096), IOOptions(), nullptr));
166+
ASSERT_OK(wfile->Truncate(8192, IOOptions(), nullptr));
167+
ASSERT_OK(wfile->Append(rnd.RandomString(8192), IOOptions(), nullptr));
168+
ASSERT_OK(wfile->Close(IOOptions(), nullptr));
169+
wfile.reset();
170+
171+
uint64_t size = 0;
172+
ASSERT_OK(fs->GetFileSize(path, IOOptions(), &size, nullptr));
173+
ASSERT_EQ(size, 16384);
174+
ASSERT_OK(fs->DeleteFile(path, IOOptions(), nullptr));
175+
}
176+
134177
} // namespace ROCKSDB_NAMESPACE
135178
#endif
136179

include/rocksdb/file_system.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,8 +1166,10 @@ class FSWritableFile {
11661166

11671167
// Truncate is necessary to trim the file to the correct size
11681168
// before closing. It is not always possible to keep track of the file
1169-
// size due to whole pages writes. The behavior is undefined if called
1170-
// with other writes to follow.
1169+
// size due to whole pages writes. If called with other writes to follow,
1170+
// the behavior is file system specific. Posix will reseek to the new EOF.
1171+
// Other file systems may behave differently. Its the caller's
1172+
// responsibility to check the file system contract.
11711173
virtual IOStatus Truncate(uint64_t /*size*/, const IOOptions& /*options*/,
11721174
IODebugContext* /*dbg*/) {
11731175
return IOStatus::OK();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PosixWritableFile now repositions the seek pointer to the new end of file after a call to Truncate.

0 commit comments

Comments
 (0)