1111#include <sys/zfs_znode.h>
1212#include <sys/dmu_objset.h>
1313#include <sys/spa_impl.h>
14+ #include <sys/zil_impl.h>
1415
1516typedef struct {
1617 u64 start_time ;
@@ -23,10 +24,11 @@ typedef struct {
2324BPF_HASH (io_info_map , u32 , io_info_t );
2425
2526#ifndef OPTARG
26- #define POOL "domain0"
27+ #define POOL "domain0"
2728#else
28- #define POOL (OPTARG)
29+ #define POOL (OPTARG)
2930#endif
31+
3032#define ZFS_READ_SYNC_LENGTH 14
3133#define ZFS_READ_ASYNC_LENGTH 15
3234#define ZFS_WRITE_SYNC_LENGTH 15
@@ -36,35 +38,23 @@ BPF_HASH(io_info_map, u32, io_info_t);
3638static inline bool
3739equal_to_pool (char * str )
3840{
39- char comparand [sizeof (POOL )];
40- bpf_probe_read (& comparand , sizeof (comparand ), str );
41- char compare [] = POOL ;
42- for (int i = 0 ; i < sizeof (comparand ); ++ i )
43- if (compare [i ] != comparand [i ])
44- return (false);
45- return (true);
41+ char comparand [sizeof (POOL )];
42+ bpf_probe_read (& comparand , sizeof (comparand ), str );
43+ char compare [] = POOL ;
44+ for (int i = 0 ; i < sizeof (comparand ); ++ i )
45+ if (compare [i ] != comparand [i ])
46+ return (false);
47+ return (true);
4648}
4749
4850static inline int
4951zfs_read_write_entry (io_info_t * info , struct znode * zn , zfs_uio_t * uio , int flags )
5052{
51- // Essentially ITOZSB, but written explicitly so that BCC can insert
52- // the necessary calls to bpf_probe_read.
53- zfsvfs_t * zfsvfs = zn -> z_inode .i_sb -> s_fs_info ;
54-
55- objset_t * z_os = zfsvfs -> z_os ;
56- spa_t * spa = z_os -> os_spa ;
57-
58- if (!equal_to_pool (spa -> spa_name ))
59- return (0 );
60-
6153 info -> start_time = bpf_ktime_get_ns ();
6254 info -> bytes = uio -> uio_resid ;
63- info -> is_sync =
64- z_os -> os_sync == ZFS_SYNC_ALWAYS || (flags & (O_SYNC | O_DSYNC ));
55+ info -> is_sync = (flags & (O_SYNC | O_DSYNC ));
6556
6657 u32 tid = bpf_get_current_pid_tgid ();
67- io_info_t * infop = io_info_map .lookup (& tid );
6858 io_info_map .update (& tid , info );
6959
7060 return (0 );
@@ -88,10 +78,28 @@ zfs_write_entry(struct pt_regs *ctx, struct znode *zn, zfs_uio_t *uio, int flags
8878 return (zfs_read_write_entry (& info , zn , uio , flags ));
8979}
9080
81+ // @@ kprobe|zfs_log_write|zfs_log_write_entry
82+ int
83+ zfs_log_write_entry (struct pt_regs * ctx , zilog_t * zilog )
84+ {
85+ u32 tid = bpf_get_current_pid_tgid ();
86+ io_info_t * info = io_info_map .lookup (& tid );
87+ if (info == NULL ) {
88+ return (0 );
89+ }
90+
91+ if (!equal_to_pool (zilog -> zl_spa -> spa_name )) {
92+ io_info_map .delete (& tid );
93+ }
94+ info -> is_sync = info -> is_sync || zilog -> zl_os -> os_sync == ZFS_SYNC_ALWAYS ;
95+
96+ return (0 );
97+ }
98+
9199// @@ kretprobe|zfs_read|zfs_read_write_exit
92100// @@ kretprobe|zfs_write|zfs_read_write_exit
93101int
94- zfs_read_write_exit (struct pt_regs * ctx , struct znode * zn , zfs_uio_t * uio )
102+ zfs_read_write_exit (struct pt_regs * ctx )
95103{
96104 u32 tid = bpf_get_current_pid_tgid ();
97105 io_info_t * info = io_info_map .lookup (& tid );
@@ -110,11 +118,7 @@ zfs_read_write_exit(struct pt_regs *ctx, struct znode *zn, zfs_uio_t *uio)
110118 __builtin_memcpy (name , "zfs_write async" , ZFS_WRITE_ASYNC_LENGTH );
111119 }
112120 } else {
113- if (info -> is_sync ) {
114- __builtin_memcpy (name , "zfs_read sync" , ZFS_READ_SYNC_LENGTH );
115- } else {
116- __builtin_memcpy (name , "zfs_read async" , ZFS_READ_ASYNC_LENGTH );
117- }
121+ __builtin_memcpy (name , "zfs_read" , ZFS_READ_SYNC_LENGTH );
118122 }
119123
120124 char axis = 0 ;
0 commit comments