[PATCH 1/2] Btrfs-progs: Add support for hot data ioctls

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ben Chociej <bchociej@xxxxxxxxx>

Add support for the new hot data functionality in-kernel. Three ioctls
were added to export hot data statistics and turn hot data tracking on
and off per inode. This patch enables btrfsctl to interact with those
ioctls.

Signed-off-by: Ben Chociej <bchociej@xxxxxxxxx>
Signed-off-by: Matt Lupfer <mlupfer@xxxxxxxxx>
Tested-by: Conor Scott <conscott@xxxxxx>
---
 btrfsctl.c   |  107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ioctl-test.c |    3 ++
 ioctl.h      |   24 +++++++++++++
 3 files changed, 134 insertions(+), 0 deletions(-)

diff --git a/btrfsctl.c b/btrfsctl.c
index be6bf25..8617d06 100644
--- a/btrfsctl.c
+++ b/btrfsctl.c
@@ -48,6 +48,7 @@ static void print_usage(void)
 {
 	printf("usage: btrfsctl [ -d file|dir] [ -s snap_name subvol|tree ]\n");
 	printf("                [-r size] [-A device] [-a] [-c] [-D dir .]\n");
+	printf("                [-t file] [-T file] [-h filename [0-2]]\n");
 	printf("\t-d filename: defragments one file\n");
 	printf("\t-d directory: defragments the entire Btree\n");
 	printf("\t-s snap_name dir: creates a new snapshot of dir\n");
@@ -57,6 +58,14 @@ static void print_usage(void)
 	printf("\t-a: scans all devices for Btrfs filesystems\n");
 	printf("\t-c: forces a single FS sync\n");
 	printf("\t-D: delete snapshot\n");
+	printf("\t-t filename: dump indexed heat information for a file\n");
+	printf("\t-T filename: dump live heat informaton for a file\n");
+	printf("\t-h filename: query heat tracking/migration status\n");
+	printf("\t-h filename level: set heat tracking level:\n");
+	printf("\t\tlevel =\n");
+	printf("\t\t0: no tracking or relocation\n");
+	printf("\t\t1: access tracking only\n");
+	printf("\t\t2: tracking and automatic migration to SSD\n");
 	printf("\t-m [tree id] directory: set the default mounted subvolume"
 	       " to the [tree id] or the directory\n");
 	printf("%s\n", BTRFS_BUILD_VERSION);
@@ -99,12 +108,14 @@ int main(int ac, char **av)
 	int fd;
 	int ret;
 	struct btrfs_ioctl_vol_args args;
+	struct btrfs_ioctl_heat_info hotinfo;
 	char *name = NULL;
 	int i;
 	unsigned long command = 0;
 	int len;
 	char *fullpath;
 	u64 objectid = 0;
+	int heatarg;
 
 	if (ac == 2 && strcmp(av[1], "-a") == 0) {
 		fprintf(stderr, "Scanning for Btrfs filesystems\n");
@@ -205,6 +216,38 @@ int main(int ac, char **av)
 					exit(1);
 				}
 			}
