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