Skip to content

Commit

Permalink
Add error checking when using ftell
Browse files Browse the repository at this point in the history
Summary:
For no good reason, DiskFile has been using ftell without any error checking. This hasn't been a problem, but we should be more careful.
This also removes the last dependency on errno, as DiskFileChunk now returns an unambiguous error status in all cases.

Reviewed By: jtbraun

Differential Revision: D57580321

fbshipit-source-id: f5e9a5c4522b83e688c7dbf89acb5ee3a0b5a102
  • Loading branch information
Georges Berenger authored and facebook-github-bot committed May 21, 2024
1 parent 0d101b5 commit 29380c9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
34 changes: 24 additions & 10 deletions vrs/DiskFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ void DiskFile::forgetFurtherChunks(int64_t fileSize) {
}

int DiskFile::skipForward(int64_t offset) {
int64_t chunkPos = currentChunk_->tell();
int64_t chunkPos{};
if ((lastError_ = currentChunk_->tell(chunkPos)) != 0) {
return lastError_;
}
if (chunkPos + offset < currentChunk_->getSize()) {
lastError_ = currentChunk_->seek(offset, SEEK_CUR);
return lastError_;
Expand Down Expand Up @@ -262,7 +265,11 @@ int DiskFile::overwrite(const void* buffer, size_t length) {
do {
size_t requestSize = (length > lastRWSize_) ? length - lastRWSize_ : 0;
if (!isLastChunk()) {
int64_t maxRequest = max<int64_t>(currentChunk_->getSize() - currentChunk_->tell(), 0);
int64_t pos{};
if ((lastError_ = currentChunk_->tell(pos)) != 0) {
return lastError_;
}
int64_t maxRequest = max<int64_t>(currentChunk_->getSize() - pos, 0);
requestSize = min<size_t>(requestSize, static_cast<size_t>(maxRequest));
}
size_t writtenSize{};
Expand All @@ -283,9 +290,9 @@ int DiskFile::truncate() {
lastError_ = DISKFILE_READ_ONLY;
return lastError_;
}
int64_t chunkSize = currentChunk_->tell();
lastError_ = currentChunk_->truncate(chunkSize);
if (lastError_ == 0) {
int64_t chunkSize{};
if ((lastError_ = currentChunk_->tell(chunkSize)) == 0 &&
(lastError_ = currentChunk_->truncate(chunkSize)) == 0) {
// update the following chunks' offset
size_t chunkIndex = static_cast<size_t>(currentChunk_ - chunks_.data());
int64_t nextChunkOffset = currentChunk_->getOffset() + currentChunk_->getSize();
Expand Down Expand Up @@ -372,9 +379,12 @@ int DiskFile::addChunk(const string& chunkFilePath) {
filesOpenCount_++;
int64_t chunkOffset = 0;
if (currentChunk_ != nullptr && currentChunk_->isOpened()) {
currentChunk_->setSize(currentChunk_->tell());
lastError_ = currentChunk_->flush();
if (lastError_ != 0 || currentChunk_->getSize() < 0) {
int64_t pos{};
if ((lastError_ = currentChunk_->tell(pos)) != 0) {
return lastError_;
}
currentChunk_->setSize(pos);
if ((lastError_ = currentChunk_->flush()) != 0) {
// We're s***d: the last chunk is messed up, no point in trying to use the new one
newChunk.close();
os::remove(chunkFilePath);
Expand All @@ -400,11 +410,15 @@ int DiskFile::addChunk(const string& chunkFilePath) {
}

int64_t DiskFile::getPos() const {
return currentChunk_->getOffset() + currentChunk_->tell();
int64_t pos{};
IF_ERROR_LOG(currentChunk_->tell(pos));
return currentChunk_->getOffset() + pos;
}

int64_t DiskFile::getChunkPos() const {
return currentChunk_->tell();
int64_t pos{};
IF_ERROR_LOG(currentChunk_->tell(pos));
return pos;
}

int DiskFile::getChunkRange(int64_t& outChunkOffset, int64_t& outChunkSize) const {
Expand Down
5 changes: 3 additions & 2 deletions vrs/DiskFileChunk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ class DiskFileChunk {
int flush() {
return ::fflush(file_) != 0 ? errno : SUCCESS;
}
int64_t tell() const {
return os::fileTell(file_);
int tell(int64_t& outFilepos) const {
outFilepos = os::fileTell(file_);
return outFilepos < 0 ? errno : SUCCESS;
}
int seek(int64_t pos, int origin) {
return os::fileSeek(file_, pos, origin) != 0 ? errno : SUCCESS;
Expand Down

0 comments on commit 29380c9

Please sign in to comment.