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