/*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#include "folly/io/RecordIO.h"
+#include <folly/io/RecordIO.h>
#include <sys/types.h>
-#include <unistd.h>
-#include "folly/Exception.h"
-#include "folly/FileUtil.h"
-#include "folly/Memory.h"
-#include "folly/ScopeGuard.h"
-#include "folly/String.h"
+#include <folly/Exception.h>
+#include <folly/FileUtil.h>
+#include <folly/Memory.h>
+#include <folly/Portability.h>
+#include <folly/ScopeGuard.h>
+#include <folly/String.h>
+#include <folly/portability/Unistd.h>
namespace folly {
}
DCHECK_EQ(buf->computeChainDataLength(), totalLength);
- auto iov = buf->getIov();
// We're going to write. Reserve space for ourselves.
off_t pos = filePos_.fetch_add(totalLength);
+
+#if FOLLY_HAVE_PWRITEV
+ auto iov = buf->getIov();
ssize_t bytes = pwritevFull(file_.fd(), iov.data(), iov.size(), pos);
+#else
+ buf->unshare();
+ buf->coalesce();
+ ssize_t bytes = pwriteFull(file_.fd(), buf->data(), buf->length(), pos);
+#endif
+
checkUnixError(bytes, "pwrite() failed");
DCHECK_EQ(bytes, totalLength);
}
: range_(range),
fileId_(fileId),
recordAndPos_(ByteRange(), 0) {
- if (pos >= range_.size()) {
+ if (size_t(pos) >= range_.size()) {
+ // Note that this branch can execute if pos is negative as well.
recordAndPos_.second = off_t(-1);
range_.clear();
} else {
RecordInfo validateRecord(ByteRange range, uint32_t fileId) {
if (range.size() <= headerSize()) { // records may not be empty
- return {0};
+ return {0, {}};
}
const Header* header = reinterpret_cast<const Header*>(range.begin());
range.advance(sizeof(Header));
header->flags != 0 ||
(fileId != 0 && header->fileId != fileId) ||
header->dataLength > range.size()) {
- return {0};
+ return {0, {}};
}
if (headerHash(*header) != header->headerHash) {
- return {0};
+ return {0, {}};
}
range.reset(range.begin(), header->dataLength);
if (dataHash(range) != header->dataHash) {
- return {0};
+ return {0, {}};
}
return {header->fileId, range};
}
static const uint32_t magic = Header::kMagic;
static const ByteRange magicRange(reinterpret_cast<const uint8_t*>(&magic),
sizeof(magic));
- static constexpr size_t headerTail = sizeof(Header) - sizeof(magic);
DCHECK_GE(searchRange.begin(), wholeRange.begin());
DCHECK_LE(searchRange.end(), wholeRange.end());
start += sizeof(magic);
}
- return {0};
+ return {0, {}};
}
} // namespace