mbox series

[0/3] Two furhter additions for fsinfo ioctl

Message ID 20200710140511.30343-1-johannes.thumshirn@wdc.com (mailing list archive)
Headers show
Series Two furhter additions for fsinfo ioctl | expand

Message

Johannes Thumshirn July 10, 2020, 2:05 p.m. UTC
This series extents the fsinfo ioctl by adding two new often requested
members, the filesystem generation and the metadata UUID. Both can be
retrieved from the kernel by setting the appropriate flag in the ioctl
structure.

The last patch adds a compile time assertion on the structure sizes, so we're
not accidentally breaking size assumptions.

The series was tested using the following test tool, strace support will be
written once the kernel side is accepted.

--- 8< ---
#include <linux/types.h>
#include <linux/btrfs.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

struct btrfs_ioctl_fs_info_args_new {
	__u64 max_id;                           /* out */
	__u64 num_devices;                      /* out */
	__u8 fsid[BTRFS_FSID_SIZE];             /* out */
	__u32 nodesize;                         /* out */
	__u32 sectorsize;                       /* out */
	__u32 clone_alignment;                  /* out */
	__u32 flags;                            /* out */
	__u16 csum_type;
	__u16 csum_size;
	__u32 generation;
	__u8 metadata_uuid[BTRFS_FSID_SIZE];
	__u8 reserved[952];                    /* pad to 1k */
};

#define BTRFS_FS_INFO_FLAG_CSUM_TYPE_SIZE	(1 << 0)
#define BTRFS_FS_INFO_FLAG_GENERATION		(1 << 1)
#define BTRFS_FS_INFO_FLAG_METADATA_UUID	(1 << 2)


static const char hex_chars[16] = "0123456789abcdef";
# define BYTE_HEX_CHARS(b_) \
	hex_chars[((uint8_t) (b_)) >> 4], hex_chars[((uint8_t) (b_)) & 0xf]

void format_uuid(const unsigned char *uuid, char *buf) 
{                                                                                                                                                                                    
	const char str[] = {                                                                                                                                                         
		BYTE_HEX_CHARS(uuid[0]),                                                                                                                                             
		BYTE_HEX_CHARS(uuid[1]),                                                                                                                                             
		BYTE_HEX_CHARS(uuid[2]),                                                                                                                                             
		BYTE_HEX_CHARS(uuid[3]),                                                                                                                                             
		'-',                                                                                                                                                                 
		BYTE_HEX_CHARS(uuid[4]),                                                                                                                                             
		BYTE_HEX_CHARS(uuid[5]),                                                                                                                                             
		'-',                                                                                                                                                                 
		BYTE_HEX_CHARS(uuid[6]),                                                                                                                                             
		BYTE_HEX_CHARS(uuid[7]),                                                                                                                                             
		'-',                                                                                                                                                                 
		BYTE_HEX_CHARS(uuid[8]),                                                                                                                                             
		BYTE_HEX_CHARS(uuid[9]),                                                                                                                                             
		'-',                                                                                                                                                                 
		BYTE_HEX_CHARS(uuid[10]),                                                                                                                                            
		BYTE_HEX_CHARS(uuid[11]),                                                                                                                                            
		BYTE_HEX_CHARS(uuid[12]),                                                                                                                                            
		BYTE_HEX_CHARS(uuid[13]),                                                                                                                                            
		BYTE_HEX_CHARS(uuid[14]),                                                                                                                                            
		BYTE_HEX_CHARS(uuid[15]),                                                                                                                                            
		'\0'                                                                                                                                                                 
	};                                                                                                                                                                           

	sprintf(buf, "%s", str);
}                                                      

int call_ioctl(int fd, bool csum, bool gen, bool meta)
{
	struct btrfs_ioctl_fs_info_args_new args = { 0 };
	char fsid[37], meta_uuid[37];
	int ret;

	if (csum)
		args.flags |= BTRFS_FS_INFO_FLAG_CSUM_TYPE_SIZE;
	if (gen)
		args.flags |= BTRFS_FS_INFO_FLAG_GENERATION;
	if (meta)
		args.flags |= BTRFS_FS_INFO_FLAG_METADATA_UUID;

	ret = ioctl(fd, BTRFS_IOC_FS_INFO, &args);
	if (ret < 0) {
		perror("ioctl");
		return ret;
	}

	format_uuid(args.fsid, fsid);
	format_uuid(args.metadata_uuid, meta_uuid);

	printf("\tfsid: %s\n", fsid);
	printf("\tmax_id: %llu\n", args.max_id);
	printf("\tnum_devices: %llu\n", args.num_devices);
	printf("\tnodesize: %u\n", args.nodesize);
	printf("\tsectorsize: %u\n", args.sectorsize);
	printf("\tclone_alignment: %u\n", args.clone_alignment);
	printf("\tflags: 0x%x\n", args.flags);
	if (args.flags & BTRFS_FS_INFO_FLAG_CSUM_TYPE_SIZE) {
		printf("\tcsum_type: %u\n", args.csum_type);
		printf("\tcsum_size: %u\n", args.csum_size);
	}
	if (args.flags & BTRFS_FS_INFO_FLAG_GENERATION)
		printf("\tgeneration: %u\n", args.generation);
	if (args.flags & BTRFS_FS_INFO_FLAG_METADATA_UUID)
		printf("\tmetadata UUID: %s\n", meta_uuid);

	return 0;
}

int main(int argc, char **argv)
{
	int fd, ret;

	if (argc != 2) {
		printf("Usage: %s file\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	fd = open(argv[1], O_RDWR);
	if (fd == -1) {
		perror("open");
		exit(1);
	}

	printf("%s: (old)\n", argv[1]);
	ret = call_ioctl(fd, false, false, false);
	if (ret)
		goto close_fd;

	printf("%s: (new)\n", argv[1]);
	ret = call_ioctl(fd, true, true, true);

close_fd:
	close(fd);
	exit(EXIT_SUCCESS);
}
--- >8 ---

Johannes Thumshirn (3):
  btrfs: add filesystem generation to fsinfo ioctl
  btrfs: add metadata_uuid to fsinfo ioctl
  btrfs: assert sizes of ioctl structures

 fs/btrfs/ioctl.c           | 11 +++++++++++
 include/uapi/linux/btrfs.h | 19 +++++++++++++++++--
 2 files changed, 28 insertions(+), 2 deletions(-)

Comments

Josef Bacik July 10, 2020, 2:24 p.m. UTC | #1
On 7/10/20 10:05 AM, Johannes Thumshirn wrote:
> This series extents the fsinfo ioctl by adding two new often requested
> members, the filesystem generation and the metadata UUID. Both can be
> retrieved from the kernel by setting the appropriate flag in the ioctl
> structure.
> 
> The last patch adds a compile time assertion on the structure sizes, so we're
> not accidentally breaking size assumptions.
> 
> The series was tested using the following test tool, strace support will be
> written once the kernel side is accepted.
> 

Applies and builds on misc-next as of this morning, looks fine to me, you can 
add the following to the whole series

Reviewed-by: Josef Bacik <josef@toxicpanda.com>

Thanks,

Josef