+		} else if (strcmp(av[i], "-t") == 0) {
+			if (i >= ac - 1) {
+				fprintf(stderr,
+					"-t requires a file argument\n");
+				print_usage();
+			}
+			hotinfo.live = 0;
+			command = BTRFS_IOC_GET_HEAT_INFO;
+		} else if (strcmp(av[i], "-T") == 0) {
+			if (i >= ac - 1) {
+				fprintf(stderr,
+					"-T requires a file argument\n");
+				print_usage();
+			}
+			hotinfo.live = 1;
+			command = BTRFS_IOC_GET_HEAT_INFO;
+		} else if (strcmp(av[i], "-h") == 0) {
+			if (i == ac - 2) {
+				command = BTRFS_IOC_GET_HEAT_OPTS;
+			} else if (i == ac - 3) {
+				command = BTRFS_IOC_SET_HEAT_OPTS;
+				heatarg = atoi(av[i + 2]);
+			} else {
+				fprintf(stderr, "-h invalid number of "
+					"arguments\n");
+				print_usage();
+				exit(1);
+			}
+
+			fprintf(stderr, "Btrfs hot data tracking: `%s'\n\n",
+				av[i + 1]);
+			av[i + 2] = av[i + 1];
 		}
 	}
 	if (command == 0) {
@@ -236,6 +279,70 @@ int main(int ac, char **av)
 	} else if (command == BTRFS_IOC_DEFAULT_SUBVOL) {
 		printf("objectid is %llu\n", objectid);
 		ret = ioctl(fd, command, &objectid);
+	} else if (command == BTRFS_IOC_GET_HEAT_INFO) {
+		strcpy(hotinfo.filename, fname);
+		ret = ioctl(fd, command, &hotinfo);
+		if (ret == 0) {
+			printf("Btrfs file hotness information\n");
+			printf("%s\n\n", hotinfo.filename);
+			printf("Last write: %llu\n",
+				(u64) hotinfo.last_write_time);
+			printf("Last read: %llu\n",
+				(u64) hotinfo.last_read_time);
+			printf("Average write delta: %llu\n",
+				(u64) hotinfo.avg_delta_writes);
+			printf("Average read delta: %llu\n",
+				(u64) hotinfo.avg_delta_reads);
+			printf("Number of writes: %u\n",
+				(u32) hotinfo.num_writes);
+			printf("Number of reads: %u\n\n",
+				(u32) hotinfo.num_reads);
+			if (hotinfo.live > 0)
+				printf("Temperature (live): %u\n\n",
+					hotinfo.temperature);
+			else
+				printf("Temperature (indexed): %u\n\n",
+					hotinfo.temperature);
+		}
+	} else if (command == BTRFS_IOC_SET_HEAT_OPTS) {
+		ret = ioctl(fd, command, &heatarg);
+		switch (heatarg) {
+		case 0:
+			printf("Turning OFF heat tracking and migration inode "
+				"flags.\n");
+			break;
+		case 1:
+			printf("Turning ON the heat tracking inode flag.\n");
+			printf("Turning OFF the migration inode flag.\n");
+			break;
+		case 2:
+			printf("Turning ON heat tracking and migration inode "
+				"flags.\n");
+			break;
+		default:
+			printf("Invalid heat tracking argument.\n");
+		}
+		printf("(Inode flags can be overridden by mount options)\n\n");
+	} else if (command == BTRFS_IOC_GET_HEAT_OPTS) {
+		ret = ioctl(fd, command, &heatarg);
+		switch (heatarg) {
+		case 0:
+			printf("Heat tracking and migration inode flags are "
+				"OFF.\n");
+			break;
+		case 1:
+			printf("Heat tracking inode flag is ON, migration "
+				"inode flag is OFF.\n");
+			break;
+		case 2:
+			printf("Heat tracking and migration inode flags are "
+				"both ON.\n");
+			break;
+		default:
+			printf("Wrong filesystem type, or invalid status "
+				"returned.\n");
+		}
+		printf("(Inode flags can be overridden by mount options)\n\n");
 	} else
 		ret = ioctl(fd, command, &args);
 	if (ret < 0) {
diff --git a/ioctl-test.c b/ioctl-test.c
index 7cf3bc2..8d54301 100644
--- a/ioctl-test.c
+++ b/ioctl-test.c
@@ -22,6 +22,9 @@ unsigned long ioctls[] = {
 	BTRFS_IOC_INO_LOOKUP,
 	BTRFS_IOC_DEFAULT_SUBVOL,
 	BTRFS_IOC_SPACE_INFO,
+	BTRFS_IOC_GET_HEAT_INFO,
+	BTRFS_IOC_SET_HEAT_OPTS,
+	BTRFS_IOC_GET_HEAT_OPTS,
 	0 };
 
 int main(int ac, char **av)
diff --git a/ioctl.h b/ioctl.h
index 776d7a9..5827338 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -132,6 +132,18 @@ struct btrfs_ioctl_space_args {
 	struct btrfs_ioctl_space_info spaces[0];
 };
 
+struct btrfs_ioctl_heat_info {
+	__u64 avg_delta_reads;
+	__u64 avg_delta_writes;
+	__u64 last_read_time;
+	__u64 last_write_time;
+	__u32 num_reads;
+	__u32 num_writes;
+	char filename[BTRFS_PATH_NAME_MAX + 1];
+	int temperature;
+	__u8 live;
+};
+
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -169,4 +181,16 @@ struct btrfs_ioctl_space_args {
 #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
 #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
 				    struct btrfs_ioctl_space_args)
+
+/*
+ * Hot data tracking ioctls:
+ *
+ * GET_HEAT_INFO - retrieve frequency of access info on a file
+ * SET_HEAT_OPTS - set whether a file is tracked/migratable
+ * GET_HEAT_OPTS - check whether a file is tracked/migratable
+ */
+#define BTRFS_IOC_GET_HEAT_INFO _IOWR(BTRFS_IOCTL_MAGIC, 21, \
+				struct btrfs_ioctl_heat_info)
+#define BTRFS_IOC_SET_HEAT_OPTS _IOW(BTRFS_IOCTL_MAGIC, 22, int)
+#define BTRFS_IOC_GET_HEAT_OPTS _IOR(BTRFS_IOCTL_MAGIC, 23, int)
 #endif
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux