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