xref: /titanic_52/usr/src/uts/common/fs/zev/zev_callbacks.c (revision 9193e9c2f160bcdc30e75eef8df0635e63f514a1)
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_VERIFY(exp)							\
7 	if (0 != (exp)) {						\
8 		zev_queue_error(op, "operation failed: "		\
9 		                #exp " (line %d in %s)",		\
10 		                __LINE__, __FILE__);			\
11 		if (nvl) {						\
12 			nvlist_free(nvl);				\
13 		}							\
14 		return;							\
15 	}
16 
17 #define ZEV_ADD_INODE_INFO(znode, name)				\
18 	do {								\
19 		uint64_t mtime[2], ctime[2];				\
20 		sa_bulk_attr_t bulk[2];					\
21 		int count = 0;						\
22 		timestruc_t mtime_s, ctime_s;				\
23 		SA_ADD_BULK_ATTR(bulk, count,				\
24 			         SA_ZPL_MTIME(znode->z_zfsvfs),		\
25 		                 NULL, &mtime, 16);			\
26 		SA_ADD_BULK_ATTR(bulk, count,				\
27 			         SA_ZPL_CTIME(znode->z_zfsvfs),		\
28 		                 NULL, &ctime, 16);			\
29 		if ((sa_bulk_lookup(znode->z_sa_hdl, bulk, count)) != 0) { \
30 			zev_queue_error(op, "znode write: "		\
31 			                "mtime/ctime unavailable");	\
32 			/* continue anyway, use fake data */		\
33 			mtime_s.tv_sec = ctime_s.tv_sec = 0;		\
34 		}							\
35 		ZFS_TIME_DECODE(&mtime_s, mtime);			\
36 		ZFS_TIME_DECODE(&ctime_s, ctime);			\
37 		ZEV_VERIFY(nvlist_add_uint64(nvl, name ".ino",		\
38 		           znode->z_id));				\
39 		ZEV_VERIFY(nvlist_add_uint64(nvl, name ".gen",		\
40 		           znode->z_gen));				\
41 		ZEV_VERIFY(nvlist_add_uint64(nvl, name ".mtime",	\
42 		           mtime_s.tv_sec));				\
43 		ZEV_VERIFY(nvlist_add_uint64(nvl, name ".ctime",	\
44 		           ctime_s.tv_sec));				\
45 		ZEV_VERIFY(nvlist_add_uint64(nvl, name ".size",	\
46 		           znode->z_size));				\
47 		ZEV_VERIFY(nvlist_add_uint64(nvl, name ".mode",	\
48 		           znode->z_mode & MODEMASK));			\
49 		ZEV_VERIFY(nvlist_add_int32(nvl, name ".type",		\
50 		           znode->z_vnode->v_type));			\
51 		ZEV_VERIFY(nvlist_add_uint64(nvl, name ".links",	\
52 		           znode->z_links));				\
53 	} while(0);							\
54 
55 void
56 zev_zfs_mount_cb(vfs_t *vfs, vnode_t *mpt, char *dataset, boolean_t remount)
57 {
58 	nvlist_t *nvl = NULL;
59 	int op = ZEV_OP_ZFS_MOUNT;
60 	char mountpoint[MAXPATHLEN+1];
61 
62 	zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data;
63 	if (zev_skip_pool(zfsvfs->z_os))
64 		return;
65 	/* expensive, but we don't have many mount ops. */
66 	if ((vnodetopath(NULL, mpt, mountpoint, sizeof(mountpoint),
67 	    kcred)) != 0) {
68 		zev_queue_error(ZEV_OP_ZFS_MOUNT,
69 		                "unresolvable mountpoint, dataset=%s", dataset);
70 		return;
71 	}
72 
73 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
74 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
75 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
76 	           zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
77 	ZEV_VERIFY(nvlist_add_string(nvl, "dataset", dataset));
78 	ZEV_VERIFY(nvlist_add_string(nvl, "mountpoint", dataset));
79 	ZEV_VERIFY(nvlist_add_uint64(nvl, "root.ino", zfsvfs->z_root));
80 	ZEV_VERIFY(nvlist_add_boolean_value(nvl, "remount", remount));
81 	zev_queue_message(op, nvl);
82 	nvlist_free(nvl);
83 }
84 
85 void
86 zev_zfs_umount_cb(vfs_t *vfs)
87 {
88 	nvlist_t *nvl = NULL;
89 	int op = ZEV_OP_ZFS_UMOUNT;
90 
91 	zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data;
92 	if (zev_skip_pool(zfsvfs->z_os))
93 		return;
94 
95 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
96 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
97 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
98 	           zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
99 	zev_queue_message(op, nvl);
100 	nvlist_free(nvl);
101 }
102 
103 void
104 zev_zvol_truncate_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len)
105 {
106 	nvlist_t *nvl = NULL;
107 	int op = ZEV_OP_ZVOL_TRUNCATE;
108 
109 	if (zev_skip_pool(os))
110 		return;
111 
112 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
113 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
114 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
115 	           os->os_dsl_dataset->ds_phys->ds_guid));
116 	ZEV_VERIFY(nvlist_add_string(nvl, "dataset", dataset));
117 	ZEV_VERIFY(nvlist_add_uint64(nvl, "offset", off));
118 	ZEV_VERIFY(nvlist_add_uint64(nvl, "length", len));
119 	zev_queue_message(op, nvl);
120 	nvlist_free(nvl);
121 }
122 
123 void
124 zev_zvol_write_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len)
125 {
126 	nvlist_t *nvl = NULL;
127 	int op = ZEV_OP_ZVOL_WRITE;
128 
129 	if (zev_skip_pool(os))
130 		return;
131 
132 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
133 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
134 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
135 	           os->os_dsl_dataset->ds_phys->ds_guid));
136 	ZEV_VERIFY(nvlist_add_string(nvl, "dataset", dataset));
137 	ZEV_VERIFY(nvlist_add_uint64(nvl, "offset", off));
138 	ZEV_VERIFY(nvlist_add_uint64(nvl, "length", len));
139 	zev_queue_message(op, nvl);
140 	nvlist_free(nvl);
141 }
142 
143 void
144 zev_znode_close_after_update_cb(znode_t *zp)
145 {
146 	nvlist_t *nvl = NULL;
147 	int op = ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE;
148 
149 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
150 		return;
151 
152 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
153 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
154 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
155 	           zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
156 	ZEV_ADD_INODE_INFO(zp, "file");
157 	zev_queue_message(op, nvl);
158 	nvlist_free(nvl);
159 }
160 
161 void
162 zev_znode_create_cb(znode_t *dzp, znode_t *zp, char *name, uint64_t txtype)
163 {
164 	nvlist_t *nvl = NULL;
165 	int op = ZEV_OP_ZNODE_CREATE;
166 
167 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
168 		return;
169 
170 	int type = (int)txtype;
171 	switch(type) {
172 	case TX_CREATE:
173 	case TX_CREATE_ACL:
174 	case TX_CREATE_ATTR:
175 	case TX_CREATE_ACL_ATTR:
176 		op = ZEV_OP_ZNODE_CREATE;
177 		break;
178 	case TX_MKDIR:
179 	case TX_MKDIR_ACL:
180 	case TX_MKDIR_ATTR:
181 	case TX_MKDIR_ACL_ATTR:
182 		op = ZEV_OP_ZNODE_MKDIR;
183 		break;
184 	case TX_MKXATTR:
185 		op = ZEV_OP_ZNODE_MAKE_XATTR_DIR;
186 		break;
187 	default:
188 		zev_queue_error(ZEV_OP_ZNODE_CREATE,
189 		    "ERROR: ZNODE_CREATE: unknown txtype %d "
190 		    "(dir_inode=%d:%d inode=%d:%d name='%s')\n",
191 		    type,
192 		    dzp->z_gen,
193 		    dzp->z_id,
194 		    zp->z_gen,
195 		    zp->z_id,
196 		    name);
197 		return;
198 	}
199 
200 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
201 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
202 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
203 	           zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
204 	ZEV_ADD_INODE_INFO(dzp, "parent");
205 	ZEV_ADD_INODE_INFO(zp, "file");
206 	ZEV_VERIFY(nvlist_add_string(nvl, "file.name", name));
207 	zev_queue_message(op, nvl);
208 	nvlist_free(nvl);
209 }
210 
211 void
212 zev_znode_remove_cb(znode_t *dzp, char *name, uint64_t txtype)
213 {
214 	nvlist_t *nvl = NULL;
215 	int op = ZEV_OP_ZNODE_REMOVE;
216 
217 	if (zev_skip_pool(dzp->z_zfsvfs->z_os))
218 		return;
219 
220 	int type = (int)txtype;
221 	switch(type) {
222 	case TX_REMOVE:
223 		op = ZEV_OP_ZNODE_REMOVE;
224 		break;
225 	case TX_RMDIR:
226 		op = ZEV_OP_ZNODE_RMDIR;
227 		break;
228 	default:
229 		zev_queue_error(ZEV_OP_ZNODE_REMOVE,
230 		    "ERROR: ZNODE_REMOVE: unknown txtype %d "
231 		    "(dir_inode=%d:%d name='%s')\n",
232 		    type,
233 		    dzp->z_gen,
234 		    dzp->z_id,
235 		    name);
236 		return;
237 	}
238 
239 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
240 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
241 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
242 	           dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
243 	ZEV_ADD_INODE_INFO(dzp, "parent");
244 	ZEV_VERIFY(nvlist_add_string(nvl, "file.name", name));
245 	zev_queue_message(op, nvl);
246 	nvlist_free(nvl);
247 }
248 
249 void
250 zev_znode_link_cb(znode_t *dzp, znode_t *zp, char *name)
251 {
252 	nvlist_t *nvl = NULL;
253 	int op = ZEV_OP_ZNODE_LINK;
254 
255 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
256 		return;
257 
258 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
259 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
260 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
261 	           zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
262 	ZEV_ADD_INODE_INFO(dzp, "parent");
263 	ZEV_ADD_INODE_INFO(zp, "file");
264 	ZEV_VERIFY(nvlist_add_string(nvl, "file.new_name", name));
265 	zev_queue_message(op, nvl);
266 	nvlist_free(nvl);
267 }
268 
269 void
270 zev_znode_symlink_cb(znode_t *dzp, znode_t *zp, char *name, char *link)
271 {
272 	nvlist_t *nvl = NULL;
273 	int op = ZEV_OP_ZNODE_SYMLINK;
274 
275 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
276 		return;
277 
278 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
279 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
280 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
281 	           zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
282 	ZEV_ADD_INODE_INFO(dzp, "parent");
283 	ZEV_ADD_INODE_INFO(zp, "file");
284 	ZEV_VERIFY(nvlist_add_string(nvl, "file.name", name));
285 	ZEV_VERIFY(nvlist_add_string(nvl, "file.link", link));
286 	zev_queue_message(op, nvl);
287 	nvlist_free(nvl);
288 }
289 
290 void
291 zev_znode_rename_cb(znode_t *sdzp, char *sname, znode_t *tdzp,
292     char *tname, znode_t *szp)
293 {
294 	nvlist_t *nvl = NULL;
295 	int op = ZEV_OP_ZNODE_RENAME;
296 
297 	if (zev_skip_pool(szp->z_zfsvfs->z_os))
298 		return;
299 
300 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
301 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
302 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
303 	           szp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
304 	ZEV_ADD_INODE_INFO(sdzp, "srcdir");
305 	ZEV_ADD_INODE_INFO(tdzp, "targetdir");
306 	ZEV_ADD_INODE_INFO(szp, "file");
307 	ZEV_VERIFY(nvlist_add_string(nvl, "file.src_name", sname));
308 	ZEV_VERIFY(nvlist_add_string(nvl, "file.target_name", tname));
309 	zev_queue_message(op, nvl);
310 }
311 
312 void
313 zev_znode_write_cb(znode_t *zp, uint64_t off, uint64_t len)
314 {
315 	nvlist_t *nvl = NULL;
316 	int op = ZEV_OP_ZNODE_WRITE;
317 
318 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
319 		return;
320 
321 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
322 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
323 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
324 	           zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
325 	ZEV_VERIFY(nvlist_add_uint64(nvl, "offset", off));
326 	ZEV_VERIFY(nvlist_add_uint64(nvl, "length", len));
327 	ZEV_ADD_INODE_INFO(zp, "file");
328 	zev_queue_message(op, nvl);
329 	nvlist_free(nvl);
330 }
331 
332 void
333 zev_znode_truncate_cb(znode_t *zp, uint64_t off, uint64_t len)
334 {
335 	nvlist_t *nvl = NULL;
336 	int op = ZEV_OP_ZNODE_TRUNCATE;
337 
338 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
339 		return;
340 
341 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
342 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
343 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
344 	           zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
345 	ZEV_VERIFY(nvlist_add_uint64(nvl, "offset", off));
346 	ZEV_VERIFY(nvlist_add_uint64(nvl, "length", len));
347 	ZEV_ADD_INODE_INFO(zp, "file");
348 	zev_queue_message(op, nvl);
349 	nvlist_free(nvl);
350 }
351 
352 void
353 zev_znode_setattr_cb(znode_t *zp)
354 {
355 	nvlist_t *nvl = NULL;
356 	int op = ZEV_OP_ZNODE_SETATTR;
357 
358 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
359 		return;
360 
361 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
362 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
363 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
364 	           zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
365 	ZEV_ADD_INODE_INFO(zp, "file");
366 	zev_queue_message(op, nvl);
367 	nvlist_free(nvl);
368 }
369 
370 void
371 zev_znode_acl_cb(znode_t *zp)
372 {
373 	nvlist_t *nvl = NULL;
374 	int op = ZEV_OP_ZNODE_ACL;
375 
376 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
377 		return;
378 
379 	ZEV_VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP));
380 	ZEV_VERIFY(nvlist_add_byte(nvl, "op", op));
381 	ZEV_VERIFY(nvlist_add_uint64(nvl, "guid",
382 	           zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid));
383 	ZEV_ADD_INODE_INFO(zp, "file");
384 	zev_queue_message(op, nvl);
385 	nvlist_free(nvl);
386 }
387 
388 rz_zev_callbacks_t zev_callbacks = {
389 	/* zfsvfs events */
390 	.rz_zev_zfs_mount                = zev_zfs_mount_cb,
391 	.rz_zev_zfs_umount               = zev_zfs_umount_cb,
392 
393 	/* zvol zil events */
394 	.rz_zev_zvol_truncate            = zev_zvol_truncate_cb,
395 	.rz_zev_zvol_write               = zev_zvol_write_cb,
396 
397 	/* znode zil events */
398 	.rz_zev_znode_close_after_update = zev_znode_close_after_update_cb,
399 	.rz_zev_znode_create             = zev_znode_create_cb,
400 	.rz_zev_znode_remove             = zev_znode_remove_cb,
401 	.rz_zev_znode_link               = zev_znode_link_cb,
402 	.rz_zev_znode_symlink            = zev_znode_symlink_cb,
403 	.rz_zev_znode_rename             = zev_znode_rename_cb,
404 	.rz_zev_znode_write              = zev_znode_write_cb,
405 	.rz_zev_znode_truncate           = zev_znode_truncate_cb,
406 	.rz_zev_znode_setattr            = zev_znode_setattr_cb,
407 	.rz_zev_znode_acl                = zev_znode_acl_cb,
408 };
409 
410