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, znode_t *zp, 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(file, zp); 288 ZEV_FILL_INODE_INFO(parent, dzp); 289 rec->name_len = name_len; 290 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 291 zev_queue_message(op, msg); 292 } 293 294 void 295 zev_znode_link_cb(znode_t *dzp, znode_t *zp, char *name) 296 { 297 int op = ZEV_OP_ZNODE_LINK; 298 zev_znode_link_t *rec; 299 zev_msg_t *msg = NULL; 300 int msg_size; 301 int name_len; 302 303 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 304 return; 305 306 name_len = strlen(name); 307 msg_size = sizeof(*rec) + name_len + 1; 308 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 309 msg->size = msg_size; 310 rec = (zev_znode_link_t *)(msg + 1); 311 rec->record_len = msg_size; 312 rec->op = op; 313 rec->op_time = ddi_get_time(); 314 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 315 ZEV_FILL_INODE_INFO(parent, dzp); 316 ZEV_FILL_INODE_INFO(file, zp); 317 rec->name_len = name_len; 318 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 319 zev_queue_message(op, msg); 320 } 321 322 void 323 zev_znode_symlink_cb(znode_t *dzp, znode_t *zp, char *name, char *link) 324 { 325 int op = ZEV_OP_ZNODE_SYMLINK; 326 zev_znode_symlink_t *rec; 327 zev_msg_t *msg = NULL; 328 int msg_size; 329 int name_len; 330 int link_len; 331 332 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 333 return; 334 335 name_len = strlen(name); 336 link_len = strlen(link); 337 msg_size = sizeof(*rec) + name_len + 1 + link_len + 1; 338 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 339 msg->size = msg_size; 340 rec = (zev_znode_symlink_t *)(msg + 1); 341 rec->record_len = msg_size; 342 rec->op = op; 343 rec->op_time = ddi_get_time(); 344 rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 345 ZEV_FILL_INODE_INFO(parent, dzp); 346 ZEV_FILL_INODE_INFO(file, zp); 347 rec->name_len = name_len; 348 rec->link_len = link_len; 349 (void) memcpy(ZEV_NAME(rec), name, name_len + 1); 350 (void) memcpy(ZEV_LINK(rec), link, link_len + 1); 351 zev_queue_message(op, msg); 352 } 353 354 void 355 zev_znode_rename_cb(znode_t *sdzp, char *sname, znode_t *tdzp, 356 char *tname, znode_t *szp) 357 { 358 int op = ZEV_OP_ZNODE_RENAME; 359 zev_znode_rename_t *rec; 360 zev_msg_t *msg = NULL; 361 int msg_size; 362 int srcname_len; 363 int dstname_len; 364 365 if (zev_skip_pool(szp->z_zfsvfs->z_os)) 366 return; 367 368 srcname_len = strlen(sname); 369 dstname_len = strlen(tname); 370 msg_size = sizeof(*rec) + srcname_len + 1 + dstname_len + 1; 371 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 372 msg->size = msg_size; 373 rec = (zev_znode_rename_t *)(msg + 1); 374 rec->record_len = msg_size; 375 rec->op = op; 376 rec->op_time = ddi_get_time(); 377 rec->guid = szp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 378 ZEV_FILL_INODE_INFO(srcdir, sdzp); 379 ZEV_FILL_INODE_INFO(dstdir, tdzp); 380 ZEV_FILL_INODE_INFO(file, szp); 381 rec->srcname_len = srcname_len; 382 rec->dstname_len = dstname_len; 383 (void) memcpy(ZEV_SRCNAME(rec), sname, srcname_len + 1); 384 (void) memcpy(ZEV_DSTNAME(rec), tname, dstname_len + 1); 385 zev_queue_message(op, msg); 386 } 387 388 void 389 zev_znode_write_cb(znode_t *zp, uint64_t off, uint64_t len) 390 { 391 int op = ZEV_OP_ZNODE_WRITE; 392 zev_znode_write_t *rec; 393 zev_msg_t *msg = NULL; 394 int msg_size; 395 396 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 397 return; 398 399 msg_size = sizeof(*rec); 400 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 401 msg->size = msg_size; 402 rec = (zev_znode_write_t *)(msg + 1); 403 rec->record_len = msg_size; 404 rec->op = op; 405 rec->op_time = ddi_get_time(); 406 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 407 ZEV_FILL_INODE_INFO(file, zp); 408 rec->offset = off; 409 rec->length = len; 410 zev_queue_message(op, msg); 411 } 412 413 void 414 zev_znode_truncate_cb(znode_t *zp, uint64_t off, uint64_t len) 415 { 416 int op = ZEV_OP_ZNODE_TRUNCATE; 417 zev_znode_truncate_t *rec; 418 zev_msg_t *msg = NULL; 419 int msg_size; 420 421 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 422 return; 423 424 msg_size = sizeof(*rec); 425 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 426 msg->size = msg_size; 427 rec = (zev_znode_truncate_t *)(msg + 1); 428 rec->record_len = msg_size; 429 rec->op = op; 430 rec->op_time = ddi_get_time(); 431 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 432 ZEV_FILL_INODE_INFO(file, zp); 433 rec->offset = off; 434 rec->length = len; 435 zev_queue_message(op, msg); 436 } 437 438 void 439 zev_znode_setattr_cb(znode_t *zp) 440 { 441 int op = ZEV_OP_ZNODE_SETATTR; 442 zev_znode_setattr_t *rec; 443 zev_msg_t *msg = NULL; 444 int msg_size; 445 446 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 447 return; 448 449 msg_size = sizeof(*rec); 450 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 451 msg->size = msg_size; 452 rec = (zev_znode_setattr_t *)(msg + 1); 453 rec->record_len = msg_size; 454 rec->op = op; 455 rec->op_time = ddi_get_time(); 456 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 457 ZEV_FILL_INODE_INFO(file, zp); 458 zev_queue_message(op, msg); 459 } 460 461 void 462 zev_znode_acl_cb(znode_t *zp) 463 { 464 int op = ZEV_OP_ZNODE_ACL; 465 zev_znode_acl_t *rec; 466 zev_msg_t *msg = NULL; 467 int msg_size; 468 469 if (zev_skip_pool(zp->z_zfsvfs->z_os)) 470 return; 471 472 msg_size = sizeof(*rec); 473 msg = kmem_alloc(sizeof(*msg) + msg_size, KM_SLEEP); 474 msg->size = msg_size; 475 rec = (zev_znode_acl_t *)(msg + 1); 476 rec->record_len = msg_size; 477 rec->op = op; 478 rec->op_time = ddi_get_time(); 479 rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid; 480 ZEV_FILL_INODE_INFO(file, zp); 481 zev_queue_message(op, msg); 482 } 483 484 rz_zev_callbacks_t zev_callbacks = { 485 /* zfsvfs events */ 486 .rz_zev_zfs_mount = zev_zfs_mount_cb, 487 .rz_zev_zfs_umount = zev_zfs_umount_cb, 488 489 /* zvol zil events */ 490 .rz_zev_zvol_truncate = zev_zvol_truncate_cb, 491 .rz_zev_zvol_write = zev_zvol_write_cb, 492 493 /* znode zil events */ 494 .rz_zev_znode_close_after_update = zev_znode_close_after_update_cb, 495 .rz_zev_znode_create = zev_znode_create_cb, 496 .rz_zev_znode_remove = zev_znode_remove_cb, 497 .rz_zev_znode_link = zev_znode_link_cb, 498 .rz_zev_znode_symlink = zev_znode_symlink_cb, 499 .rz_zev_znode_rename = zev_znode_rename_cb, 500 .rz_zev_znode_write = zev_znode_write_cb, 501 .rz_zev_znode_truncate = zev_znode_truncate_cb, 502 .rz_zev_znode_setattr = zev_znode_setattr_cb, 503 .rz_zev_znode_acl = zev_znode_acl_cb, 504 }; 505 506