diff options
-rw-r--r-- | src/missing.h | 21 | ||||
-rw-r--r-- | src/readahead-collect.c | 35 |
2 files changed, 44 insertions, 12 deletions
diff --git a/src/missing.h b/src/missing.h index 539979e1bd..ff5dcb4092 100644 --- a/src/missing.h +++ b/src/missing.h @@ -101,4 +101,25 @@ static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t ma return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dfd, pathname); } +#ifndef BTRFS_IOCTL_MAGIC +#define BTRFS_IOCTL_MAGIC 0x94 +#endif + +#ifndef BTRFS_PATH_NAME_MAX +#define BTRFS_PATH_NAME_MAX 4087 +#endif + +struct btrfs_ioctl_vol_args { + int64_t fd; + char name[BTRFS_PATH_NAME_MAX + 1]; +}; + +#ifndef BTRFS_IOC_DEFRAG +#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_SUPER_MAGIC +#define BTRFS_SUPER_MAGIC 0x9123683E +#endif + #endif diff --git a/src/readahead-collect.c b/src/readahead-collect.c index 93a04521f3..5ff3711068 100644 --- a/src/readahead-collect.c +++ b/src/readahead-collect.c @@ -39,6 +39,7 @@ #include <linux/fs.h> #include <linux/fiemap.h> #include <sys/ioctl.h> +#include <sys/vfs.h> #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); @@ -321,6 +329,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 +350,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 +385,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); } |