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