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

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Mon Jul 21 06:02:22 PDT 2014


On Mon, Jul 21, 2014 at 09:38:57AM +0300, Timofey Titovets wrote:
> Just completed TODO:
> * readahead: use BTRFS_IOC_DEFRAG_RANGE instead of BTRFS_IOC_DEFRAG

This is still not an explanation. What is the difference between the
two?

> 
> //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;
Please use static initalization as in:

 struct btrfs_ioctl_defrag_range_args range = {
       .start = 0,
       .len = -1,
       ...
  };

and the same for the other arg.

> 
> -        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);
You can skip the name change, we just have one function like that
anyway.

> 
>          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];
> +};
Try adding -E to the normal gcc options (you can use make V=1 to see them). This
will give you the proprocessed output.

Zbyszek


> +
>  #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