-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
There seem to be multiple ways to do readahead in Linux, and only some of them work. Hopefully reading the actual data is one of them. This is an attempt to avoid page-by-page reads in the generic dedupe code. We load both extents into the VFS cache (read sequentially) and hope they are still there by the time we call dedupe on them. We also call readahead(2) and hopefully that either helps or does nothing. Signed-off-by: Zygo Blaxell <[email protected]>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -371,6 +371,31 @@ bees_sync(int fd) | |
BEESCOUNTADD(sync_ms, sync_timer.age() * 1000); | ||
} | ||
|
||
void | ||
bees_readahead(int const fd, off_t offset, size_t size) | ||
{ | ||
Timer readahead_timer; | ||
BEESNOTE("readahead " << name_fd(fd) << " offset " << to_hex(offset) << " len " << pretty(size)); | ||
BEESTOOLONG("readahead " << name_fd(fd) << " offset " << to_hex(offset) << " len " << pretty(size)); | ||
// This might not do anything? | ||
DIE_IF_NON_ZERO(readahead(fd, offset, size)); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Zygo
Owner
|
||
// Make sure this data is in page cache | ||
// Note spelling: readahead vs read ahead | ||
BEESNOTE("read ahead " << name_fd(fd) << " offset " << to_hex(offset) << " len " << pretty(size)); | ||
while (size) { | ||
static uint8_t dummy[BEES_READAHEAD_SIZE]; | ||
size_t this_read_size = min(size, sizeof(dummy)); | ||
// Ignore errors and short reads. | ||
// It turns out our size parameter isn't all that accurate. | ||
pread(fd, dummy, this_read_size, offset); | ||
BEESCOUNT(readahead_count); | ||
BEESCOUNTADD(readahead_bytes, this_read_size); | ||
offset += this_read_size; | ||
size -= this_read_size; | ||
} | ||
BEESCOUNTADD(readahead_ms, readahead_timer.age() * 1000); | ||
} | ||
|
||
BeesStringFile::BeesStringFile(Fd dir_fd, string name, size_t limit) : | ||
m_dir_fd(dir_fd), | ||
m_name(name), | ||
|
readahead()
may ("may", because I didn't check the kernel lately) simply ignore offset and size, and just set a flag in the kernel FD to increase RA size from 64k to 128k for this file descriptor. Also, if size is below a page boundary, it will be rounded down, effectively making sub-page sizes into a no-op. The man pages about these functions seem generally wrong, a look at the kernel source reveals how these functions really work.