Skip to content

Commit

Permalink
fs: implement cache invalidation
Browse files Browse the repository at this point in the history
Implement cache invalidation - we do support non-direct reads
so tell the page cache to drop all data that the extents
map to.

Signed-off-by: Hans Holmberg <hans.holmberg@wdc.com>
  • Loading branch information
yhr committed Jan 25, 2023
1 parent 604a3a9 commit b04ca0c
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 4 deletions.
32 changes: 32 additions & 0 deletions fs/io_zenfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,38 @@ ZoneExtent* ZoneFile::GetExtent(uint64_t file_offset, uint64_t* dev_offset) {
return NULL;
}

IOStatus ZoneFile::InvalidateCache(uint64_t pos, uint64_t size) {
ReadLock lck(this);
uint64_t offset = pos;
uint64_t left = size;
IOStatus s = IOStatus::OK();

if (left == 0) {
left = GetFileSize();
}

while (left) {
uint64_t dev_offset;
ZoneExtent* extent = GetExtent(offset, &dev_offset);

if (!extent) {
s = IOStatus::IOError("Extent not found while invalidating cache");
break;
}

uint64_t extent_end = extent->start_ + extent->length_;
uint64_t invalidate_size = std::min(left, extent_end - dev_offset);

s = zbd_->InvalidateCache(dev_offset, invalidate_size);
if (!s.ok()) break;

left -= invalidate_size;
offset += invalidate_size;
}

return s;
}

IOStatus ZoneFile::PositionedRead(uint64_t offset, size_t n, Slice* result,
char* scratch, bool direct) {
ZenFSMetricsLatencyGuard guard(zbd_->GetMetrics(), ZENFS_READ_LATENCY,
Expand Down
10 changes: 6 additions & 4 deletions fs/io_zenfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ class ZoneFile {
uint32_t GetNrLinks() { return linkfiles_.size(); }
const std::vector<std::string>& GetLinkFiles() const { return linkfiles_; }

IOStatus InvalidateCache(uint64_t pos, uint64_t size);

private:
void ReleaseActiveZone();
void SetActiveZone(Zone* zone);
Expand Down Expand Up @@ -282,8 +284,8 @@ class ZonedSequentialFile : public FSSequentialFile {
return zoneFile_->GetBlockSize();
}

IOStatus InvalidateCache(size_t /*offset*/, size_t /*length*/) override {
return IOStatus::OK();
IOStatus InvalidateCache(size_t offset, size_t length) override {
return zoneFile_->InvalidateCache(offset, length);
}
};

Expand Down Expand Up @@ -314,8 +316,8 @@ class ZonedRandomAccessFile : public FSRandomAccessFile {
return zoneFile_->GetBlockSize();
}

IOStatus InvalidateCache(size_t /*offset*/, size_t /*length*/) override {
return IOStatus::OK();
IOStatus InvalidateCache(size_t offset, size_t length) override {
return zoneFile_->InvalidateCache(offset, length);
}
};

Expand Down
9 changes: 9 additions & 0 deletions fs/zbd_zenfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,15 @@ IOStatus ZonedBlockDevice::AllocateEmptyZone(Zone **zone_out) {
return IOStatus::OK();
}

IOStatus ZonedBlockDevice::InvalidateCache(uint64_t pos, uint64_t size) {
int ret = zbd_be_->InvalidateCache(pos, size);

if (ret) {
return IOStatus::IOError("Failed to invalidate cache");
}
return IOStatus::OK();
}

int ZonedBlockDevice::Read(char *buf, uint64_t offset, int n, bool direct) {
int ret = 0;
int left = n;
Expand Down
2 changes: 2 additions & 0 deletions fs/zbd_zenfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class ZonedBlockDeviceBackend {
virtual IOStatus Close(uint64_t start) = 0;
virtual int Read(char *buf, int size, uint64_t pos, bool direct) = 0;
virtual int Write(char *data, uint32_t size, uint64_t pos) = 0;
virtual int InvalidateCache(uint64_t pos, uint64_t size) = 0;
virtual bool ZoneIsSwr(std::unique_ptr<ZoneList> &zones,
unsigned int idx) = 0;
virtual bool ZoneIsOffline(std::unique_ptr<ZoneList> &zones,
Expand Down Expand Up @@ -215,6 +216,7 @@ class ZonedBlockDevice {
void GetZoneSnapshot(std::vector<ZoneSnapshot> &snapshot);

int Read(char *buf, uint64_t offset, int n, bool direct);
IOStatus InvalidateCache(uint64_t pos, uint64_t size);

IOStatus ReleaseMigrateZone(Zone *zone);

Expand Down
4 changes: 4 additions & 0 deletions fs/zbdlib_zenfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ IOStatus ZbdlibBackend::Close(uint64_t start) {
return IOStatus::OK();
}

int ZbdlibBackend::InvalidateCache(uint64_t pos, uint64_t size) {
return posix_fadvise(read_f_, pos, size, POSIX_FADV_DONTNEED);
}

int ZbdlibBackend::Read(char *buf, int size, uint64_t pos, bool direct) {
return pread(direct ? read_direct_f_ : read_f_, buf, size, pos);
}
Expand Down
1 change: 1 addition & 0 deletions fs/zbdlib_zenfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ZbdlibBackend : public ZonedBlockDeviceBackend {
IOStatus Close(uint64_t start);
int Read(char *buf, int size, uint64_t pos, bool direct);
int Write(char *data, uint32_t size, uint64_t pos);
int InvalidateCache(uint64_t pos, uint64_t size);

bool ZoneIsSwr(std::unique_ptr<ZoneList> &zones, unsigned int idx) {
struct zbd_zone *z = &((struct zbd_zone *)zones->GetData())[idx];
Expand Down
9 changes: 9 additions & 0 deletions fs/zonefs_zenfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,15 @@ IOStatus ZoneFsBackend::Close(uint64_t start) {
return IOStatus::OK();
}

int ZoneFsBackend::InvalidateCache(uint64_t pos, uint64_t size) {
uint64_t offset = LBAToZoneOffset(pos);

std::shared_ptr<ZoneFsFile> file = GetZoneFile(pos, O_RDONLY);
if (file == nullptr) return -EINVAL;

return posix_fadvise(file->GetFd(), offset, size, POSIX_FADV_DONTNEED);
}

int ZoneFsBackend::Read(char *buf, int size, uint64_t pos, bool direct) {
int flags = direct ? O_RDONLY | O_DIRECT : O_RDONLY;
uint64_t offset = LBAToZoneOffset(pos);
Expand Down
2 changes: 2 additions & 0 deletions fs/zonefs_zenfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class ZoneFsBackend : public ZonedBlockDeviceBackend {
IOStatus Close(uint64_t start);
int Read(char *buf, int size, uint64_t pos, bool direct);
int Write(char *data, uint32_t size, uint64_t pos);
int InvalidateCache(uint64_t pos, uint64_t size);

bool ZoneIsSwr(std::unique_ptr<ZoneList> &zones, unsigned int idx);
bool ZoneIsOffline(std::unique_ptr<ZoneList> &zones, unsigned int idx);
bool ZoneIsWritable(std::unique_ptr<ZoneList> &zones, unsigned int idx);
Expand Down

0 comments on commit b04ca0c

Please sign in to comment.