Message ID | 20200803094629.21898-2-Filip.Bozuta@syrmia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | linux-user: Adding support for a group of btrfs ioctls | expand |
Le 03/08/2020 à 11:46, Filip Bozuta a écrit : > This patch implements functionality of following ioctls: > > BTRFS_IOC_SUBVOL_CREATE - Creating a btrfs subvolume > > Create a btrfs subvolume. The subvolume is created using the ioctl's > third argument which represents a pointer to a following structure > type: > > struct btrfs_ioctl_vol_args { > __s64 fd; > char name[BTRFS_PATH_NAME_MAX + 1]; > }; > > Before calling this ioctl, the fields of this structure should be filled > with aproppriate values. The fd field represents the file descriptor > value of the subvolume and the name field represents the subvolume > path. > > BTRFS_IOC_SUBVOL_GETFLAGS - Getting subvolume flags > > Read the flags of the btrfs subvolume. The flags are read using > the ioctl's third argument that is a pointer of __u64 (unsigned long). > The third argument represents a bit mask that can be composed of following > values: > BTRFS_SUBVOL_RDONLY (1ULL << 1) > BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2) > BTRFS_DEVICE_SPEC_BY_ID (1ULL << 3) > BTRFS_SUBVOL_SPEC_BY_ID (1ULL << 4) > > BTRFS_IOC_SUBVOL_SETFLAGS - Setting subvolume flags > > Set the flags of the btrfs subvolume. The flags are set using the > ioctl's third argument that is a pointer of __u64 (unsigned long). > The third argument represents a bit mask that can be composed of same > values as in the case of previous ioctl (BTRFS_IOC_SUBVOL_GETFLAGS). > > BTRFS_IOC_SUBVOL_GETINFO - Getting subvolume information > > Read information about the subvolume. The subvolume information is > returned in the ioctl's third argument which represents a pointer to > a following structure type: > > struct btrfs_ioctl_get_subvol_info_args { > /* Id of this subvolume */ > __u64 treeid; > > /* Name of this subvolume, used to get the real name at mount point */ > char name[BTRFS_VOL_NAME_MAX + 1]; > > /* > * Id of the subvolume which contains this subvolume. > * Zero for top-level subvolume or a deleted subvolume. > */ > __u64 parent_id; > > /* > * Inode number of the directory which contains this subvolume. > * Zero for top-level subvolume or a deleted subvolume > */ > __u64 dirid; > > /* Latest transaction id of this subvolume */ > __u64 generation; > > /* Flags of this subvolume */ > __u64 flags; > > /* UUID of this subvolume */ > __u8 uuid[BTRFS_UUID_SIZE]; > > /* > * UUID of the subvolume of which this subvolume is a snapshot. > * All zero for a non-snapshot subvolume. > */ > __u8 parent_uuid[BTRFS_UUID_SIZE]; > > /* > * UUID of the subvolume from which this subvolume was received. > * All zero for non-received subvolume. > */ > __u8 received_uuid[BTRFS_UUID_SIZE]; > > /* Transaction id indicating when change/create/send/receive happened */ > __u64 ctransid; > __u64 otransid; > __u64 stransid; > __u64 rtransid; > /* Time corresponding to c/o/s/rtransid */ > struct btrfs_ioctl_timespec ctime; > struct btrfs_ioctl_timespec otime; > struct btrfs_ioctl_timespec stime; > struct btrfs_ioctl_timespec rtime; > > /* Must be zero */ > __u64 reserved[8]; > }; > > All of the fields of this structure are filled after the ioctl call. > > Implementation notes: > > Ioctls BTRFS_IOC_SUBVOL_CREATE and BTRFS_IOC_SUBVOL_GETINFO have structure > types as third arguments. That is the reason why a corresponding definition > are added in file 'linux-user/syscall_types.h'. > > The line '#include <linux/btrfs.h>' is added in file 'linux-user/syscall.c' to > recognise preprocessor definitions for these ioctls. Since the file "linux/btrfs.h" > was added in the kernel version 3.9, it is enwrapped in an #ifdef statement > with parameter CONFIG_BTRFS which is defined in 'configure' if the > header file is present. > > Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> > Reviewed-by: Laurent Vivier <laurent@vivier.eu> > --- > configure | 9 +++++++++ > linux-user/ioctls.h | 15 +++++++++++++++ > linux-user/syscall.c | 3 +++ > linux-user/syscall_defs.h | 8 ++++++++ > linux-user/syscall_types.h | 28 ++++++++++++++++++++++++++++ > 5 files changed, 63 insertions(+) > > diff --git a/configure b/configure > index b969dee675..8b3b214031 100755 > --- a/configure > +++ b/configure > @@ -4945,6 +4945,12 @@ if check_include sys/kcov.h ; then > kcov=yes > fi > > +# check for btrfs filesystem support (kernel must be 3.9+) > +btrfs=no > +if check_include linux/btrfs.h ; then > + btrfs=yes > +fi > + > # If we're making warnings fatal, apply this to Sphinx runs as well > sphinx_werror="" > if test "$werror" = "yes"; then > @@ -7057,6 +7063,9 @@ fi > if test "$kcov" = "yes" ; then > echo "CONFIG_KCOV=y" >> $config_host_mak > fi > +if test "$btrfs" = "yes" ; then > + echo "CONFIG_BTRFS=y" >> $config_host_mak > +fi > if test "$inotify" = "yes" ; then > echo "CONFIG_INOTIFY=y" >> $config_host_mak > fi > diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h > index 0defa1d8c1..544184ff95 100644 > --- a/linux-user/ioctls.h > +++ b/linux-user/ioctls.h > @@ -174,6 +174,21 @@ > IOCTL(FS_IOC32_GETVERSION, IOC_R, MK_PTR(TYPE_INT)) > IOCTL(FS_IOC32_SETVERSION, IOC_W, MK_PTR(TYPE_INT)) > > +#ifdef BTRFS_IOC_SUBVOL_CREATE > + IOCTL(BTRFS_IOC_SUBVOL_CREATE, IOC_W, > + MK_PTR(MK_STRUCT(STRUCT_btrfs_ioctl_vol_args))) > +#endif > +#ifdef BTRFS_IOC_SUBVOL_GETFLAGS > + IOCTL(BTRFS_IOC_SUBVOL_GETFLAGS, IOC_R, MK_PTR(TYPE_ULONGLONG)) > +#endif > +#ifdef BTRFS_IOC_SUBVOL_SETFLAGS > + IOCTL(BTRFS_IOC_SUBVOL_SETFLAGS, IOC_W, MK_PTR(TYPE_ULONGLONG)) > +#endif > +#ifdef BTRFS_IOC_GET_SUBVOL_INFO > + IOCTL(BTRFS_IOC_GET_SUBVOL_INFO, IOC_R, > + MK_PTR(MK_STRUCT(STRUCT_btrfs_ioctl_get_subvol_info_args))) > +#endif > + > #ifdef CONFIG_USBFS > /* USB ioctls */ > IOCTL(USBDEVFS_CONTROL, IOC_RW, > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 05f03919ff..4a65b28999 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -112,6 +112,9 @@ > #include <linux/if_alg.h> > #include <linux/rtc.h> > #include <sound/asound.h> > +#ifdef CONFIG_BTRFS > +#include <linux/btrfs.h> > +#endif > #include "linux_loop.h" > #include "uname.h" > > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h > index 152ec637cb..67a3c110b6 100644 > --- a/linux-user/syscall_defs.h > +++ b/linux-user/syscall_defs.h > @@ -967,6 +967,14 @@ struct target_rtc_pll_info { > #define TARGET_FS_IOC32_GETVERSION TARGET_IOR('v', 1, int) > #define TARGET_FS_IOC32_SETVERSION TARGET_IOW('v', 2, int) > > +/* btrfs ioctls */ > +#define TARGET_BTRFS_IOC_SUBVOL_CREATE TARGET_IOWU(BTRFS_IOCTL_MAGIC, 14) > +#define TARGET_BTRFS_IOC_SUBVOL_GETFLAGS TARGET_IOR(BTRFS_IOCTL_MAGIC, 25,\ > + abi_ullong) > +#define TARGET_BTRFS_IOC_SUBVOL_SETFLAGS TARGET_IOW(BTRFS_IOCTL_MAGIC, 26,\ > + abi_ullong) > +#define TARGET_BTRFS_IOC_GET_SUBVOL_INFO TARGET_IORU(BTRFS_IOCTL_MAGIC, 60) > + > /* usb ioctls */ > #define TARGET_USBDEVFS_CONTROL TARGET_IOWRU('U', 0) > #define TARGET_USBDEVFS_BULK TARGET_IOWRU('U', 2) > diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h > index 4e12c1661e..75ce6482ea 100644 > --- a/linux-user/syscall_types.h > +++ b/linux-user/syscall_types.h > @@ -321,6 +321,34 @@ STRUCT(blkpg_partition, > MK_ARRAY(TYPE_CHAR, BLKPG_DEVNAMELTH), /* devname */ > MK_ARRAY(TYPE_CHAR, BLKPG_VOLNAMELTH)) /* volname */ > > +STRUCT(btrfs_ioctl_vol_args, > + TYPE_LONGLONG, /* fd */ > + MK_ARRAY(TYPE_CHAR, BTRFS_PATH_NAME_MAX + 1)) /* name */ > + > +STRUCT(btrfs_ioctl_timespec, > + TYPE_ULONGLONG, /* sec */ > + TYPE_INT) /* nsec */ > + > +STRUCT(btrfs_ioctl_get_subvol_info_args, > + TYPE_ULONGLONG, /* treeid */ > + MK_ARRAY(TYPE_CHAR, BTRFS_VOL_NAME_MAX + 1), > + TYPE_ULONGLONG, /* parentid */ > + TYPE_ULONGLONG, /* dirid */ > + TYPE_ULONGLONG, /* generation */ > + TYPE_ULONGLONG, /* flags */ > + MK_ARRAY(TYPE_CHAR, BTRFS_UUID_SIZE), /* uuid */ > + MK_ARRAY(TYPE_CHAR, BTRFS_UUID_SIZE), /* parent_uuid */ > + MK_ARRAY(TYPE_CHAR, BTRFS_UUID_SIZE), /* received_uuid */ > + TYPE_ULONGLONG, /* ctransid */ > + TYPE_ULONGLONG, /* otransid */ > + TYPE_ULONGLONG, /* stransid */ > + TYPE_ULONGLONG, /* rtransid */ > + MK_STRUCT(STRUCT_btrfs_ioctl_timespec), /* ctime */ > + MK_STRUCT(STRUCT_btrfs_ioctl_timespec), /* otime */ > + MK_STRUCT(STRUCT_btrfs_ioctl_timespec), /* stime */ > + MK_STRUCT(STRUCT_btrfs_ioctl_timespec), /* rtime */ > + MK_ARRAY(TYPE_ULONGLONG, 8)) /* reserved */ > + > STRUCT(rtc_time, > TYPE_INT, /* tm_sec */ > TYPE_INT, /* tm_min */ > Applied to my linux-user-for-5.2 branch. Thanks, Laurent
diff --git a/configure b/configure index b969dee675..8b3b214031 100755 --- a/configure +++ b/configure @@ -4945,6 +4945,12 @@ if check_include sys/kcov.h ; then kcov=yes fi +# check for btrfs filesystem support (kernel must be 3.9+) +btrfs=no +if check_include linux/btrfs.h ; then + btrfs=yes +fi + # If we're making warnings fatal, apply this to Sphinx runs as well sphinx_werror="" if test "$werror" = "yes"; then @@ -7057,6 +7063,9 @@ fi if test "$kcov" = "yes" ; then echo "CONFIG_KCOV=y" >> $config_host_mak fi +if test "$btrfs" = "yes" ; then + echo "CONFIG_BTRFS=y" >> $config_host_mak +fi if test "$inotify" = "yes" ; then echo "CONFIG_INOTIFY=y" >> $config_host_mak fi diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 0defa1d8c1..544184ff95 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -174,6 +174,21 @@ IOCTL(FS_IOC32_GETVERSION, IOC_R, MK_PTR(TYPE_INT)) IOCTL(FS_IOC32_SETVERSION, IOC_W, MK_PTR(TYPE_INT)) +#ifdef BTRFS_IOC_SUBVOL_CREATE + IOCTL(BTRFS_IOC_SUBVOL_CREATE, IOC_W, + MK_PTR(MK_STRUCT(STRUCT_btrfs_ioctl_vol_args))) +#endif +#ifdef BTRFS_IOC_SUBVOL_GETFLAGS + IOCTL(BTRFS_IOC_SUBVOL_GETFLAGS, IOC_R, MK_PTR(TYPE_ULONGLONG)) +#endif +#ifdef BTRFS_IOC_SUBVOL_SETFLAGS + IOCTL(BTRFS_IOC_SUBVOL_SETFLAGS, IOC_W, MK_PTR(TYPE_ULONGLONG)) +#endif +#ifdef BTRFS_IOC_GET_SUBVOL_INFO + IOCTL(BTRFS_IOC_GET_SUBVOL_INFO, IOC_R, + MK_PTR(MK_STRUCT(STRUCT_btrfs_ioctl_get_subvol_info_args))) +#endif + #ifdef CONFIG_USBFS /* USB ioctls */ IOCTL(USBDEVFS_CONTROL, IOC_RW, diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 05f03919ff..4a65b28999 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -112,6 +112,9 @@ #include <linux/if_alg.h> #include <linux/rtc.h> #include <sound/asound.h> +#ifdef CONFIG_BTRFS +#include <linux/btrfs.h> +#endif #include "linux_loop.h" #include "uname.h" diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 152ec637cb..67a3c110b6 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -967,6 +967,14 @@ struct target_rtc_pll_info { #define TARGET_FS_IOC32_GETVERSION TARGET_IOR('v', 1, int) #define TARGET_FS_IOC32_SETVERSION TARGET_IOW('v', 2, int) +/* btrfs ioctls */ +#define TARGET_BTRFS_IOC_SUBVOL_CREATE TARGET_IOWU(BTRFS_IOCTL_MAGIC, 14) +#define TARGET_BTRFS_IOC_SUBVOL_GETFLAGS TARGET_IOR(BTRFS_IOCTL_MAGIC, 25,\ + abi_ullong) +#define TARGET_BTRFS_IOC_SUBVOL_SETFLAGS TARGET_IOW(BTRFS_IOCTL_MAGIC, 26,\ + abi_ullong) +#define TARGET_BTRFS_IOC_GET_SUBVOL_INFO TARGET_IORU(BTRFS_IOCTL_MAGIC, 60) + /* usb ioctls */ #define TARGET_USBDEVFS_CONTROL TARGET_IOWRU('U', 0) #define TARGET_USBDEVFS_BULK TARGET_IOWRU('U', 2) diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 4e12c1661e..75ce6482ea 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -321,6 +321,34 @@ STRUCT(blkpg_partition, MK_ARRAY(TYPE_CHAR, BLKPG_DEVNAMELTH), /* devname */ MK_ARRAY(TYPE_CHAR, BLKPG_VOLNAMELTH)) /* volname */ +STRUCT(btrfs_ioctl_vol_args, + TYPE_LONGLONG, /* fd */ + MK_ARRAY(TYPE_CHAR, BTRFS_PATH_NAME_MAX + 1)) /* name */ + +STRUCT(btrfs_ioctl_timespec, + TYPE_ULONGLONG, /* sec */ + TYPE_INT) /* nsec */ + +STRUCT(btrfs_ioctl_get_subvol_info_args, + TYPE_ULONGLONG, /* treeid */ + MK_ARRAY(TYPE_CHAR, BTRFS_VOL_NAME_MAX + 1), + TYPE_ULONGLONG, /* parentid */ + TYPE_ULONGLONG, /* dirid */ + TYPE_ULONGLONG, /* generation */ + TYPE_ULONGLONG, /* flags */ + MK_ARRAY(TYPE_CHAR, BTRFS_UUID_SIZE), /* uuid */ + MK_ARRAY(TYPE_CHAR, BTRFS_UUID_SIZE), /* parent_uuid */ + MK_ARRAY(TYPE_CHAR, BTRFS_UUID_SIZE), /* received_uuid */ + TYPE_ULONGLONG, /* ctransid */ + TYPE_ULONGLONG, /* otransid */ + TYPE_ULONGLONG, /* stransid */ + TYPE_ULONGLONG, /* rtransid */ + MK_STRUCT(STRUCT_btrfs_ioctl_timespec), /* ctime */ + MK_STRUCT(STRUCT_btrfs_ioctl_timespec), /* otime */ + MK_STRUCT(STRUCT_btrfs_ioctl_timespec), /* stime */ + MK_STRUCT(STRUCT_btrfs_ioctl_timespec), /* rtime */ + MK_ARRAY(TYPE_ULONGLONG, 8)) /* reserved */ + STRUCT(rtc_time, TYPE_INT, /* tm_sec */ TYPE_INT, /* tm_min */