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