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