Commit 746f8906 authored by Lennart Poettering's avatar Lennart Poettering

readahead: add btrfs defrag support

parent 05115020
...@@ -101,4 +101,25 @@ static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t ma ...@@ -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); 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 #endif
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/fiemap.h> #include <linux/fiemap.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/vfs.h>
#include "missing.h" #include "missing.h"
#include "util.h" #include "util.h"
...@@ -47,15 +48,18 @@ ...@@ -47,15 +48,18 @@
#include "ioprio.h" #include "ioprio.h"
#include "readahead-common.h" #include "readahead-common.h"
/* #define MINCORE_VEC_SIZE (READAHEAD_FILE_SIZE_MAX/PAGE_SIZE)
fixme:
- 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; struct stat st;
void *start = MAP_FAILED; void *start = MAP_FAILED;
uint8_t vec[MINCORE_VEC_SIZE]; uint8_t vec[MINCORE_VEC_SIZE];
...@@ -78,6 +82,9 @@ static int pack_file(FILE *pack, const char *fn) { ...@@ -78,6 +82,9 @@ static int pack_file(FILE *pack, const char *fn) {
goto finish; goto finish;
} }
if (on_btrfs)
btrfs_defrag(fd);
l = PAGE_ALIGN(st.st_size); l = PAGE_ALIGN(st.st_size);
if ((start = mmap(NULL, l, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { if ((start = mmap(NULL, l, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
log_warning("mmap(%s) failed: %m", fn); log_warning("mmap(%s) failed: %m", fn);
...@@ -190,7 +197,8 @@ static int collect(const char *root) { ...@@ -190,7 +197,8 @@ static int collect(const char *root) {
sigset_t mask; sigset_t mask;
FILE *pack = NULL; FILE *pack = NULL;
char *pack_fn_new = NULL, *pack_fn = NULL; char *pack_fn_new = NULL, *pack_fn = NULL;
bool on_ssd; bool on_ssd, on_btrfs;
struct statfs sfs;
assert(root); assert(root);
...@@ -321,6 +329,9 @@ static int collect(const char *root) { ...@@ -321,6 +329,9 @@ static int collect(const char *root) {
on_ssd = fs_on_ssd(root); on_ssd = fs_on_ssd(root);
log_debug("On SSD: %s", yes_no(on_ssd)); 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, "%s/.readahead", root);
asprintf(&pack_fn_new, "%s/.readahead.new", root); asprintf(&pack_fn_new, "%s/.readahead.new", root);
...@@ -339,13 +350,13 @@ static int collect(const char *root) { ...@@ -339,13 +350,13 @@ static int collect(const char *root) {
fputs(CANONICAL_HOST "\n", pack); fputs(CANONICAL_HOST "\n", pack);
putc(on_ssd ? 'S' : 'R', 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 /* On SSD or on btrfs, just write things out in the
* files where accessed */ * order the files where accessed. */
HASHMAP_FOREACH_KEY(q, p, files, i) HASHMAP_FOREACH_KEY(q, p, files, i)
pack_file(pack, p); pack_file(pack, p, on_btrfs);
} else { } else {
struct item *ordered, *j; struct item *ordered, *j;
unsigned k, n; unsigned k, n;
...@@ -374,7 +385,7 @@ static int collect(const char *root) { ...@@ -374,7 +385,7 @@ static int collect(const char *root) {
qsort(ordered, n, sizeof(struct item), qsort_compare); qsort(ordered, n, sizeof(struct item), qsort_compare);
for (k = 0; k < n; k++) for (k = 0; k < n; k++)
pack_file(pack, ordered[k].path); pack_file(pack, ordered[k].path, on_btrfs);
free(ordered); free(ordered);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment