X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Freadahead-collect.c;h=937231ca4282d46355b01b738c51c6cbccf896ef;hb=4030d7a923427a50745fc5786f4905aa703f0bcb;hp=93a04521f3fb82a7dd9d3385f36ff18fe14f1525;hpb=22be093ffb403a1c474037939ca9b88b1ee39f77;p=elogind.git diff --git a/src/readahead-collect.c b/src/readahead-collect.c index 93a04521f..937231ca4 100644 --- a/src/readahead-collect.c +++ b/src/readahead-collect.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "missing.h" #include "util.h" @@ -47,15 +48,18 @@ #include "ioprio.h" #include "readahead-common.h" -/* - fixme: +#define MINCORE_VEC_SIZE (READAHEAD_FILE_SIZE_MAX/PAGE_SIZE) - - BTRFS_IOC_DEFRAG -*/ +static int btrfs_defrag(int fd) { + struct btrfs_ioctl_vol_args data; -#define MINCORE_VEC_SIZE (READAHEAD_FILE_SIZE_MAX/PAGE_SIZE) + zero(data); + data.fd = fd; -static int pack_file(FILE *pack, const char *fn) { + return ioctl(fd, BTRFS_IOC_DEFRAG, &data); +} + +static int pack_file(FILE *pack, const char *fn, bool on_btrfs) { struct stat st; void *start = MAP_FAILED; uint8_t vec[MINCORE_VEC_SIZE]; @@ -78,6 +82,9 @@ static int pack_file(FILE *pack, const char *fn) { goto finish; } + if (on_btrfs) + btrfs_defrag(fd); + l = PAGE_ALIGN(st.st_size); if ((start = mmap(NULL, l, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { log_warning("mmap(%s) failed: %m", fn); @@ -190,7 +197,8 @@ static int collect(const char *root) { sigset_t mask; FILE *pack = NULL; char *pack_fn_new = NULL, *pack_fn = NULL; - bool on_ssd; + bool on_ssd, on_btrfs; + struct statfs sfs; assert(root); @@ -247,6 +255,9 @@ static int collect(const char *root) { ssize_t n; struct fanotify_event_metadata *m; + if (hashmap_size(files) > READAHEAD_FILES_MAX) + break; + if (poll(pollfd, _FD_MAX, -1) < 0) { if (errno == EINTR) @@ -308,7 +319,6 @@ static int collect(const char *root) { m = FAN_EVENT_NEXT(m, n); } - } if (fanotify_fd >= 0) { @@ -321,6 +331,9 @@ static int collect(const char *root) { on_ssd = fs_on_ssd(root); log_debug("On SSD: %s", yes_no(on_ssd)); + on_btrfs = statfs(root, &sfs) >= 0 && sfs.f_type == BTRFS_SUPER_MAGIC; + log_debug("On btrfs: %s", yes_no(on_btrfs)); + asprintf(&pack_fn, "%s/.readahead", root); asprintf(&pack_fn_new, "%s/.readahead.new", root); @@ -339,13 +352,13 @@ static int collect(const char *root) { fputs(CANONICAL_HOST "\n", pack); putc(on_ssd ? 'S' : 'R', pack); - if (on_ssd) { + if (on_ssd || on_btrfs) { - /* On SSD, just write things out in the order the - * files where accessed */ + /* On SSD or on btrfs, just write things out in the + * order the files where accessed. */ HASHMAP_FOREACH_KEY(q, p, files, i) - pack_file(pack, p); + pack_file(pack, p, on_btrfs); } else { struct item *ordered, *j; unsigned k, n; @@ -374,7 +387,7 @@ static int collect(const char *root) { qsort(ordered, n, sizeof(struct item), qsort_compare); for (k = 0; k < n; k++) - pack_file(pack, ordered[k].path); + pack_file(pack, ordered[k].path, on_btrfs); free(ordered); } @@ -424,13 +437,12 @@ finish: } int main(int argc, char *argv[]) { - /* log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); */ + + log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); log_parse_environment(); log_open(); - log_set_max_level(LOG_DEBUG); - - if (collect("/") < 0) + if (collect(argc >= 2 ? argv[1] : "/") < 0) return 1; return 0;