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