diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-05-04 00:13:20 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-05-04 00:13:20 +0200 |
commit | 6de338a2d9904ef5a67552b024491700523074a3 (patch) | |
tree | 5d8807c0bedbd8a7feee1c5bb344bfb20745caaa /src/readahead/readahead-common.c | |
parent | 37099707e26ef2c6d215f6e7f17dd46bf6aad586 (diff) |
readhead: temporarily lower the kernel's read_ahead_kb setting while collecting
While collecting readahead data we want to know exactly what userspace
accesses unblurred by the kernel's read_ahead_kb. Hence lower this
during collection, and raise it afterwards.
This is mostly based on ideas and code by Auke Kok.
Diffstat (limited to 'src/readahead/readahead-common.c')
-rw-r--r-- | src/readahead/readahead-common.c | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/src/readahead/readahead-common.c b/src/readahead/readahead-common.c index 4e8e636975..99dbac2525 100644 --- a/src/readahead/readahead-common.c +++ b/src/readahead/readahead-common.c @@ -210,7 +210,7 @@ finish: #define BUMP_REQUEST_NR (16*1024) -int bump_request_nr(const char *p) { +int block_bump_request_nr(const char *p) { struct stat st; uint64_t u; char *ap = NULL, *line = NULL; @@ -267,3 +267,83 @@ finish: return r; } + +int block_get_readahead(const char *p, uint64_t *bytes) { + struct stat st; + char *ap = NULL, *line = NULL; + int r; + dev_t d; + uint64_t u; + + assert(p); + assert(bytes); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return 0; + + d = st.st_dev; + block_get_whole_disk(d, &d); + + if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) { + r = -ENOMEM; + goto finish; + } + + r = read_one_line_file(ap, &line); + if (r < 0) + goto finish; + + r = safe_atou64(line, &u); + if (r < 0) + goto finish; + + *bytes = u * 1024ULL; + +finish: + free(ap); + free(line); + + return r; +} + +int block_set_readahead(const char *p, uint64_t bytes) { + struct stat st; + char *ap = NULL, *line = NULL; + int r; + dev_t d; + + assert(p); + assert(bytes); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return 0; + + d = st.st_dev; + block_get_whole_disk(d, &d); + + if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) { + r = -ENOMEM; + goto finish; + } + + if (asprintf(&line, "%llu", (unsigned long long) bytes / 1024ULL) < 0) { + r = -ENOMEM; + goto finish; + } + + r = write_one_line_file(ap, line); + if (r < 0) + goto finish; + +finish: + free(ap); + free(line); + + return r; +} |