#5522·bcc

zfsslower (bcc version) does not handle zpl_iter_{read,write} correctly

Author: taokyCreated Jun 16, 2026Updated Jun 16, 2026

In tools/zfsslower.py:

c
// zpl_read(), zpl_write():
int trace_rw_entry(struct pt_regs *ctx, struct file *filp, char __user *buf,
    size_t len, loff_t *ppos)
python
if BPF.get_kprobe_functions(b'zpl_iter.*'):
    b.attach_kprobe(event="zpl_iter_read", fn_name="trace_rw_entry")
    b.attach_kprobe(event="zpl_iter_write", fn_name="trace_rw_entry")

However, in zfs code:

https://github.com/openzfs/zfs/blob/0a4b5976542e794c3231b0c5c3d504903e392250/module/os/linux/zfs/zpl_file.c#L215

c
static ssize_t
zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to)

The function signature does not match, making zfsslower printing misleading output. The libbpf version fsslower does not have this issue.

A possible fix:

c
// zpl_iter_read(), zpl_iter_write():
int trace_zpl_iter_rw_entry(struct pt_regs *ctx,
                            struct kiocb *kiocb,
                            struct iov_iter *iter)
{
    u64 id = bpf_get_current_pid_tgid();
    u32 tgid = id >> 32;

    if (FILTER_PID)
        return 0;

    if (!kiocb)
        return 0;

    struct val_t val = {};
    val.ts = bpf_ktime_get_ns();

    bpf_probe_read_kernel(&val.fp, sizeof(val.fp), &kiocb->ki_filp);
    bpf_probe_read_kernel(&val.offset, sizeof(val.offset), &kiocb->ki_pos);

    if (val.fp)
        entryinfo.update(&id, &val);

    return 0;
}

And use this as kprobe for iter instead.