[systemd-devel] [PATCH v2] readahead: use BTRFS_IOC_DEFRAG_RANGE

Timofey Titovets nefelim4ag at gmail.com
Sun Jul 20 23:38:57 PDT 2014


Just completed TODO:
* readahead: use BTRFS_IOC_DEFRAG_RANGE instead of BTRFS_IOC_DEFRAG

//i save BTRFS_IOC_DEFRAG as fallback, because BTRFS_IOC_DEFRAG_RANGE 
not working (as i know) on several old kernels

v1 -> v2
Fixed spelling in TODO

----
  TODO                              |  1 -
  src/readahead/readahead-collect.c | 22 +++++++++++++++++-----
  src/shared/missing.h              | 18 ++++++++++++++++++
  3 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/TODO b/TODO
index bfa06de..636d25f 100644
--- a/TODO
+++ b/TODO
@@ -570,7 +570,6 @@ Features:
  * readahead:
    - drop /.readahead on bigger upgrades with yum
    - move readahead files into /var (look for them with .path units?)
-  - readahead: use BTRFS_IOC_DEFRAG_RANGE instead of BTRFS_IOC_DEFRAG 
ioctl, with START_IO
    - readahead: when bumping /sys readahead variable save mtime and 
compare later to detect changes
    - readahead: make use of EXT4_IOC_MOVE_EXT, as used by 
http://e4rat.sourceforge.net/

diff --git a/src/readahead/readahead-collect.c 
b/src/readahead/readahead-collect.c
index c1afd0d..7cec5c4 100644
--- a/src/readahead/readahead-collect.c
+++ b/src/readahead/readahead-collect.c
@@ -78,12 +78,24 @@ static usec_t starttime;
  #define SECTOR_TO_PTR(s) ULONG_TO_PTR((s)+1)
  #define PTR_TO_SECTOR(p) (PTR_TO_ULONG(p)-1)

-static int btrfs_defrag(int fd) {
-        struct btrfs_ioctl_vol_args data = { .fd = fd };
+static int btrfs_defrag_hybrid(int fd){
+        int ret;
+        struct btrfs_ioctl_defrag_range_args range;
+        struct btrfs_ioctl_vol_args fallback;
+        range.start = 0;
+        range.len = (uint64_t)-1;
+        range.flags = 2;
+        range.extent_thresh = 1;

-        return ioctl(fd, BTRFS_IOC_DEFRAG, &data);
-}
+        fallback.fd=fd;
+
+        ret = ioctl(fd, BTRFS_IOC_DEFRAG_RANGE, &range);

+        if (ret < 0)
+              return ioctl(fd, BTRFS_IOC_DEFRAG, &fallback);
+
+        return ret;
+}
  static int pack_file(FILE *pack, const char *fn, bool on_btrfs) {
          struct stat st;
          void *start = MAP_FAILED;
@@ -118,7 +130,7 @@ static int pack_file(FILE *pack, const char *fn, 
bool on_btrfs) {
          }

          if (on_btrfs)
-                btrfs_defrag(fd);
+                btrfs_defrag_hybrid(fd);

          l = PAGE_ALIGN(st.st_size);
          start = mmap(NULL, l, PROT_READ, MAP_SHARED, fd, 0);
diff --git a/src/shared/missing.h b/src/shared/missing.h
index 818d704..29cf80e 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -186,6 +186,19 @@ static inline int fanotify_mark(int fanotify_fd, 
unsigned int flags, uint64_t ma
  #define BTRFS_UUID_SIZE 16
  #endif

+/* TODO: Fix: won't compile if
+ * btrfs_ioctl_defrag_range_args
+ * included in ifdef HAVE_LINUX_BTRFS_H
+ */
+struct btrfs_ioctl_defrag_range_args {
+        uint64_t start;         /* start byte = 0 */
+        uint64_t len;           /* whole file uint64_t-1 */
+        uint64_t flags;         /* start_io 2 */
+        uint32_t extent_thresh; /* 0 */
+        uint32_t compress_type;
+        uint32_t unused[4];
+};
+
  #ifndef HAVE_LINUX_BTRFS_H
  struct btrfs_ioctl_vol_args {
          int64_t fd;
@@ -213,6 +226,11 @@ struct btrfs_ioctl_fs_info_args {
  #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct 
btrfs_ioctl_vol_args)
  #endif

+#ifndef BTRFS_IOC_DEFRAG_RANGE
+#define BTRFS_IOC_DEFRAG_RANGE _IOW(BTRFS_IOCTL_MAGIC, 16, \
+                                           struct 
btrfs_ioctl_defrag_range_args)
+#endif
+
  #ifndef BTRFS_IOC_DEV_INFO
  #define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \
                                   struct btrfs_ioctl_dev_info_args)


More information about the systemd-devel mailing list