1 #include <sys/zfs_znode.h> 2 #include <sys/fs/zfs.h> 3 #include <sys/fs/zev.h> 4 #include <sys/zfs_events.h> 5 6 #define ZEV_FILL_INODE_INFO(name, znode) \ 7 do { \ 8 uint64_t mtime[2], ctime[2]; \ 9 sa_bulk_attr_t bulk[2]; \ 10 int count = 0; \ 11 timestruc_t mtime_s, ctime_s; \ 12 SA_ADD_BULK_ATTR(bulk, count, \ 13 SA_ZPL_MTIME(znode->z_zfsvfs), \ 14 NULL, &mtime, 16); \ 15 SA_ADD_BULK_ATTR(bulk, count, \ 16 SA_ZPL_CTIME(znode->z_zfsvfs), \ 17 NULL, &ctime, 16); \ 18 if ((sa_bulk_lookup(znode->z_sa_hdl, bulk, count)) != 0) { \ 19 zev_queue_error(op, "znode write: " \ 20 "mtime/ctime unavailable"); \ 21 /* continue anyway, use fake data */ \ 22 mtime_s.tv_sec = ctime_s.tv_sec = 0; \ 23 } \ 24 ZFS_TIME_DECODE(&mtime_s, mtime); \ 25 ZFS_TIME_DECODE(&ctime_s, ctime); \ 26 rec->name.ino = znode->z_id; \ 27 rec->name.gen = znode->z_gen; \ 28 rec->name.mtime = mtime_s.tv_sec; \ 29 rec->name.ctime = ctime_s.tv_sec; \ 30 rec->name.size = znode->z_size; \ 31 rec->name.type = znode->z_vnode->v_type; \ 32 rec->name.mode = znode->z_mode & MODEMASK; \ 33 rec->name.links = znode->z_links; \ 34 rec->name.flags = znode->z_pflags & ZFS_XATTR ? \ 35 ZEV_FL_XATTR : 0; \ 36 } while(0) 37 38 void 39 zev_zfs_mount_cb(vfs_t *vfs, vnode_t *mpt, char *dataset, boolean_t remount) 40 { 41 int op = ZEV_OP_ZFS_MOUNT; 42 char mountpoint[MAXPATHLEN+1]; 43 int mountpoint_len; 44 int dataset_len; 45 zev_zfs_mount_t *rec; 46 zev_msg_t *msg = NULL; 47 int msg_size; 48 49 zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data; 50 if (dsl_dataset_is_snapshot(zfsvfs->z_os->os_dsl_dataset)) 51 return; 52 if (zev_skip_pool(zfsvfs->z_os)) 53 return; 54 /* expensive, but we don't have many mount ops. */ 55 if ((vnodetopath(NULL, mpt, mountpoint, sizeof(mountpoint), 56 kcred)) != 0) { 57 zev_queue_error(op, "unresolvable mountpoint, dataset=%s", 58 dataset); 59 return; 60 } 61 62 dataset_len = strlen(dataset); 63 mountpoint_len = strlen(mountpoint); 64 msg_size = sizeof(*rec) + dataset_len + 1 + mountpoint_len + 1; 65 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 66 msg->size = msg_size; 67 rec = (zev_zfs_mount_t *)(msg + 1); 68 rec->record_len = msg_size; 69 rec->op = op; 70 rec->op_time = ddi_get_time(); 71 rec->guid = zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 72 rec->remount = remount; 73 rec->dataset_len = dataset_len; 74 rec->mountpoint_len = mountpoint_len; 75 (void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1); 76 (void) memcpy(ZEV_MOUNTPOINT(rec), mountpoint, mountpoint_len + 1); 77 rec->root_ino = zfsvfs->z_root; 78 zev_queue_message(op, msg); 79 } 80 81 void 82 zev_zfs_umount_cb(vfs_t *vfs) 83 { 84 int op = ZEV_OP_ZFS_UMOUNT; 85 zev_zfs_umount_t *rec; 86 zev_msg_t *msg = NULL; 87 int msg_size; 88 89 zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data; 90 if (dsl_dataset_is_snapshot(zfsvfs->z_os->os_dsl_dataset)) 91 return; 92 if (zev_skip_pool(zfsvfs->z_os)) 93 return; 94 95 msg_size = sizeof(*rec); 96 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 97 msg->size = msg_size; 98 rec = (zev_zfs_umount_t *)(msg + 1); 99 rec->record_len = msg_size; 100 rec->op = op; 101 rec->op_time = ddi_get_time(); 102 rec->guid = zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 103 zev_queue_message(op, msg); 104 } 105 106 void 107 zev_zvol_truncate_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len) 108 { 109 int op = ZEV_OP_ZVOL_TRUNCATE; 110 zev_zvol_truncate_t *rec; 111 zev_msg_t *msg = NULL; 112 int msg_size; 113 int dataset_len; 114 115 if (zev_skip_pool(os)) 116 return; 117 118 dataset_len = strlen(dataset); 119 msg_size = sizeof(*rec) + dataset_len + 1; 120 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 121 msg->size = msg_size; 122 rec = (zev_zvol_truncate_t *)(msg + 1); 123 rec->record_len = msg_size; 124 rec->op = op; 125 rec->op_time = ddi_get_time(); 126 rec->guid = os->os_dsl_dataset->ds_phys->ds_guid; 127 rec->offset = off; 128 rec->length = len; 129 rec->dataset_len = dataset_len; 130 (void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1); 131 zev_queue_message(op, msg); 132 } 133 134 void 135 zev_zvol_write_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len) 136 { 137 int op = ZEV_OP_ZVOL_WRITE; 138 zev_zvol_write_t *rec; 139 zev_msg_t *msg = NULL; 140 int msg_size; 141 int dataset_len; 142 143 if (zev_skip_pool(os)) 144 return; 145 146 dataset_len = strlen(dataset); 147 msg_size = sizeof(*rec) + dataset_len + 1; 148 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 149 msg->size = msg_size; 150 rec = (zev_zvol_write_t *)(msg + 1); 151 rec->record_len = msg_size; 152 rec->op = op; 153 rec->op_time = ddi_get_time(); 154 rec->guid = os->os_dsl_dataset->ds_phys->ds_guid; 155 rec->offset = off; 156 rec->length = len; 157 rec->dataset_len = dataset_len; 158 (void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1); 159 zev_queue_message(op, msg); 160 } 161 162 void 163 zev_znode_close_after_update_cb(znode_t *zp) 164 { 165 int op = ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE; 166 zev_znode_close_after_update_t *rec; 167 zev_msg_t *msg = NULL; 168 int msg_size; 169 170 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 171 return; 172 173 msg_size = sizeof(*rec); 174 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 175 msg->size = msg_size; 176 rec = (zev_znode_close_after_update_t *)(msg + 1); 177 rec->record_len = msg_size; 178 rec->op = op; 179 rec->op_time = ddi_get_time(); 180 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 181 ZEV_FILL_INODE_INFO(file, zp); 182 zev_queue_message(op, msg); 183 } 184 185 void 186 zev_znode_create_cb(znode_t *dzp, znode_t *zp, char *name, uint64_t txtype) 187 { 188 int op = ZEV_OP_ZNODE_CREATE; 189 zev_znode_create_t *rec; 190 zev_msg_t *msg = NULL; 191 int msg_size; 192 int name_len; 193 194 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 195 return; 196 197 int type = (int)txtype; 198 switch(type) { 199 case TX_CREATE: 200 case TX_CREATE_ACL: 201 case TX_CREATE_ATTR: 202 case TX_CREATE_ACL_ATTR: 203 op = ZEV_OP_ZNODE_CREATE; 204 break; 205 case TX_MKDIR: 206 case TX_MKDIR_ACL: 207 case TX_MKDIR_ATTR: 208 case TX_MKDIR_ACL_ATTR: 209 op = ZEV_OP_ZNODE_MKDIR; 210 break; 211 case TX_MKXATTR: 212 op = ZEV_OP_ZNODE_MAKE_XATTR_DIR; 213 break; 214 default: 215 zev_queue_error(ZEV_OP_ZNODE_CREATE, 216 "ERROR: ZNODE_CREATE: unknown txtype %d " 217 "(dir_inode=%d:%d inode=%d:%d name='%s')\n", 218 type, 219 dzp->z_gen, 220 dzp->z_id, 221 zp->z_gen, 222 zp->z_id, 223 name); 224 return; 225 } 226 227 /* all three types use the same struct, so this works for all types: */ 228 name_len = strlen(name); 229 msg_size = sizeof(*rec) + name_len + 1; 230 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 231 msg->size = msg_size; 232 rec = (zev_znode_create_t *)(msg + 1); 233 rec->record_len = msg_size; 234 rec->op = op; 235 rec->op_time = ddi_get_time(); 236 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 237 ZEV_FILL_INODE_INFO(parent, dzp); 238 ZEV_FILL_INODE_INFO(file, zp); 239 rec->name_len = name_len; 240 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 241 zev_queue_message(op, msg); 242 } 243 244 void 245 zev_znode_remove_cb(znode_t *dzp, char *name, uint64_t txtype) 246 { 247 int op = ZEV_OP_ZNODE_REMOVE; 248 zev_znode_remove_t *rec; 249 zev_msg_t *msg = NULL; 250 int msg_size; 251 int name_len; 252 253 if (zev_skip_pool(dzp->z_zfsvfs->z_os)) 254 return; 255 256 int type = (int)txtype; 257 switch(type) { 258 case TX_REMOVE: 259 op = ZEV_OP_ZNODE_REMOVE; 260 break; 261 case TX_RMDIR: 262 op = ZEV_OP_ZNODE_RMDIR; 263 break; 264 default: 265 zev_queue_error(ZEV_OP_ZNODE_REMOVE, 266 "ERROR: ZNODE_REMOVE: unknown txtype %d " 267 "(dir_inode=%d:%d name='%s')\n", 268 type, 269 dzp->z_gen, 270 dzp->z_id, 271 name); 272 return; 273 } 274 275 /* both types use the same struct, so this works for all types: */ 276 name_len = strlen(name); 277 msg_size = sizeof(*rec) + name_len + 1; 278 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 279 msg->size = msg_size; 280 rec = (zev_znode_remove_t *)(msg + 1); 281 rec->record_len = msg_size; 282 rec->op = op; 283 rec->op_time = ddi_get_time(); 284 rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 285 ZEV_FILL_INODE_INFO(parent, dzp); 286 rec->name_len = name_len; 287 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 288 zev_queue_message(op, msg); 289 } 290 291 void 292 zev_znode_link_cb(znode_t *dzp, znode_t *zp, char *name) 293 { 294 int op = ZEV_OP_ZNODE_LINK; 295 zev_znode_link_t *rec; 296 zev_msg_t *msg = NULL; 297 int msg_size; 298 int name_len; 299 300 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 301 return; 302 303 name_len = strlen(name); 304 msg_size = sizeof(*rec) + name_len + 1; 305 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 306 msg->size = msg_size; 307 rec = (zev_znode_link_t *)(msg + 1); 308 rec->record_len = msg_size; 309 rec->op = op; 310 rec->op_time = ddi_get_time(); 311 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 312 ZEV_FILL_INODE_INFO(parent, dzp); 313 ZEV_FILL_INODE_INFO(file, zp); 314 rec->name_len = name_len; 315 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 316 zev_queue_message(op, msg); 317 } 318 319 void 320 zev_znode_symlink_cb(znode_t *dzp, znode_t *zp, char *name, char *link) 321 { 322 int op = ZEV_OP_ZNODE_SYMLINK; 323 zev_znode_symlink_t *rec; 324 zev_msg_t *msg = NULL; 325 int msg_size; 326 int name_len; 327 int link_len; 328 329 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 330 return; 331 332 name_len = strlen(name); 333 link_len = strlen(link); 334 msg_size = sizeof(*rec) + name_len + 1 + link_len + 1; 335 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 336 msg->size = msg_size; 337 rec = (zev_znode_symlink_t *)(msg + 1); 338 rec->record_len = msg_size; 339 rec->op = op; 340 rec->op_time = ddi_get_time(); 341 rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 342 ZEV_FILL_INODE_INFO(parent, dzp); 343 ZEV_FILL_INODE_INFO(file, zp); 344 rec->name_len = name_len; 345 rec->link_len = link_len; 346 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 347 (void) memcpy(ZEV_LINK(rec), link, link_len + 1); 348 zev_queue_message(op, msg); 349 } 350 351 void 352 zev_znode_rename_cb(znode_t *sdzp, char *sname, znode_t *tdzp, 353 char *tname, znode_t *szp) 354 { 355 int op = ZEV_OP_ZNODE_RENAME; 356 zev_znode_rename_t *rec; 357 zev_msg_t *msg = NULL; 358 int msg_size; 359 int srcname_len; 360 int dstname_len; 361 362 if (zev_skip_pool(szp->z_zfsvfs->z_os)) 363 return; 364 365 srcname_len = strlen(sname); 366 dstname_len = strlen(tname); 367 msg_size = sizeof(*rec) + srcname_len + 1 + dstname_len + 1; 368 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 369 msg->size = msg_size; 370 rec = (zev_znode_rename_t *)(msg + 1); 371 rec->record_len = msg_size; 372 rec->op = op; 373 rec->op_time = ddi_get_time(); 374 rec->guid = szp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 375 ZEV_FILL_INODE_INFO(srcdir, sdzp); 376 ZEV_FILL_INODE_INFO(dstdir, tdzp); 377 ZEV_FILL_INODE_INFO(file, szp); 378 rec->srcname_len = srcname_len; 379 rec->dstname_len = dstname_len; 380 (void) memcpy(ZEV_SRCNAME(rec), sname, srcname_len + 1); 381 (void) memcpy(ZEV_DSTNAME(rec), tname, dstname_len + 1); 382 zev_queue_message(op, msg); 383 } 384 385 void 386 zev_znode_write_cb(znode_t *zp, uint64_t off, uint64_t len) 387 { 388 int op = ZEV_OP_ZNODE_WRITE; 389 zev_znode_write_t *rec; 390 zev_msg_t *msg = NULL; 391 int msg_size; 392 393 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 394 return; 395 396 msg_size = sizeof(*rec); 397 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 398 msg->size = msg_size; 399 rec = (zev_znode_write_t *)(msg + 1); 400 rec->record_len = msg_size; 401 rec->op = op; 402 rec->op_time = ddi_get_time(); 403 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 404 ZEV_FILL_INODE_INFO(file, zp); 405 rec->offset = off; 406 rec->length = len; 407 zev_queue_message(op, msg); 408 } 409 410 void 411 zev_znode_truncate_cb(znode_t *zp, uint64_t off, uint64_t len) 412 { 413 int op = ZEV_OP_ZNODE_TRUNCATE; 414 zev_znode_truncate_t *rec; 415 zev_msg_t *msg = NULL; 416 int msg_size; 417 418 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 419 return; 420 421 msg_size = sizeof(*rec); 422 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 423 msg->size = msg_size; 424 rec = (zev_znode_truncate_t *)(msg + 1); 425 rec->record_len = msg_size; 426 rec->op = op; 427 rec->op_time = ddi_get_time(); 428 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 429 ZEV_FILL_INODE_INFO(file, zp); 430 rec->offset = off; 431 rec->length = len; 432 zev_queue_message(op, msg); 433 } 434 435 void 436 zev_znode_setattr_cb(znode_t *zp) 437 { 438 int op = ZEV_OP_ZNODE_SETATTR; 439 zev_znode_setattr_t *rec; 440 zev_msg_t *msg = NULL; 441 int msg_size; 442 443 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 444 return; 445 446 msg_size = sizeof(*rec); 447 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 448 msg->size = msg_size; 449 rec = (zev_znode_setattr_t *)(msg + 1); 450 rec->record_len = msg_size; 451 rec->op = op; 452 rec->op_time = ddi_get_time(); 453 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 454 ZEV_FILL_INODE_INFO(file, zp); 455 zev_queue_message(op, msg); 456 } 457 458 void 459 zev_znode_acl_cb(znode_t *zp) 460 { 461 int op = ZEV_OP_ZNODE_ACL; 462 zev_znode_acl_t *rec; 463 zev_msg_t *msg = NULL; 464 int msg_size; 465 466 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 467 return; 468 469 msg_size = sizeof(*rec); 470 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 471 msg->size = msg_size; 472 rec = (zev_znode_acl_t *)(msg + 1); 473 rec->record_len = msg_size; 474 rec->op = op; 475 rec->op_time = ddi_get_time(); 476 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 477 ZEV_FILL_INODE_INFO(file, zp); 478 zev_queue_message(op, msg); 479 } 480 481 rz_zev_callbacks_t zev_callbacks = { 482 /* zfsvfs events */ 483 .rz_zev_zfs_mount = zev_zfs_mount_cb, 484 .rz_zev_zfs_umount = zev_zfs_umount_cb, 485 486 /* zvol zil events */ 487 .rz_zev_zvol_truncate = zev_zvol_truncate_cb, 488 .rz_zev_zvol_write = zev_zvol_write_cb, 489 490 /* znode zil events */ 491 .rz_zev_znode_close_after_update = zev_znode_close_after_update_cb, 492 .rz_zev_znode_create = zev_znode_create_cb, 493 .rz_zev_znode_remove = zev_znode_remove_cb, 494 .rz_zev_znode_link = zev_znode_link_cb, 495 .rz_zev_znode_symlink = zev_znode_symlink_cb, 496 .rz_zev_znode_rename = zev_znode_rename_cb, 497 .rz_zev_znode_write = zev_znode_write_cb, 498 .rz_zev_znode_truncate = zev_znode_truncate_cb, 499 .rz_zev_znode_setattr = zev_znode_setattr_cb, 500 .rz_zev_znode_acl = zev_znode_acl_cb, 501 }; 502 503