[libvirt] [PATCH 0/2] Adding reflink support for XFS and others.

This serie add XFS library to use the macro for reflink (clone). This is the case where BTRFS is not available but XFS is. In case of both is unavailable, the code will use FICLONE from filesystem library if it is defined. This implementation is similar to copy command. If you run a copy and trace the syscalls, you will see that ioctl uses BTRFS_IOC_CLONE or FICLONE to create a reflink. Julio Faracco (2): configure: Adding XFS library/headers check. storage: Rename btrfsCloneFile to support other filesystems. configure.ac | 7 +++++++ src/storage/storage_util.c | 20 ++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) -- 2.17.1

This commit checks for xfs.h library to use XFS_IOC_CLONE which is defined into that library file. So, after that it is possible to use thie macro to create reflinks. Signed-off-by: Julio Faracco <jcfaracco@gmail.com> --- configure.ac | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/configure.ac b/configure.ac index 59d2d09611..a87ca06854 100644 --- a/configure.ac +++ b/configure.ac @@ -625,6 +625,13 @@ if test "$with_linux" = "yes"; then AC_CHECK_HEADERS([linux/btrfs.h]) fi +dnl +dnl check for xfs dev headers required by xfs ioctl +dnl +if test "$with_linux" = "yes"; then + AC_CHECK_HEADERS([xfs/xfs.h]) +fi + dnl dnl check for DEVLINK_CMD_ESWITCH_GET dnl -- 2.17.1

This commit renames and adds other macros to support aother filesystems when a reflink is performed. After that, XFS filesystems (and others) with reflink support will be able to clone. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1565004 Signed-off-by: Julio Faracco <jcfaracco@gmail.com> --- src/storage/storage_util.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index a701a75702..fd1239c6cb 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -36,6 +36,9 @@ # ifndef FS_NOCOW_FL # define FS_NOCOW_FL 0x00800000 /* Do not cow file */ # endif +# ifdef FICLONE +# define REFLINK_IOC_CLONE FICLONE +# endif #endif #if WITH_BLKID @@ -48,6 +51,10 @@ #if HAVE_LINUX_BTRFS_H # include <linux/btrfs.h> +# define REFLINK_IOC_CLONE BTRFS_IOC_CLONE +#elif HAVE_XFS_XFS_H +# include <xfs/xfs.h> +# define REFLINK_IOC_CLONE XFS_IOC_CLONE #endif #include "datatypes.h" @@ -80,22 +87,23 @@ VIR_LOG_INIT("storage.storage_util"); * Perform the O(1) btrfs clone operation, if possible. * Upon success, return 0. Otherwise, return -1 and set errno. */ -#if HAVE_LINUX_BTRFS_H +#ifdef REFLINK_IOC_CLONE static inline int -btrfsCloneFile(int dest_fd, int src_fd) +reflinkCloneFile(int dest_fd, int src_fd) { - return ioctl(dest_fd, BTRFS_IOC_CLONE, src_fd); + return ioctl(dest_fd, REFLINK_IOC_CLONE, src_fd); } #else static inline int -btrfsCloneFile(int dest_fd ATTRIBUTE_UNUSED, - int src_fd ATTRIBUTE_UNUSED) +reflinkCloneFile(int dest_fd ATTRIBUTE_UNUSED, + int src_fd ATTRIBUTE_UNUSED) { errno = ENOTSUP; return -1; } #endif + static int ATTRIBUTE_NONNULL(2) virStorageBackendCopyToFD(virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, @@ -142,7 +150,7 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol, } if (reflink_copy) { - if (btrfsCloneFile(fd, inputfd) < 0) { + if (reflinkCloneFile(fd, inputfd) < 0) { ret = -errno; virReportSystemError(errno, _("failed to clone files from '%s'"), -- 2.17.1

