xref: /titanic_54/usr/src/uts/common/fs/zev/zev_callbacks.c (revision f66561e7b6add9048a3eaf092bac3de20dc79084)
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 
7 #define ZEV_FILL_INODE_INFO(name, znode)				\
8 	do {								\
9 		uint64_t mtime[2], ctime[2];				\
10 		sa_bulk_attr_t bulk[2];					\
11 		int count = 0;						\
12 		timestruc_t mtime_s, ctime_s;				\
13 		SA_ADD_BULK_ATTR(bulk, count,				\
14 			         SA_ZPL_MTIME(znode->z_zfsvfs),		\
15 		                 NULL, &mtime, 16);			\
16 		SA_ADD_BULK_ATTR(bulk, count,				\
17 			         SA_ZPL_CTIME(znode->z_zfsvfs),		\
18 		                 NULL, &ctime, 16);			\
19 		if ((sa_bulk_lookup(znode->z_sa_hdl, bulk, count)) != 0) { \
20 			zev_queue_error(op, "znode write: "		\
21 			                "mtime/ctime unavailable");	\
22 			/* continue anyway, use fake data */		\
23 			mtime_s.tv_sec = ctime_s.tv_sec = 0;		\
24 		}							\
25 		ZFS_TIME_DECODE(&mtime_s, mtime);			\
26 		ZFS_TIME_DECODE(&ctime_s, ctime);			\
27 		rec->name.ino = znode->z_id;				\
28 		rec->name.gen = znode->z_gen;				\
29 		rec->name.mtime = mtime_s.tv_sec;			\
30 		rec->name.ctime = ctime_s.tv_sec;			\
31 		rec->name.size = znode->z_size;				\
32 		rec->name.type = znode->z_vnode->v_type;		\
33 		rec->name.mode =					\
34 			znode->z_mode | VTTOIF(znode->z_vnode->v_type);	\
35 		rec->name.links = znode->z_links;			\
36 		rec->name.flags = znode->z_pflags & ZFS_XATTR ?		\
37 			ZEV_FL_XATTR : 0;				\
38 	} while(0)
39 
40 void
41 zev_zfs_mount_cb(vfs_t *vfs, vnode_t *mpt, char *dataset, boolean_t remount)
42 {
43 	int op = ZEV_OP_ZFS_MOUNT;
44 	char mountpoint[MAXPATHLEN+1];
45 	int mountpoint_len;
46 	int dataset_len;
47 	zev_zfs_mount_t *rec;
48 	zev_msg_t *msg = NULL;
49 	int msg_size;
50 	znode_t *zp_root;
51 
52 	zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data;
53 	if (dsl_dataset_is_snapshot(zfsvfs->z_os->os_dsl_dataset))
54 		return;
55 	if (zev_skip_pool(zfsvfs->z_os))
56 		return;
57 	/* expensive, but we don't have many mount ops. */
58 	if ((vnodetopath(NULL, mpt, mountpoint, sizeof(mountpoint),
59 	    kcred)) != 0) {
60 		zev_queue_error(op, "unresolvable mountpoint, dataset=%s",
61 		                dataset);
62 		return;
63 	}
64 	if (zfs_zget(zfsvfs, zfsvfs->z_root, &zp_root) != 0) {
65 		zev_queue_error(op, "can't get root znode, dataset=%s",
66 		                dataset);
67 		return;
68 	}
69 
70 	dataset_len = strlen(dataset);
71 	mountpoint_len = strlen(mountpoint);
72 	msg_size = sizeof(*rec) + dataset_len + 1 + mountpoint_len + 1;
73 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
74 	msg->size = msg_size;
75 	rec = (zev_zfs_mount_t *)(msg + 1);
76 	rec->record_len = msg_size;
77 	rec->op = op;
78 	rec->op_time = ddi_get_time();
79 	rec->guid = zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
80 	rec->remount = remount;
81 	rec->dataset_len = dataset_len;
82 	rec->mountpoint_len = mountpoint_len;
83 	ZEV_FILL_INODE_INFO(root, zp_root);
84 	VN_RELE(ZTOV(zp_root));
85 	(void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1);
86 	(void) memcpy(ZEV_MOUNTPOINT(rec), mountpoint, mountpoint_len + 1);
87 	zev_queue_message(op, msg);
88 }
89 
90 void
91 zev_zfs_umount_cb(vfs_t *vfs)
92 {
93 	int op = ZEV_OP_ZFS_UMOUNT;
94 	zev_zfs_umount_t *rec;
95 	zev_msg_t *msg = NULL;
96 	int msg_size;
97 
98 	zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data;
99 	if (dsl_dataset_is_snapshot(zfsvfs->z_os->os_dsl_dataset))
100 		return;
101 	if (zev_skip_pool(zfsvfs->z_os))
102 		return;
103 
104 	msg_size = sizeof(*rec);
105 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
106 	msg->size = msg_size;
107 	rec = (zev_zfs_umount_t *)(msg + 1);
108 	rec->record_len = msg_size;
109 	rec->op = op;
110 	rec->op_time = ddi_get_time();
111 	rec->guid = zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
112 	zev_queue_message(op, msg);
113 }
114 
115 void
116 zev_zvol_truncate_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len)
117 {
118 	int op = ZEV_OP_ZVOL_TRUNCATE;
119 	zev_zvol_truncate_t *rec;
120 	zev_msg_t *msg = NULL;
121 	int msg_size;
122 	int dataset_len;
123 
124 	if (zev_skip_pool(os))
125 		return;
126 
127 	dataset_len = strlen(dataset);
128 	msg_size = sizeof(*rec) + dataset_len + 1;
129 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
130 	msg->size = msg_size;
131 	rec = (zev_zvol_truncate_t *)(msg + 1);
132 	rec->record_len = msg_size;
133 	rec->op = op;
134 	rec->op_time = ddi_get_time();
135 	rec->guid = os->os_dsl_dataset->ds_phys->ds_guid;
136 	rec->offset = off;
137 	rec->length = len;
138 	rec->dataset_len = dataset_len;
139 	(void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1);
140 	zev_queue_message(op, msg);
141 }
142 
143 void
144 zev_zvol_write_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len)
145 {
146 	int op = ZEV_OP_ZVOL_WRITE;
147 	zev_zvol_write_t *rec;
148 	zev_msg_t *msg = NULL;
149 	int msg_size;
150 	int dataset_len;
151 
152 	if (zev_skip_pool(os))
153 		return;
154 
155 	dataset_len = strlen(dataset);
156 	msg_size = sizeof(*rec) + dataset_len + 1;
157 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
158 	msg->size = msg_size;
159 	rec = (zev_zvol_write_t *)(msg + 1);
160 	rec->record_len = msg_size;
161 	rec->op = op;
162 	rec->op_time = ddi_get_time();
163 	rec->guid = os->os_dsl_dataset->ds_phys->ds_guid;
164 	rec->offset = off;
165 	rec->length = len;
166 	rec->dataset_len = dataset_len;
167 	(void) memcpy(ZEV_DATASET(rec), dataset, dataset_len + 1);
168 	zev_queue_message(op, msg);
169 }
170 
171 void
172 zev_znode_close_after_update_cb(znode_t *zp)
173 {
174 	int op = ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE;
175 	zev_znode_close_after_update_t *rec;
176 	zev_msg_t *msg = NULL;
177 	int msg_size;
178 
179 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
180 		return;
181 
182 	msg_size = sizeof(*rec);
183 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
184 	msg->size = msg_size;
185 	rec = (zev_znode_close_after_update_t *)(msg + 1);
186 	rec->record_len = msg_size;
187 	rec->op = op;
188 	rec->op_time = ddi_get_time();
189 	rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
190 	ZEV_FILL_INODE_INFO(file, zp);
191 	zev_queue_message(op, msg);
192 }
193 
194 void
195 zev_znode_create_cb(znode_t *dzp, znode_t *zp, char *name, uint64_t txtype)
196 {
197 	int op = ZEV_OP_ZNODE_CREATE;
198 	zev_znode_create_t *rec;
199 	zev_msg_t *msg = NULL;
200 	int msg_size;
201 	int name_len;
202 
203 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
204 		return;
205 
206 	int type = (int)txtype;
207 	switch(type) {
208 	case TX_CREATE:
209 	case TX_CREATE_ACL:
210 	case TX_CREATE_ATTR:
211 	case TX_CREATE_ACL_ATTR:
212 		op = ZEV_OP_ZNODE_CREATE;
213 		break;
214 	case TX_MKDIR:
215 	case TX_MKDIR_ACL:
216 	case TX_MKDIR_ATTR:
217 	case TX_MKDIR_ACL_ATTR:
218 		op = ZEV_OP_ZNODE_MKDIR;
219 		break;
220 	case TX_MKXATTR:
221 		op = ZEV_OP_ZNODE_MAKE_XATTR_DIR;
222 		break;
223 	default:
224 		zev_queue_error(ZEV_OP_ZNODE_CREATE,
225 		    "ERROR: ZNODE_CREATE: unknown txtype %d "
226 		    "(dir_inode=%d:%d inode=%d:%d name='%s')\n",
227 		    type,
228 		    dzp->z_gen,
229 		    dzp->z_id,
230 		    zp->z_gen,
231 		    zp->z_id,
232 		    name);
233 		return;
234 	}
235 
236 	/* all three types use the same struct, so this works for all types: */
237 	name_len = strlen(name);
238 	msg_size = sizeof(*rec) + name_len + 1;
239 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
240 	msg->size = msg_size;
241 	rec = (zev_znode_create_t *)(msg + 1);
242 	rec->record_len = msg_size;
243 	rec->op = op;
244 	rec->op_time = ddi_get_time();
245 	rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
246 	ZEV_FILL_INODE_INFO(parent, dzp);
247 	ZEV_FILL_INODE_INFO(file, zp);
248 	rec->name_len = name_len;
249 	(void) memcpy(ZEV_NAME(rec), name, name_len + 1);
250 	zev_queue_message(op, msg);
251 }
252 
253 void
254 zev_znode_remove_cb(znode_t *dzp, znode_t *zp, char *name, uint64_t txtype)
255 {
256 	int op = ZEV_OP_ZNODE_REMOVE;
257 	zev_znode_remove_t *rec;
258 	zev_msg_t *msg = NULL;
259 	int msg_size;
260 	int name_len;
261 
262 	if (zev_skip_pool(dzp->z_zfsvfs->z_os))
263 		return;
264 
265 	int type = (int)txtype;
266 	switch(type) {
267 	case TX_REMOVE:
268 		op = ZEV_OP_ZNODE_REMOVE;
269 		break;
270 	case TX_RMDIR:
271 		op = ZEV_OP_ZNODE_RMDIR;
272 		break;
273 	default:
274 		zev_queue_error(ZEV_OP_ZNODE_REMOVE,
275 		    "ERROR: ZNODE_REMOVE: unknown txtype %d "
276 		    "(dir_inode=%d:%d name='%s')\n",
277 		    type,
278 		    dzp->z_gen,
279 		    dzp->z_id,
280 		    name);
281 		return;
282 	}
283 
284 	/* both types use the same struct, so this works for all types: */
285 	name_len = strlen(name);
286 	msg_size = sizeof(*rec) + name_len + 1;
287 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
288 	msg->size = msg_size;
289 	rec = (zev_znode_remove_t *)(msg + 1);
290 	rec->record_len = msg_size;
291 	rec->op = op;
292 	rec->op_time = ddi_get_time();
293 	rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
294 	ZEV_FILL_INODE_INFO(file, zp);
295 	ZEV_FILL_INODE_INFO(parent, dzp);
296 	rec->name_len = name_len;
297 	(void) memcpy(ZEV_NAME(rec), name, name_len + 1);
298 	zev_queue_message(op, msg);
299 }
300 
301 void
302 zev_znode_link_cb(znode_t *dzp, znode_t *zp, char *name)
303 {
304 	int op = ZEV_OP_ZNODE_LINK;
305 	zev_znode_link_t *rec;
306 	zev_msg_t *msg = NULL;
307 	int msg_size;
308 	int name_len;
309 
310 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
311 		return;
312 
313 	name_len = strlen(name);
314 	msg_size = sizeof(*rec) + name_len + 1;
315 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
316 	msg->size = msg_size;
317 	rec = (zev_znode_link_t *)(msg + 1);
318 	rec->record_len = msg_size;
319 	rec->op = op;
320 	rec->op_time = ddi_get_time();
321 	rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
322 	ZEV_FILL_INODE_INFO(parent, dzp);
323 	ZEV_FILL_INODE_INFO(file, zp);
324 	rec->name_len = name_len;
325 	(void) memcpy(ZEV_NAME(rec), name, name_len + 1);
326 	zev_queue_message(op, msg);
327 }
328 
329 void
330 zev_znode_symlink_cb(znode_t *dzp, znode_t *zp, char *name, char *link)
331 {
332 	int op = ZEV_OP_ZNODE_SYMLINK;
333 	zev_znode_symlink_t *rec;
334 	zev_msg_t *msg = NULL;
335 	int msg_size;
336 	int name_len;
337 	int link_len;
338 
339 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
340 		return;
341 
342 	name_len = strlen(name);
343 	link_len = strlen(link);
344 	msg_size = sizeof(*rec) + name_len + 1 + link_len + 1;
345 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
346 	msg->size = msg_size;
347 	rec = (zev_znode_symlink_t *)(msg + 1);
348 	rec->record_len = msg_size;
349 	rec->op = op;
350 	rec->op_time = ddi_get_time();
351 	rec->guid = dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
352 	ZEV_FILL_INODE_INFO(parent, dzp);
353 	ZEV_FILL_INODE_INFO(file, zp);
354 	rec->name_len = name_len;
355 	rec->link_len = link_len;
356 	(void) memcpy(ZEV_NAME(rec), name, name_len + 1);
357 	(void) memcpy(ZEV_LINK(rec), link, link_len + 1);
358 	zev_queue_message(op, msg);
359 }
360 
361 void
362 zev_znode_rename_cb(znode_t *sdzp, char *sname, znode_t *tdzp,
363     char *tname, znode_t *szp)
364 {
365 	int op = ZEV_OP_ZNODE_RENAME;
366 	zev_znode_rename_t *rec;
367 	zev_msg_t *msg = NULL;
368 	int msg_size;
369 	int srcname_len;
370 	int dstname_len;
371 
372 	if (zev_skip_pool(szp->z_zfsvfs->z_os))
373 		return;
374 
375 	srcname_len = strlen(sname);
376 	dstname_len = strlen(tname);
377 	msg_size = sizeof(*rec) + srcname_len + 1 + dstname_len + 1;
378 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
379 	msg->size = msg_size;
380 	rec = (zev_znode_rename_t *)(msg + 1);
381 	rec->record_len = msg_size;
382 	rec->op = op;
383 	rec->op_time = ddi_get_time();
384 	rec->guid = szp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
385 	ZEV_FILL_INODE_INFO(srcdir, sdzp);
386 	ZEV_FILL_INODE_INFO(dstdir, tdzp);
387 	ZEV_FILL_INODE_INFO(file, szp);
388 	rec->srcname_len = srcname_len;
389 	rec->dstname_len = dstname_len;
390 	(void) memcpy(ZEV_SRCNAME(rec), sname, srcname_len + 1);
391 	(void) memcpy(ZEV_DSTNAME(rec), tname, dstname_len + 1);
392 	zev_queue_message(op, msg);
393 }
394 
395 void
396 zev_znode_write_cb(znode_t *zp, uint64_t off, uint64_t len)
397 {
398 	int op = ZEV_OP_ZNODE_WRITE;
399 	zev_znode_write_t *rec;
400 	zev_msg_t *msg = NULL;
401 	int msg_size;
402 
403 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
404 		return;
405 
406 	msg_size = sizeof(*rec);
407 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
408 	msg->size = msg_size;
409 	rec = (zev_znode_write_t *)(msg + 1);
410 	rec->record_len = msg_size;
411 	rec->op = op;
412 	rec->op_time = ddi_get_time();
413 	rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
414 	ZEV_FILL_INODE_INFO(file, zp);
415 	rec->offset = off;
416 	rec->length = len;
417 	zev_queue_message(op, msg);
418 }
419 
420 void
421 zev_znode_truncate_cb(znode_t *zp, uint64_t off, uint64_t len)
422 {
423 	int op = ZEV_OP_ZNODE_TRUNCATE;
424 	zev_znode_truncate_t *rec;
425 	zev_msg_t *msg = NULL;
426 	int msg_size;
427 
428 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
429 		return;
430 
431 	msg_size = sizeof(*rec);
432 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
433 	msg->size = msg_size;
434 	rec = (zev_znode_truncate_t *)(msg + 1);
435 	rec->record_len = msg_size;
436 	rec->op = op;
437 	rec->op_time = ddi_get_time();
438 	rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
439 	ZEV_FILL_INODE_INFO(file, zp);
440 	rec->offset = off;
441 	rec->length = len;
442 	zev_queue_message(op, msg);
443 }
444 
445 void
446 zev_znode_setattr_cb(znode_t *zp)
447 {
448 	int op = ZEV_OP_ZNODE_SETATTR;
449 	zev_znode_setattr_t *rec;
450 	zev_msg_t *msg = NULL;
451 	int msg_size;
452 
453 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
454 		return;
455 
456 	msg_size = sizeof(*rec);
457 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
458 	msg->size = msg_size;
459 	rec = (zev_znode_setattr_t *)(msg + 1);
460 	rec->record_len = msg_size;
461 	rec->op = op;
462 	rec->op_time = ddi_get_time();
463 	rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
464 	ZEV_FILL_INODE_INFO(file, zp);
465 	zev_queue_message(op, msg);
466 }
467 
468 void
469 zev_znode_acl_cb(znode_t *zp)
470 {
471 	int op = ZEV_OP_ZNODE_ACL;
472 	zev_znode_acl_t *rec;
473 	zev_msg_t *msg = NULL;
474 	int msg_size;
475 
476 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
477 		return;
478 
479 	msg_size = sizeof(*rec);
480 	msg = ZEV_ALLOC(sizeof(*msg) + msg_size);
481 	msg->size = msg_size;
482 	rec = (zev_znode_acl_t *)(msg + 1);
483 	rec->record_len = msg_size;
484 	rec->op = op;
485 	rec->op_time = ddi_get_time();
486 	rec->guid = zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid;
487 	ZEV_FILL_INODE_INFO(file, zp);
488 	zev_queue_message(op, msg);
489 }
490 
491 rz_zev_callbacks_t zev_callbacks = {
492 	/* zfsvfs events */
493 	.rz_zev_zfs_mount                = zev_zfs_mount_cb,
494 	.rz_zev_zfs_umount               = zev_zfs_umount_cb,
495 
496 	/* zvol zil events */
497 	.rz_zev_zvol_truncate            = zev_zvol_truncate_cb,
498 	.rz_zev_zvol_write               = zev_zvol_write_cb,
499 
500 	/* znode zil events */
501 	.rz_zev_znode_close_after_update = zev_znode_close_after_update_cb,
502 	.rz_zev_znode_create             = zev_znode_create_cb,
503 	.rz_zev_znode_remove             = zev_znode_remove_cb,
504 	.rz_zev_znode_link               = zev_znode_link_cb,
505 	.rz_zev_znode_symlink            = zev_znode_symlink_cb,
506 	.rz_zev_znode_rename             = zev_znode_rename_cb,
507 	.rz_zev_znode_write              = zev_znode_write_cb,
508 	.rz_zev_znode_truncate           = zev_znode_truncate_cb,
509 	.rz_zev_znode_setattr            = zev_znode_setattr_cb,
510 	.rz_zev_znode_acl                = zev_znode_acl_cb,
511 };
512 
513