#!/usr/bin/bpftrace 

uprobe:/lib/x86_64-linux-gnu/libc.so.6:fsync {
    @start_fsync_user[tid] = nsecs;
}

tracepoint:syscalls:sys_enter_fsync {
    @start_fsync_kernel[tid] = nsecs;
}

uprobe:/lib/x86_64-linux-gnu/libc.so.6:fdatasync {
    @start_fdatasync_user[tid] = nsecs;
}

tracepoint:syscalls:sys_enter_fdatasync {
    @start_fdatasync_kernel[tid] = nsecs;
}

tracepoint:syscalls:sys_exit_fsync /@start_fsync_user[tid]/ {
    $now = nsecs;
    $k_duration = ($now - @start_fsync_kernel[tid]) / 1000;
    $u_duration = ($now - @start_fsync_user[tid]) / 1000;
    
    printf("[    fsync] PID %-6d | Kernel: %-6d us | User: %-6d us | Lag: %-6d us\n", 
        tid, $k_duration, $u_duration, $u_duration - $k_duration);
        
    delete(@start_fsync_user[tid]);
    delete(@start_fsync_kernel[tid]);
}

tracepoint:syscalls:sys_exit_fdatasync /@start_fdatasync_user[tid]/ {
    $now = nsecs;
    $k_duration = ($now - @start_fdatasync_kernel[tid]) / 1000;
    $u_duration = ($now - @start_fdatasync_user[tid]) / 1000;
    
    printf("[fdatasync] PID %-6d | Kernel: %-6d us | User: %-6d us | Lag: %-6d us\n", 
        tid, $k_duration, $u_duration, $u_duration - $k_duration);
        
    delete(@start_fdatasync_user[tid]);
    delete(@start_fdatasync_kernel[tid]);
}
