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