--- /dev/null
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE 600
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <error.h>
+
+int trace_fd = -1;
+int marker_fd = -1;
+
+#define MAX_PATH 256
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
+#define MARKER(str) write(marker_fd, str, strlen(str));
+
+static const char *find_debugfs(void)
+{
+ static char debugfs[MAX_PATH+1];
+ static int debugfs_found;
+ char type[100];
+ FILE *fp;
+
+ if (debugfs_found)
+ return debugfs;
+
+ if ((fp = fopen("/proc/mounts","r")) == NULL)
+ return NULL;
+
+ while (fscanf(fp, "%*s %"
+ STR(MAX_PATH)
+ "s %99s %*s %*d %*d\n",
+ debugfs, type) == 2) {
+ if (strcmp(type, "debugfs") == 0)
+ break;
+ }
+ fclose(fp);
+
+ if (strcmp(type, "debugfs") != 0)
+ return NULL;
+
+ debugfs_found = 1;
+
+ return debugfs;
+}
+
+void init_ftrace()
+{
+ const char *debugfs;
+ char path[256], pid[10];
+ int pid_fd;
+
+ debugfs = find_debugfs();
+ if (debugfs) {
+ strcpy(path, debugfs);
+ strcat(path,"/tracing/trace_marker");
+ marker_fd = open(path, O_WRONLY);
+
+ strcpy(path, debugfs);
+ strcat(path,"/tracing/set_ftrace_pid");
+ pid_fd = open(path, O_WRONLY);
+ sprintf(pid, "%d", getpid());
+ if (pid_fd >= 0)
+ write(pid_fd, pid, strlen(pid));
+
+ strcpy(path, debugfs);
+ strcat(path,"/tracing/tracing_on");
+ trace_fd = open(path, O_WRONLY);
+ if (trace_fd >= 0)
+ write(trace_fd, "1", 1);
+ }
+}
+
+int main()
+{
+ int fd, ret;
+ char *buf;
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+
+ buf = memalign(pagesize, pagesize);
+ if (!buf)
+ error(1, errno, "memalign");
+
+ init_ftrace();
+
+ if (marker_fd >= 0)
+ MARKER("Without O_DIRECT");
+
+ fd = open("file", O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0)
+ error(1, errno, "open");
+ ret = write(fd, buf, 512);
+ if (ret < 0)
+ error(1, errno, "write");
+ close(fd);
+
+ if (marker_fd)
+ MARKER("With O_DIRECT");
+
+ fd = open("file", O_CREAT | O_TRUNC | O_WRONLY | O_DIRECT, S_IRUSR | S_IWUSR);
+ if (fd < 0)
+ error(1, errno, "open");
+ ret = write(fd, buf, 512);
+ if (ret < 0)
+ error(1, errno, "write");
+ close(fd);
+
+ if (marker_fd)
+ MARKER("Without O_DIRECT and with posix_fadvise");
+
+ fd = open("file", O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0)
+ error(1, errno, "open");
+ ret = write(fd, buf, 512);
+ if (ret < 0)
+ error(1, errno, "write");
+ ret = posix_fadvise(fd, 0, 512, POSIX_FADV_DONTNEED);
+ if (ret != 0)
+ error(1, ret, "posix_fadvise");
+ close(fd);
+
+ if (marker_fd)
+ MARKER("End");
+
+ if (trace_fd >= 0)
+ write(trace_fd, "0", 1);
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+DEBUGFS=`grep debugfs /proc/mounts | awk '{ print $2; }'`
+T=$DEBUGFS/tracing
+
+echo 0 > $T/tracing_enabled
+echo function_graph > $T/current_tracer
+echo > $T/trace
+
+echo > $T/set_ftrace_filter
+
+echo > $T/set_graph_function
+echo sys_open sys_write sys_close sys_fadvise64_64 > $T/set_graph_function
+
+echo 1 > $T/events/syscalls/sys_enter_write/enable
+echo 1 > $T/events/syscalls/sys_enter_open/enable
+echo 1 > $T/events/syscalls/sys_enter_close/enable
+
+echo 0 > $T/tracing_on # We switch tracing on in the program
+echo 1 > $T/tracing_enabled
+
+( exec ./direct )
+
+echo 0 > $T/tracing_enabled
+cp $T/trace .