xref: /titanic_54/usr/src/uts/common/fs/zev/zev_callbacks.c (revision 94bf38f1a41f1b790ff40cef75ab4241ab0b2e24)
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 #include <sys/zev_checksums.h>
7 #include <sys/dmu_tx.h>
8 #include <sys/mntent.h>
9 
10 #define ZEV_FILL_INODE_INFO(name, znode)				\
11 	do {								\
12 		uint64_t mtime[2], ctime[2];				\
13 		sa_bulk_attr_t bulk[2];					\
14 		int count = 0;						\
15 		timestruc_t mtime_s, ctime_s;				\
16 		SA_ADD_BULK_ATTR(bulk, count,				\
17 			         SA_ZPL_MTIME(znode->z_zfsvfs),		\
18 		                 NULL, &mtime, 16);			\
19 		SA_ADD_BULK_ATTR(bulk, count,				\
20 			         SA_ZPL_CTIME(znode->z_zfsvfs),		\
21 		                 NULL, &ctime, 16);			\
22 		if ((sa_bulk_lookup(znode->z_sa_hdl, bulk, count)) != 0) { \
23 			zev_queue_error(op, "znode write: "		\
24 			                "mtime/ctime unavailable");	\
25 			/* continue anyway, use fake data */		\
26 			mtime_s.tv_sec = ctime_s.tv_sec = 0;		\
27 		}							\
28 		ZFS_TIME_DECODE(&mtime_s, mtime);			\
29 		ZFS_TIME_DECODE(&ctime_s, ctime);			\
30 		rec->name.ino = znode->z_id;				\
31 		rec->name.gen = znode->z_gen;				\
32 		rec->name.mtime = mtime_s.tv_sec;			\
33 		rec->name.ctime = ctime_s.tv_sec;			\
34 		rec->name.size = znode->z_size;				\
35 		rec->name.type = znode->z_vnode->v_type;		\
36 		rec->name.mode =					\
37 			znode->z_mode | VTTOIF(znode->z_vnode->v_type);	\
38 		rec->name.links = znode->z_links;			\
39 		rec->name.flags = znode->z_pflags & ZFS_XATTR ?		\
40 			ZEV_FL_XATTR : 0;				\
41 	} while(0)
42 
43 void
44 zev_zfs_mount_cb(vfs_t *vfs, vnode_t *mpt, char *dataset, boolean_t remount)
45 {
46 	int op = ZEV_OP_ZFS_MOUNT;
47 	char mountpoint[MAXPATHLEN+1];
48 	int mountpoint_len;
49 	int dataset_len;
50 	zev_zfs_mount_t *rec;
51 	zev_msg_t *msg = NULL;
52 	int msg_size;
53 	znode_t *zp_root;
54 	dmu_tx_t *tx;
55 	int error;
56 	uint64_t txg;
57 
58 	zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data;
59 	if (zfsvfs->z_os->os_dsl_dataset->ds_is_snapshot)
60 		return;
61 	if (zev_skip_pool(zfsvfs->z_os))
62 		return;
63 	if (zev_skip_fs(zfsvfs))
64 		return;
65 	/* expensive, but we don't have many mount ops. */
66 	if ((vnodetopath(NULL, mpt, mountpoint, sizeof(mountpoint),
67 	    kcred)) != 0) {
68 		zev_queue_error(op, "unresolvable mountpoint, dataset=%s",
69 		                dataset);
70 		return;
71 	}
72 	if (zfs_zget(zfsvfs, zfsvfs->z_root, &zp_root) != 0) {
73 		zev_queue_error(op, "can't get root znode, dataset=%s",
74 		                dataset);
75 		return;
76 	}
77 
78 	/* get current tgx by adding an empty tx */
79 	tx = dmu_tx_create(zfsvfs->z_os);
80 	error = dmu_tx_assign(tx, TXG_WAIT);
81 	if (error) {
82 		dmu_tx_abort(tx);
83 		zev_queue_error(op, "can't create tx, dataset=%s", dataset);
84 		return;
85 	}
86 	txg = tx->tx_txg;
87 	dmu_tx_abort(tx);
88 
89 	dataset_len = strlen(dataset);
90 	mountpoint_len = strlen(mountpoint);
91 	msg_size = sizeof(*rec) + dataset_len + 1 + mountpoint_len + 1;
92 	msg = zev_alloc(sizeof(*msg) + msg_size);
93 	msg->size = msg_size;
94 	rec = (zev_zfs_mount_t *)(msg + 1);
95 	rec->record_len = msg_size;
96 	rec->op = op;
97 	rec->op_time = ddi_get_time();
98 	rec->guid = dsl_dataset_phys(zfsvfs->z_os->os_dsl_dataset)->ds_guid;
99 	rec->txg = txg;
100 	rec->remount = remount;
101 	rec->dataset_len = dataset_len;
102 	rec->mountpoint_len = mountpoint_len;
103 	ZEV_FILL_INODE_INFO(root, zp_root);
104 	VN_RELE(ZTOV(zp_root));
105 	(void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1);
106 	(void) memcpy(ZEV_MOUNTPOINT(rec), mountpoint, mountpoint_len + 1);
107 	zev_queue_message(op, msg);
108 }
109 
110 void
111 zev_zfs_umount_cb(vfs_t *vfs)
112 {
113 	int op = ZEV_OP_ZFS_UMOUNT;
114 	zev_zfs_umount_t *rec;
115 	zev_msg_t *msg = NULL;
116 	int msg_size;
117 	struct vnode *vp;
118 	znode_t *zp;
119 	dmu_tx_t *tx;
120 	int error;
121 	uint64_t txg;
122 
123 	zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data;
124 	if (zfsvfs->z_os->os_dsl_dataset->ds_is_snapshot)
125 		return;
126 	if (zev_skip_pool(zfsvfs->z_os))
127 		return;
128 	if (zev_skip_fs(zfsvfs))
129 		return;
130 
131 	/* get current tgx by adding an empty tx */
132 	tx = dmu_tx_create(zfsvfs->z_os);
133 	error = dmu_tx_assign(tx, TXG_WAIT);
134 	if (error) {
135 		dmu_tx_abort(tx);
136 		zev_queue_error(op, "can't create tx");
137 		return;
138 	}
139 	txg = tx->tx_txg;
140 	dmu_tx_abort(tx);
141 
142 	msg_size = sizeof(*rec);
143 	msg = zev_alloc(sizeof(*msg) + msg_size);
144 	msg->size = msg_size;
145 	rec = (zev_zfs_umount_t *)(msg + 1);
146 	rec->record_len = msg_size;
147 	rec->op = op;
148 	rec->op_time = ddi_get_time();
149 	rec->guid = dsl_dataset_phys(zfsvfs->z_os->os_dsl_dataset)->ds_guid;
150 	rec->txg = txg;
151 
152 	vp = vfs->vfs_vnodecovered;
153 	if (strcmp(vfssw[vp->v_vfsp->vfs_fstype].vsw_name, MNTTYPE_ZFS)) {
154 		cmn_err(CE_WARN, "covered inode not on zfs filesystem, "
155 		        "reporting all-zero inode struct.");
156 		memset(&rec->covered, 0, sizeof(rec->covered));
157 	} else {
158 		zp = VTOZ(vfs->vfs_vnodecovered);
159 		ZEV_FILL_INODE_INFO(covered, zp);
160 	}
161 
162 	zev_queue_message(op, msg);
163 }
164 
165 void
166 zev_zvol_truncate_cb(char *dataset,
167                      objset_t *os,
168                      dmu_tx_t *tx,
169                      uint64_t off,
170                      uint64_t len)
171 {
172 	int op = ZEV_OP_ZVOL_TRUNCATE;
173 	zev_zvol_truncate_t *rec;
174 	zev_msg_t *msg = NULL;
175 	int msg_size;
176 	int dataset_len;
177 
178 	if (zev_skip_pool(os))
179 		return;
180 
181 	dataset_len = strlen(dataset);
182 	msg_size = sizeof(*rec) + dataset_len + 1;
183 	msg = zev_alloc(sizeof(*msg) + msg_size);
184 	msg->size = msg_size;
185 	rec = (zev_zvol_truncate_t *)(msg + 1);
186 	rec->record_len = msg_size;
187 	rec->op = op;
188 	rec->op_time = ddi_get_time();
189 	rec->guid = dsl_dataset_phys(os->os_dsl_dataset)->ds_guid;
190 	rec->txg = tx->tx_txg;
191 	rec->offset = off;
192 	rec->length = len;
193 	rec->dataset_len = dataset_len;
194 	(void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1);
195 	zev_queue_message(op, msg);
196 }
197 
198 void
199 zev_zvol_write_cb(char *dataset,
200                   objset_t *os,
201                   dmu_tx_t *tx,
202                   uint64_t off,
203                   uint64_t len)
204 {
205 	int op = ZEV_OP_ZVOL_WRITE;
206 	zev_zvol_write_t *rec;
207 	zev_msg_t *msg = NULL;
208 	int msg_size;
209 	int dataset_len;
210 
211 	if (zev_skip_pool(os))
212 		return;
213 
214 	dataset_len = strlen(dataset);
215 	msg_size = sizeof(*rec) + dataset_len + 1;
216 	msg = zev_alloc(sizeof(*msg) + msg_size);
217 	msg->size = msg_size;
218 	rec = (zev_zvol_write_t *)(msg + 1);
219 	rec->record_len = msg_size;
220 	rec->op = op;
221 	rec->op_time = ddi_get_time();
222 	rec->guid = dsl_dataset_phys(os->os_dsl_dataset)->ds_guid;
223 	rec->txg = tx->tx_txg;
224 	rec->offset = off;
225 	rec->length = len;
226 	rec->dataset_len = dataset_len;
227 	(void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1);
228 	zev_queue_message(op, msg);
229 }
230 
231 void
232 zev_znode_close_after_update_cb(znode_t *zp)
233 {
234 	int op = ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE;
235 	zev_znode_close_after_update_t *rec;
236 	zev_msg_t *msg = NULL;
237 	int msg_size;
238 
239 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
240 		return;
241 	if (zev_skip_fs(zp->z_zfsvfs))
242 		return;
243 
244 	msg_size = sizeof(*rec);
245 	msg = zev_alloc(sizeof(*msg) + msg_size);
246 	msg->size = msg_size;
247 	rec = (zev_znode_close_after_update_t *)(msg + 1);
248 	rec->record_len = msg_size;
249 	rec->op = op;
250 	rec->op_time = ddi_get_time();
251 	rec->guid =
252 		dsl_dataset_phys(zp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
253 	ZEV_FILL_INODE_INFO(file, zp);
254 	zev_queue_message(op, msg);
255 }
256 
257 void
258 zev_znode_create_cb(znode_t *dzp,
259                     znode_t *zp,
260                     dmu_tx_t *tx,
261                     char *name,
262                     uint64_t txtype)
263 {
264 	int op = ZEV_OP_ZNODE_CREATE;
265 	zev_znode_create_t *rec;
266 	zev_msg_t *msg = NULL;
267 	int msg_size;
268 	int name_len;
269 
270 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
271 		return;
272 	if (zev_skip_fs(zp->z_zfsvfs))
273 		return;
274 
275 	int type = (int)txtype;
276 	switch(type) {
277 	case TX_CREATE:
278 	case TX_CREATE_ACL:
279 	case TX_CREATE_ATTR:
280 	case TX_CREATE_ACL_ATTR:
281 		op = ZEV_OP_ZNODE_CREATE;
282 		break;
283 	case TX_MKDIR:
284 	case TX_MKDIR_ACL:
285 	case TX_MKDIR_ATTR:
286 	case TX_MKDIR_ACL_ATTR:
287 		op = ZEV_OP_ZNODE_MKDIR;
288 		break;
289 	case TX_MKXATTR:
290 		op = ZEV_OP_ZNODE_MAKE_XATTR_DIR;
291 		break;
292 	default:
293 		zev_queue_error(ZEV_OP_ZNODE_CREATE,
294 		    "ERROR: ZNODE_CREATE: unknown txtype %d "
295 		    "(dir_inode=%d:%d inode=%d:%d name='%s')\n",
296 		    type,
297 		    dzp->z_gen,
298 		    dzp->z_id,
299 		    zp->z_gen,
300 		    zp->z_id,
301 		    name);
302 		return;
303 	}
304 
305 	/* all three types use the same struct, so this works for all types: */
306 	name_len = strlen(name);
307 	msg_size = sizeof(*rec) + name_len + 1;
308 	msg = zev_alloc(sizeof(*msg) + msg_size);
309 	msg->size = msg_size;
310 	rec = (zev_znode_create_t *)(msg + 1);
311 	rec->record_len = msg_size;
312 	rec->op = op;
313 	rec->op_time = ddi_get_time();
314 	rec->guid =
315 		dsl_dataset_phys(zp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
316 	rec->txg = tx->tx_txg;
317 	ZEV_FILL_INODE_INFO(parent, dzp);
318 	ZEV_FILL_INODE_INFO(file, zp);
319 	rec->name_len = name_len;
320 	(void) memcpy(ZEV_NAME(rec), name, name_len + 1);
321 	zev_create_checksum(rec, zp);
322 	zev_queue_message(op, msg);
323 }
324 
325 void
326 zev_znode_remove_cb(znode_t *dzp,
327                     znode_t *zp,
328                     dmu_tx_t *tx,
329                     char *name,
330                     uint64_t txtype)
331 {
332 	int op = ZEV_OP_ZNODE_REMOVE;
333 	zev_znode_remove_t *rec;
334 	zev_msg_t *msg = NULL;
335 	int msg_size;
336 	int name_len;
337 
338 	if (zev_skip_pool(dzp->z_zfsvfs->z_os))
339 		return;
340 	if (zev_skip_fs(dzp->z_zfsvfs))
341 		return;
342 
343 	int type = (int)txtype;
344 	switch(type) {
345 	case TX_REMOVE:
346 		op = ZEV_OP_ZNODE_REMOVE;
347 		break;
348 	case TX_RMDIR:
349 		op = ZEV_OP_ZNODE_RMDIR;
350 		break;
351 	default:
352 		zev_queue_error(ZEV_OP_ZNODE_REMOVE,
353 		    "ERROR: ZNODE_REMOVE: unknown txtype %d "
354 		    "(dir_inode=%d:%d name='%s')\n",
355 		    type,
356 		    dzp->z_gen,
357 		    dzp->z_id,
358 		    name);
359 		return;
360 	}
361 
362 	/* both types use the same struct, so this works for all types: */
363 	name_len = strlen(name);
364 	msg_size = sizeof(*rec) + name_len + 1;
365 	msg = zev_alloc(sizeof(*msg) + msg_size);
366 	msg->size = msg_size;
367 	rec = (zev_znode_remove_t *)(msg + 1);
368 	rec->record_len = msg_size;
369 	rec->op = op;
370 	rec->op_time = ddi_get_time();
371 	rec->guid =
372 		dsl_dataset_phys(dzp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
373 	rec->txg = tx->tx_txg;
374 	ZEV_FILL_INODE_INFO(file, zp);
375 	ZEV_FILL_INODE_INFO(parent, dzp);
376 	rec->name_len = name_len;
377 	(void) memcpy(ZEV_NAME(rec), name, name_len + 1);
378 	zev_queue_message(op, msg);
379 }
380 
381 void
382 zev_znode_link_cb(znode_t *dzp, znode_t *zp, dmu_tx_t *tx, char *name)
383 {
384 	int op = ZEV_OP_ZNODE_LINK;
385 	zev_znode_link_t *rec;
386 	zev_msg_t *msg = NULL;
387 	int msg_size;
388 	int name_len;
389 
390 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
391 		return;
392 	if (zev_skip_fs(zp->z_zfsvfs))
393 		return;
394 
395 	name_len = strlen(name);
396 	msg_size = sizeof(*rec) + name_len + 1;
397 	msg = zev_alloc(sizeof(*msg) + msg_size);
398 	msg->size = msg_size;
399 	rec = (zev_znode_link_t *)(msg + 1);
400 	rec->record_len = msg_size;
401 	rec->op = op;
402 	rec->op_time = ddi_get_time();
403 	rec->guid =
404 		dsl_dataset_phys(zp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
405 	rec->txg = tx->tx_txg;
406 	ZEV_FILL_INODE_INFO(parent, dzp);
407 	ZEV_FILL_INODE_INFO(file, zp);
408 	rec->name_len = name_len;
409 	(void) memcpy(ZEV_NAME(rec), name, name_len + 1);
410 	zev_queue_message(op, msg);
411 }
412 
413 void
414 zev_znode_symlink_cb(znode_t *dzp,
415                      znode_t *zp,
416                      dmu_tx_t *tx,
417                      char *name,
418                      char *link)
419 {
420 	int op = ZEV_OP_ZNODE_SYMLINK;
421 	zev_znode_symlink_t *rec;
422 	zev_msg_t *msg = NULL;
423 	int msg_size;
424 	int name_len;
425 	int link_len;
426 
427 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
428 		return;
429 	if (zev_skip_fs(zp->z_zfsvfs))
430 		return;
431 
432 	name_len = strlen(name);
433 	link_len = strlen(link);
434 	msg_size = sizeof(*rec) + name_len + 1 + link_len + 1;
435 	msg = zev_alloc(sizeof(*msg) + msg_size);
436 	msg->size = msg_size;
437 	rec = (zev_znode_symlink_t *)(msg + 1);
438 	rec->record_len = msg_size;
439 	rec->op = op;
440 	rec->op_time = ddi_get_time();
441 	rec->guid =
442 		dsl_dataset_phys(dzp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
443 	rec->txg = tx->tx_txg;
444 	ZEV_FILL_INODE_INFO(parent, dzp);
445 	ZEV_FILL_INODE_INFO(file, zp);
446 	rec->name_len = name_len;
447 	rec->link_len = link_len;
448 	(void) memcpy(ZEV_NAME(rec), name, name_len + 1);
449 	(void) memcpy(ZEV_LINK(rec), link, link_len + 1);
450 	zev_symlink_checksum(rec, link);
451 	zev_queue_message(op, msg);
452 }
453 
454 void
455 zev_znode_rename_cb(znode_t *sdzp,
456                     char *sname,
457                     znode_t *tdzp,
458                     char *tname,
459                     znode_t *szp,
460                     znode_t *tzp,
461                     dmu_tx_t *tx)
462 {
463 	int op = ZEV_OP_ZNODE_RENAME;
464 	zev_znode_rename_t *rec;
465 	zev_msg_t *msg = NULL;
466 	int msg_size;
467 	int srcname_len;
468 	int dstname_len;
469 
470 	if (zev_skip_pool(szp->z_zfsvfs->z_os))
471 		return;
472 	if (zev_skip_fs(szp->z_zfsvfs))
473 		return;
474 
475 	srcname_len = strlen(sname);
476 	dstname_len = strlen(tname);
477 	msg_size = sizeof(*rec) + srcname_len + 1 + dstname_len + 1;
478 	msg = zev_alloc(sizeof(*msg) + msg_size);
479 	msg->size = msg_size;
480 	rec = (zev_znode_rename_t *)(msg + 1);
481 	rec->record_len = msg_size;
482 	rec->op = op;
483 	rec->op_time = ddi_get_time();
484 	rec->guid =
485 		dsl_dataset_phys(szp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
486 	rec->txg = tx->tx_txg;
487 	ZEV_FILL_INODE_INFO(srcdir, sdzp);
488 	ZEV_FILL_INODE_INFO(dstdir, tdzp);
489 	ZEV_FILL_INODE_INFO(file, szp);
490 	if (tzp) {
491 		ZEV_FILL_INODE_INFO(clobbered_file, tzp);
492 	} else {
493 		memset(&rec->clobbered_file, 0, sizeof(rec->clobbered_file));
494 	}
495 	rec->srcname_len = srcname_len;
496 	rec->dstname_len = dstname_len;
497 	(void) memcpy(ZEV_SRCNAME(rec), sname, srcname_len + 1);
498 	(void) memcpy(ZEV_DSTNAME(rec), tname, dstname_len + 1);
499 	zev_queue_message(op, msg);
500 }
501 
502 void
503 zev_znode_write_cb(znode_t *zp, dmu_tx_t *tx, uint64_t off, uint64_t len)
504 {
505 	int op = ZEV_OP_ZNODE_WRITE;
506 	zev_znode_write_t *rec;
507 	zev_msg_t *msg = NULL;
508 	int msg_size;
509 	zev_sig_t *sig_buf;
510 	uint64_t sig_buf_len;
511 	uint64_t sig_len;
512 	uint64_t sig_cnt;
513 	int ret;
514 
515 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
516 		return;
517 	if (zev_skip_fs(zp->z_zfsvfs))
518 		return;
519 
520 	ret = zev_get_checksums(&sig_buf, &sig_buf_len, &sig_cnt, 0,
521 	                        zp, off, len, zev_write);
522 	if (ret) {
523 		zev_queue_error(op,
524 		    "ERROR: ZNODE_WRITE: can't get checksum (inode=%d:%d)\n",
525 		    zp->z_gen,
526 		    zp->z_id);
527 		return;
528 	}
529 	sig_len = sig_cnt * sizeof(zev_sig_t);
530 
531 	msg_size = sizeof(*rec) + sig_len;
532 	msg = zev_alloc(sizeof(*msg) + msg_size);
533 	msg->size = msg_size;
534 	rec = (zev_znode_write_t *)(msg + 1);
535 	rec->record_len = msg_size;
536 	rec->op = op;
537 	rec->op_time = ddi_get_time();
538 	rec->guid =
539 		dsl_dataset_phys(zp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
540 	rec->txg = tx->tx_txg;
541 	ZEV_FILL_INODE_INFO(file, zp);
542 	rec->offset = off;
543 	rec->length = len;
544 	rec->signature_cnt = sig_cnt;
545 	if (sig_cnt && sig_buf)
546 		memcpy(ZEV_SIGNATURES(rec), sig_buf, sig_len);
547 	if (sig_buf)
548 		zev_free(sig_buf, sig_buf_len);
549 	zev_queue_message(op, msg);
550 }
551 
552 void
553 zev_znode_truncate_cb(znode_t *zp, dmu_tx_t *tx, uint64_t off, uint64_t len)
554 {
555 	int op = ZEV_OP_ZNODE_TRUNCATE;
556 	zev_znode_truncate_t *rec;
557 	zev_msg_t *msg = NULL;
558 	int msg_size;
559 	zev_sig_t *sig_buf;
560 	uint64_t sig_buf_len;
561 	uint64_t sig_len;
562 	uint64_t sig_cnt;
563 	int ret;
564 
565 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
566 		return;
567 	if (zev_skip_fs(zp->z_zfsvfs))
568 		return;
569 
570 	ret = zev_get_checksums(&sig_buf, &sig_buf_len, &sig_cnt, 0,
571 	                        zp, off, len, zev_truncate);
572 	if (ret) {
573 		zev_queue_error(op,
574 		    "ERROR: ZNODE_TRUNCATE: can't get checksum (inode=%d:%d)\n",
575 		    zp->z_gen,
576 		    zp->z_id);
577 		return;
578 	}
579 	sig_len = sig_cnt * sizeof(zev_sig_t);
580 
581 	msg_size = sizeof(*rec) + sig_len;
582 	msg = zev_alloc(sizeof(*msg) + msg_size);
583 	msg->size = msg_size;
584 	rec = (zev_znode_truncate_t *)(msg + 1);
585 	rec->record_len = msg_size;
586 	rec->op = op;
587 	rec->op_time = ddi_get_time();
588 	rec->guid =
589 		dsl_dataset_phys(zp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
590 	rec->txg = tx->tx_txg;
591 	ZEV_FILL_INODE_INFO(file, zp);
592 	rec->offset = off;
593 	rec->length = len;
594 	rec->signature_cnt = sig_cnt;
595 	if (sig_cnt && sig_buf)
596 		memcpy(ZEV_SIGNATURES(rec), sig_buf, sig_len);
597 	if (sig_buf)
598 		zev_free(sig_buf, sig_buf_len);
599 	zev_queue_message(op, msg);
600 }
601 
602 void
603 zev_znode_setattr_cb(znode_t *zp, dmu_tx_t *tx)
604 {
605 	int op = ZEV_OP_ZNODE_SETATTR;
606 	zev_znode_setattr_t *rec;
607 	zev_msg_t *msg = NULL;
608 	int msg_size;
609 
610 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
611 		return;
612 	if (zev_skip_fs(zp->z_zfsvfs))
613 		return;
614 
615 	msg_size = sizeof(*rec);
616 	msg = zev_alloc(sizeof(*msg) + msg_size);
617 	msg->size = msg_size;
618 	rec = (zev_znode_setattr_t *)(msg + 1);
619 	rec->record_len = msg_size;
620 	rec->op = op;
621 	rec->op_time = ddi_get_time();
622 	rec->guid =
623 		dsl_dataset_phys(zp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
624 	rec->txg = tx->tx_txg;
625 	ZEV_FILL_INODE_INFO(file, zp);
626 	zev_queue_message(op, msg);
627 }
628 
629 void
630 zev_znode_acl_cb(znode_t *zp, dmu_tx_t *tx)
631 {
632 	int op = ZEV_OP_ZNODE_ACL;
633 	zev_znode_acl_t *rec;
634 	zev_msg_t *msg = NULL;
635 	int msg_size;
636 
637 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
638 		return;
639 	if (zev_skip_fs(zp->z_zfsvfs))
640 		return;
641 
642 	msg_size = sizeof(*rec);
643 	msg = zev_alloc(sizeof(*msg) + msg_size);
644 	msg->size = msg_size;
645 	rec = (zev_znode_acl_t *)(msg + 1);
646 	rec->record_len = msg_size;
647 	rec->op = op;
648 	rec->op_time = ddi_get_time();
649 	rec->guid =
650 		dsl_dataset_phys(zp->z_zfsvfs->z_os->os_dsl_dataset)->ds_guid;
651 	rec->txg = tx->tx_txg;
652 	ZEV_FILL_INODE_INFO(file, zp);
653 	zev_queue_message(op, msg);
654 }
655 
656 rz_zev_callbacks_t zev_callbacks = {
657 	/* zfsvfs events */
658 	.rz_zev_zfs_mount                = zev_zfs_mount_cb,
659 	.rz_zev_zfs_umount               = zev_zfs_umount_cb,
660 
661 	/* zvol zil events */
662 	.rz_zev_zvol_truncate            = zev_zvol_truncate_cb,
663 	.rz_zev_zvol_write               = zev_zvol_write_cb,
664 
665 	/* znode zil events */
666 	.rz_zev_znode_close_after_update = zev_znode_close_after_update_cb,
667 	.rz_zev_znode_create             = zev_znode_create_cb,
668 	.rz_zev_znode_remove             = zev_znode_remove_cb,
669 	.rz_zev_znode_link               = zev_znode_link_cb,
670 	.rz_zev_znode_symlink            = zev_znode_symlink_cb,
671 	.rz_zev_znode_rename             = zev_znode_rename_cb,
672 	.rz_zev_znode_write              = zev_znode_write_cb,
673 	.rz_zev_znode_truncate           = zev_znode_truncate_cb,
674 	.rz_zev_znode_setattr            = zev_znode_setattr_cb,
675 	.rz_zev_znode_acl                = zev_znode_acl_cb,
676 };
677 
678