fileGuard.release();
}
} else {
- result->reset(new WinRandomAccessFile(
- fname, hFile, std::max(GetSectorSize(fname), page_size_), options));
+ result->reset(new WinRandomAccessFile(fname, hFile, page_size_, options));
fileGuard.release();
}
return s;
} else {
// Here we want the buffer allocation to be aligned by the SSD page size
// and to be a multiple of it
- result->reset(new WinWritableFile(
- fname, hFile, std::max(GetSectorSize(fname), GetPageSize()),
- c_BufferCapacity, local_options));
+ result->reset(new WinWritableFile(fname, hFile, GetPageSize(),
+ c_BufferCapacity, local_options));
}
return s;
}
}
UniqueCloseHandlePtr fileGuard(hFile, CloseHandleFunc);
- result->reset(new WinRandomRWFile(
- fname, hFile, std::max(GetSectorSize(fname), GetPageSize()), options));
+ result->reset(new WinRandomRWFile(fname, hFile, GetPageSize(), options));
fileGuard.release();
return s;
size_t WinFileSystem::GetSectorSize(const std::string& fname) {
size_t sector_size = kSectorSize;
- if (RX_PathIsRelative(RX_FN(fname).c_str())) {
- return sector_size;
- }
-
// obtain device handle
char devicename[7] = "\\\\.\\";
- int erresult = strncat_s(devicename, sizeof(devicename), fname.c_str(), 2);
+ int erresult = 0;
+ if (RX_PathIsRelative(RX_FN(fname).c_str())) {
+ RX_FILESTRING rx_current_dir;
+ rx_current_dir.resize(MAX_PATH);
+ DWORD len = RX_GetCurrentDirectory(MAX_PATH, &rx_current_dir[0]);
+ if (len == 0) {
+ return sector_size;
+ }
+ rx_current_dir.resize(len);
+ std::string current_dir = FN_TO_RX(rx_current_dir);
+ erresult =
+ strncat_s(devicename, sizeof(devicename), current_dir.c_str(), 2);
+ } else {
+ erresult = strncat_s(devicename, sizeof(devicename), fname.c_str(), 2);
+ }
if (erresult) {
assert(false);
#include "port/win/io_win.h"
+#include "env_win.h"
#include "monitoring/iostats_context_imp.h"
#include "test_util/sync_point.h"
#include "util/aligned_buffer.h"
return ((alignment) & (alignment - 1)) == 0;
}
-inline bool IsSectorAligned(const size_t off) {
- return (off & (kSectorSize - 1)) == 0;
-}
-
inline bool IsAligned(size_t alignment, const void* ptr) {
return ((uintptr_t(ptr)) & (alignment - 1)) == 0;
}
return 0;
}
+WinFileData::WinFileData(const std::string& filename, HANDLE hFile,
+ bool direct_io)
+ : filename_(filename),
+ hFile_(hFile),
+ use_direct_io_(direct_io),
+ sector_size_(WinFileSystem::GetSectorSize(filename)) {}
+
+bool WinFileData::IsSectorAligned(const size_t off) const {
+ return (off & (sector_size_ - 1)) == 0;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// WinMmapReadableFile
return IOStatus::NotSupported("This function is only used for direct_io");
}
- if (!IsSectorAligned(static_cast<size_t>(offset)) || !IsSectorAligned(n)) {
- return IOStatus::InvalidArgument(
- "WinSequentialFile::PositionedRead: offset is not properly aligned");
- }
+ assert(IsSectorAligned(static_cast<size_t>(offset)));
+ assert(IsSectorAligned(static_cast<size_t>(n)));
size_t bytes_read = 0; // out param
IOStatus s = PositionedReadInternal(scratch, static_cast<size_t>(n), offset,
inline WinRandomAccessImpl::WinRandomAccessImpl(WinFileData* file_base,
size_t alignment,
const FileOptions& options)
- : file_base_(file_base), alignment_(alignment) {
+ : file_base_(file_base),
+ alignment_(std::max(alignment, file_base->GetSectorSize())) {
assert(!options.use_mmap_reads);
}
char* scratch) const {
// Check buffer alignment
if (file_base_->use_direct_io()) {
- if (!IsSectorAligned(static_cast<size_t>(offset)) ||
- !IsAligned(alignment_, scratch)) {
- return IOStatus::InvalidArgument(
- "WinRandomAccessImpl::ReadImpl: offset or scratch is not properly "
- "aligned");
- }
+ assert(file_base_->IsSectorAligned(static_cast<size_t>(offset)));
+ assert(IsAligned(alignment_, scratch));
}
if (n == 0) {
inline WinWritableImpl::WinWritableImpl(WinFileData* file_data,
size_t alignment)
: file_data_(file_data),
- alignment_(alignment),
+ alignment_(std::max(alignment, file_data->GetSectorSize())),
next_write_offset_(0),
reservedsize_(0) {
// Query current position in case ReopenWritableFile is called
if (file_data_->use_direct_io()) {
// With no offset specified we are appending
// to the end of the file
- assert(IsSectorAligned(next_write_offset_));
- if (!IsSectorAligned(data.size()) ||
- !IsAligned(static_cast<size_t>(GetAlignement()), data.data())) {
- s = IOStatus::InvalidArgument(
- "WriteData must be page aligned, size must be sector aligned");
- } else {
- s = pwrite(file_data_, data, next_write_offset_, bytes_written);
- }
+ assert(file_data_->IsSectorAligned(next_write_offset_));
+ assert(file_data_->IsSectorAligned(data.size()));
+ assert(IsAligned(static_cast<size_t>(GetAlignment()), data.data()));
+ s = pwrite(file_data_, data, next_write_offset_, bytes_written);
} else {
DWORD bytesWritten = 0;
if (!WriteFile(file_data_->GetFileHandle(), data.data(),
inline IOStatus WinWritableImpl::PositionedAppendImpl(const Slice& data,
uint64_t offset) {
if (file_data_->use_direct_io()) {
- if (!IsSectorAligned(static_cast<size_t>(offset)) ||
- !IsSectorAligned(data.size()) ||
- !IsAligned(static_cast<size_t>(GetAlignement()), data.data())) {
- return IOStatus::InvalidArgument(
- "Data and offset must be page aligned, size must be sector aligned");
- }
+ assert(file_data_->IsSectorAligned(static_cast<size_t>(offset)));
+ assert(file_data_->IsSectorAligned(data.size()));
+ assert(IsAligned(static_cast<size_t>(GetAlignment()), data.data()));
}
size_t bytes_written = 0;
}
size_t WinWritableFile::GetRequiredBufferAlignment() const {
- return static_cast<size_t>(GetAlignement());
+ return static_cast<size_t>(GetAlignment());
}
IOStatus WinWritableFile::Append(const Slice& data,
}
size_t WinRandomRWFile::GetRequiredBufferAlignment() const {
- return static_cast<size_t>(GetAlignement());
+ assert(WinRandomAccessImpl::GetAlignment() ==
+ WinWritableImpl::GetAlignment());
+ return static_cast<size_t>(WinRandomAccessImpl::GetAlignment());
}
IOStatus WinRandomRWFile::Write(uint64_t offset, const Slice& data,
// will need to be aligned (not sure there is a guarantee that the buffer
// passed in is aligned).
const bool use_direct_io_;
+ const size_t sector_size_;
public:
// We want this class be usable both for inheritance (prive
// or protected) and for containment so __ctor and __dtor public
- WinFileData(const std::string& filename, HANDLE hFile, bool direct_io)
- : filename_(filename), hFile_(hFile), use_direct_io_(direct_io) {}
+ WinFileData(const std::string& filename, HANDLE hFile, bool direct_io);
virtual ~WinFileData() { this->CloseFile(); }
bool use_direct_io() const { return use_direct_io_; }
+ size_t GetSectorSize() const { return sector_size_; }
+
+ bool IsSectorAligned(const size_t off) const;
+
WinFileData(const WinFileData&) = delete;
WinFileData& operator=(const WinFileData&) = delete;
};
~WinWritableImpl() {}
- uint64_t GetAlignement() const { return alignment_; }
+ uint64_t GetAlignment() const { return alignment_; }
IOStatus AppendImpl(const Slice& data);