#include #include krwlock_t rz_zev_rwlock; volatile boolean_t rz_zev_is_active = B_FALSE; void rz_zev_init() { rw_init(&rz_zev_rwlock, NULL, RW_DRIVER, NULL); } void rz_zev_fini() { rw_destroy(&rz_zev_rwlock); } boolean_t rz_zev_active(void) { return rz_zev_is_active; } void rz_zev_set_active(boolean_t active) { rz_zev_is_active = active; } struct rz_zev_ops_counters { /* zfsvfs ops */ uint64_t rz_zev_zfs_mount; uint64_t rz_zev_zfs_umount; /* zvol ops */ uint64_t rz_zev_zvol_write; uint64_t rz_zev_zvol_truncate; /* znode ops */ uint64_t rz_zev_znode_close_after_update; uint64_t rz_zev_znode_create; uint64_t rz_zev_znode_remove; uint64_t rz_zev_znode_link; uint64_t rz_zev_znode_symlink; uint64_t rz_zev_znode_rename; uint64_t rz_zev_znode_write; uint64_t rz_zev_znode_truncate; uint64_t rz_zev_znode_setattr; uint64_t rz_zev_znode_acl; /* general statistics */ uint64_t rz_zev_total; } rz_zev_ops_counters = { .rz_zev_zfs_mount = 0, .rz_zev_zfs_umount = 0, .rz_zev_zvol_write = 0, .rz_zev_zvol_truncate = 0, .rz_zev_znode_close_after_update = 0, .rz_zev_znode_create = 0, .rz_zev_znode_remove = 0, .rz_zev_znode_link = 0, .rz_zev_znode_symlink = 0, .rz_zev_znode_rename = 0, .rz_zev_znode_write = 0, .rz_zev_znode_truncate = 0, .rz_zev_znode_setattr = 0, .rz_zev_znode_acl = 0, .rz_zev_total = 0, }; static void rz_zev_inc_total_ops_count(void) { atomic_inc_64(&rz_zev_ops_counters.rz_zev_total); DTRACE_PROBE1(rz_zev_ops_counter_total, unit64_t, rz_zev_ops_counters.rz_zev_total); /* non-atomic access */ } #define RZ_COUNTER_CB(opname, ...) \ void \ rz_zev_counter_##opname(__VA_ARGS__) \ { \ atomic_inc_64(&rz_zev_ops_counters.rz_zev_##opname); \ DTRACE_PROBE1(rz_zev_ops_counter_##opname, uint64_t, \ rz_zev_ops_counters.rz_zev_##opname); \ rz_zev_inc_total_ops_count(); \ } /* zfsvfs */ RZ_COUNTER_CB(zfs_mount, vfs_t *vfs, vnode_t *mpt, char *dataset, boolean_t remount) RZ_COUNTER_CB(zfs_umount, vfs_t *vfs) /* zvol */ RZ_COUNTER_CB(zvol_truncate, char *dataset, objset_t *os, dmu_tx_t *tx, uint64_t off, uint64_t len) RZ_COUNTER_CB(zvol_write, char *dataset, objset_t *os, dmu_tx_t *tx, uint64_t off, uint64_t len) /* znode */ RZ_COUNTER_CB(znode_close_after_update, znode_t *zp) RZ_COUNTER_CB(znode_create, znode_t *dzp, znode_t *zp, dmu_tx_t *tx, char *name, uint64_t txmode) RZ_COUNTER_CB(znode_remove, znode_t *dzp, znode_t *zp, dmu_tx_t *tx, char *name, uint64_t txmode) RZ_COUNTER_CB(znode_link, znode_t *dzp, znode_t *zp, dmu_tx_t *tx, char *name) RZ_COUNTER_CB(znode_symlink, znode_t *dzp, znode_t *zp, dmu_tx_t *tx, char *name, char *link) RZ_COUNTER_CB(znode_rename, znode_t *sdzp, char *sname, znode_t *tdzp, char *tname, znode_t *szp, znode_t *tzp, dmu_tx_t *tx) RZ_COUNTER_CB(znode_write, znode_t *zp, dmu_tx_t *tx, uint64_t off, uint64_t len) RZ_COUNTER_CB(znode_truncate, znode_t *zp, dmu_tx_t *tx, uint64_t off, uint64_t len) RZ_COUNTER_CB(znode_setattr, znode_t *zp, dmu_tx_t *tx) RZ_COUNTER_CB(znode_acl, znode_t *zp, dmu_tx_t *tx) rz_zev_callbacks_t rz_zev_counter_callbacks = { /* zfsvfs */ rz_zev_counter_zfs_mount, /* mount */ rz_zev_counter_zfs_umount, /* umount */ /* zvol */ rz_zev_counter_zvol_truncate, /* zvol truncate */ rz_zev_counter_zvol_write, /* zvol write */ /* znode */ rz_zev_counter_znode_close_after_update, /* close */ rz_zev_counter_znode_create, /* create */ rz_zev_counter_znode_remove, /* remove */ rz_zev_counter_znode_link, /* link */ rz_zev_counter_znode_symlink, /* symlink */ rz_zev_counter_znode_rename, /* rename */ rz_zev_counter_znode_write, /* write */ rz_zev_counter_znode_truncate, /* truncate */ rz_zev_counter_znode_setattr, /* setattr */ rz_zev_counter_znode_acl, /* acl */ }; /* * Hooks for write operation event callbacks. Will be changed by * a loadable module if event callbacks are desired. */ rz_zev_callbacks_t *rz_zev_default_callbacks = &rz_zev_counter_callbacks; rz_zev_callbacks_t *rz_zev_callbacks = &rz_zev_counter_callbacks;