On 07/06/2018 03:43 PM, Julio Faracco wrote:
This commit renames and adds other macros to support aother filesystems when a reflink is performed. After that, XFS filesystems (and others) with reflink support will be able to clone.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1565004
Signed-off-by: Julio Faracco <jcfaracco@gmail.com> --- src/storage/storage_util.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index a701a75702..fd1239c6cb 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -36,6 +36,9 @@ # ifndef FS_NOCOW_FL # define FS_NOCOW_FL 0x00800000 /* Do not cow file */ # endif +# ifdef FICLONE +# define REFLINK_IOC_CLONE FICLONE +# endif #endif
#if WITH_BLKID @@ -48,6 +51,10 @@
#if HAVE_LINUX_BTRFS_H # include <linux/btrfs.h> +# define REFLINK_IOC_CLONE BTRFS_IOC_CLONE +#elif HAVE_XFS_XFS_H +# include <xfs/xfs.h> +# define REFLINK_IOC_CLONE XFS_IOC_CLONE #endif
Problem is, REFLING_IOC_CLONE is defined already at this point (by hunk above) so this redefines the macro. Fixed by squashing this in: diff --git i/src/storage/storage_util.c w/src/storage/storage_util.c index fd1239c6cb..da99043e0a 100644 --- i/src/storage/storage_util.c +++ w/src/storage/storage_util.c @@ -36,9 +36,6 @@ # ifndef FS_NOCOW_FL # define FS_NOCOW_FL 0x00800000 /* Do not cow file */ # endif -# ifdef FICLONE -# define REFLINK_IOC_CLONE FICLONE -# endif #endif #if WITH_BLKID @@ -55,6 +52,8 @@ #elif HAVE_XFS_XFS_H # include <xfs/xfs.h> # define REFLINK_IOC_CLONE XFS_IOC_CLONE +#elif defined(FICLONE) +# define REFLINK_IOC_CLONE FICLONE #endif #include "datatypes.h" Michal

