f2fs_io: add gc_urgent

e.g.,
f2fs_io gc_urgent dm-4 [start/end/run] [time in sec]

This controls sysfs/gc_urgent to run f2fs_gc urgently.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
diff --git a/tools/f2fs_io/f2fs_io.c b/tools/f2fs_io/f2fs_io.c
index 70fde6e..cb28ff8 100644
--- a/tools/f2fs_io/f2fs_io.c
+++ b/tools/f2fs_io/f2fs_io.c
@@ -359,6 +359,40 @@
 	exit(0);
 }
 
+#define gc_urgent_desc "start/end/run gc_urgent for given time period"
+#define gc_urgent_help					\
+"f2fs_io gc_urgent $dev [start/end/run] [time in sec]\n\n"\
+" - f2fs_io gc_urgent sda21 start\n"		\
+" - f2fs_io gc_urgent sda21 end\n"		\
+" - f2fs_io gc_urgent sda21 run 10\n"		\
+
+static void do_gc_urgent(int argc, char **argv, const struct cmd_desc *cmd)
+{
+	char command[255];
+
+	if (argc == 3 && !strcmp(argv[2], "start")) {
+		printf("gc_urgent: start on %s\n", argv[1]);
+		sprintf(command, "echo %d > %s/%s/gc_urgent", 1, "/sys/fs/f2fs/", argv[1]);
+		system(command);
+	} else if (argc == 3 && !strcmp(argv[2], "end")) {
+		printf("gc_urgent: end on %s\n", argv[1]);
+		sprintf(command, "echo %d > %s/%s/gc_urgent", 0, "/sys/fs/f2fs/", argv[1]);
+		system(command);
+	} else if (argc == 4 && !strcmp(argv[2], "run")) {
+		printf("gc_urgent: start on %s for %d secs\n", argv[1], atoi(argv[3]));
+		sprintf(command, "echo %d > %s/%s/gc_urgent", 1, "/sys/fs/f2fs/", argv[1]);
+		system(command);
+		sleep(atoi(argv[3]));
+		printf("gc_urgent: end on %s for %d secs\n", argv[1], atoi(argv[3]));
+		sprintf(command, "echo %d > %s/%s/gc_urgent", 0, "/sys/fs/f2fs/", argv[1]);
+		system(command);
+	} else {
+		fputs("Excess arguments\n\n", stderr);
+		fputs(cmd->cmd_help, stderr);
+		exit(1);
+	}
+}
+
 #define CMD_HIDDEN 	0x0001
 #define CMD(name) { #name, do_##name, name##_desc, name##_help, 0 }
 #define _CMD(name) { #name, do_##name, NULL, NULL, CMD_HIDDEN }
@@ -371,6 +405,7 @@
 	CMD(write),
 	CMD(read),
 	CMD(fiemap),
+	CMD(gc_urgent),
 	{ NULL, NULL, NULL, NULL, 0 }
 };