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 /* 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
zev_zfs_umount_cb(vfs_t * vfs)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
zev_zvol_truncate_cb(char * dataset,objset_t * os,dmu_tx_t * tx,uint64_t off,uint64_t len)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
zev_zvol_write_cb(char * dataset,objset_t * os,dmu_tx_t * tx,uint64_t off,uint64_t len)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
zev_znode_close_after_update_cb(znode_t * zp)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
zev_znode_create_cb(znode_t * dzp,znode_t * zp,dmu_tx_t * tx,char * name,uint64_t txtype)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
zev_znode_remove_cb(znode_t * dzp,znode_t * zp,dmu_tx_t * tx,char * name,uint64_t txtype)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
zev_znode_link_cb(znode_t * dzp,znode_t * zp,dmu_tx_t * tx,char * name)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
zev_znode_symlink_cb(znode_t * dzp,znode_t * zp,dmu_tx_t * tx,char * name,char * link)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
zev_znode_rename_cb(znode_t * sdzp,char * sname,znode_t * tdzp,char * tname,znode_t * szp,znode_t * tzp,dmu_tx_t * tx)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
zev_znode_write_cb(znode_t * zp,dmu_tx_t * tx,uint64_t off,uint64_t len)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
zev_znode_truncate_cb(znode_t * zp,dmu_tx_t * tx,uint64_t off,uint64_t len)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
zev_znode_setattr_cb(znode_t * zp,dmu_tx_t * tx)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
zev_znode_acl_cb(znode_t * zp,dmu_tx_t * tx)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