On Fri, Jul 06, 2018 at 16:57:17 +0200, Michal Privoznik wrote:
On 07/06/2018 03:43 PM, Julio Faracco wrote:
This commit renames and adds other macros to support aother filesystems when a reflink is performed. After that, XFS filesystems (and others) with reflink support will be able to clone.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1565004
Signed-off-by: Julio Faracco <jcfaracco@gmail.com> --- src/storage/storage_util.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index a701a75702..fd1239c6cb 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -36,6 +36,9 @@ # ifndef FS_NOCOW_FL # define FS_NOCOW_FL 0x00800000 /* Do not cow file */ # endif +# ifdef FICLONE +# define REFLINK_IOC_CLONE FICLONE +# endif #endif
#if WITH_BLKID @@ -48,6 +51,10 @@
#if HAVE_LINUX_BTRFS_H # include <linux/btrfs.h> +# define REFLINK_IOC_CLONE BTRFS_IOC_CLONE +#elif HAVE_XFS_XFS_H +# include <xfs/xfs.h> +# define REFLINK_IOC_CLONE XFS_IOC_CLONE #endif
Problem is, REFLING_IOC_CLONE is defined already at this point (by hunk above) so this redefines the macro.
Fixed by squashing this in:
diff --git i/src/storage/storage_util.c w/src/storage/storage_util.c index fd1239c6cb..da99043e0a 100644 --- i/src/storage/storage_util.c +++ w/src/storage/storage_util.c @@ -36,9 +36,6 @@ # ifndef FS_NOCOW_FL # define FS_NOCOW_FL 0x00800000 /* Do not cow file */ # endif -# ifdef FICLONE -# define REFLINK_IOC_CLONE FICLONE -# endif #endif
#if WITH_BLKID @@ -55,6 +52,8 @@ #elif HAVE_XFS_XFS_H # include <xfs/xfs.h> # define REFLINK_IOC_CLONE XFS_IOC_CLONE +#elif defined(FICLONE) +# define REFLINK_IOC_CLONE FICLONE
While it fortunately does not matter functionally as: /usr/include/linux/fs.h:#define FICLONE _IOW(0x94, 9, int) /usr/include/xfs/xfs_fs.h:#define XFS_IOC_CLONE _IOW (0x94, 9, int) /usr/include/linux/btrfs.h:#define BTRFS_IOCTL_MAGIC 0x94 /usr/include/linux/btrfs.h:#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int) I think the logic should be the other way around and use the most-generic definition first. This is just plain confusing for readers e.g. if you have both headers for XFS and BTRFS. For linux users it does not matter if any of the others are defined as the FICLONE should always be defined.
#endif
#include "datatypes.h"
Michal
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On 07/09/2018 08:57 AM, Peter Krempa wrote:
On Fri, Jul 06, 2018 at 16:57:17 +0200, Michal Privoznik wrote:
On 07/06/2018 03:43 PM, Julio Faracco wrote:
This commit renames and adds other macros to support aother filesystems when a reflink is performed. After that, XFS filesystems (and others) with reflink support will be able to clone.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1565004
Signed-off-by: Julio Faracco <jcfaracco@gmail.com> --- src/storage/storage_util.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index a701a75702..fd1239c6cb 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -36,6 +36,9 @@ # ifndef FS_NOCOW_FL # define FS_NOCOW_FL 0x00800000 /* Do not cow file */ # endif +# ifdef FICLONE +# define REFLINK_IOC_CLONE FICLONE +# endif #endif
#if WITH_BLKID @@ -48,6 +51,10 @@
#if HAVE_LINUX_BTRFS_H # include <linux/btrfs.h> +# define REFLINK_IOC_CLONE BTRFS_IOC_CLONE +#elif HAVE_XFS_XFS_H +# include <xfs/xfs.h> +# define REFLINK_IOC_CLONE XFS_IOC_CLONE #endif
Problem is, REFLING_IOC_CLONE is defined already at this point (by hunk above) so this redefines the macro.
Fixed by squashing this in:
diff --git i/src/storage/storage_util.c w/src/storage/storage_util.c index fd1239c6cb..da99043e0a 100644 --- i/src/storage/storage_util.c +++ w/src/storage/storage_util.c @@ -36,9 +36,6 @@ # ifndef FS_NOCOW_FL # define FS_NOCOW_FL 0x00800000 /* Do not cow file */ # endif -# ifdef FICLONE -# define REFLINK_IOC_CLONE FICLONE -# endif #endif
#if WITH_BLKID @@ -55,6 +52,8 @@ #elif HAVE_XFS_XFS_H # include <xfs/xfs.h> # define REFLINK_IOC_CLONE XFS_IOC_CLONE +#elif defined(FICLONE) +# define REFLINK_IOC_CLONE FICLONE
While it fortunately does not matter functionally as:
/usr/include/linux/fs.h:#define FICLONE _IOW(0x94, 9, int)
/usr/include/xfs/xfs_fs.h:#define XFS_IOC_CLONE _IOW (0x94, 9, int)
/usr/include/linux/btrfs.h:#define BTRFS_IOCTL_MAGIC 0x94 /usr/include/linux/btrfs.h:#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int)
Huh. So why are filesystems providing their own symbol? Just to confuse users?
I think the logic should be the other way around and use the most-generic definition first. This is just plain confusing for readers e.g. if you have both headers for XFS and BTRFS. For linux users it does not matter if any of the others are defined as the FICLONE should always be defined.
Okay. I'll post a patch for that. Michal

On 07/06/2018 03:42 PM, Julio Faracco wrote:
This serie add XFS library to use the macro for reflink (clone). This is the case where BTRFS is not available but XFS is. In case of both is unavailable, the code will use FICLONE from filesystem library if it is defined. This implementation is similar to copy command. If you run a copy and trace the syscalls, you will see that ioctl uses BTRFS_IOC_CLONE or FICLONE to create a reflink.
Julio Faracco (2): configure: Adding XFS library/headers check. storage: Rename btrfsCloneFile to support other filesystems.
configure.ac | 7 +++++++ src/storage/storage_util.c | 20 ++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-)
ACKed and pushed. Michal
participants (4)
-
Julio Faracco
-
Michal Privoznik
-
Michal Prívozník
-
Peter Krempa