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