1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2024-2026 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
5 */
6 #include "xfs_platform.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_mount.h"
13 #include "xfs_inode.h"
14 #include "xfs_trace.h"
15 #include "xfs_ag.h"
16 #include "xfs_btree.h"
17 #include "xfs_da_format.h"
18 #include "xfs_da_btree.h"
19 #include "xfs_quota_defs.h"
20 #include "xfs_rtgroup.h"
21 #include "xfs_health.h"
22 #include "xfs_healthmon.h"
23 #include "xfs_fsops.h"
24 #include "xfs_notify_failure.h"
25 #include "xfs_file.h"
26 #include "xfs_ioctl.h"
27
28 #include <linux/anon_inodes.h>
29 #include <linux/eventpoll.h>
30 #include <linux/poll.h>
31 #include <linux/fserror.h>
32
33 /*
34 * Live Health Monitoring
35 * ======================
36 *
37 * Autonomous self-healing of XFS filesystems requires a means for the kernel
38 * to send filesystem health events to a monitoring daemon in userspace. To
39 * accomplish this, we establish a thread_with_file kthread object to handle
40 * translating internal events about filesystem health into a format that can
41 * be parsed easily by userspace. When those internal events occur, the core
42 * filesystem code calls this health monitor to convey the events to userspace.
43 * Userspace reads events from the file descriptor returned by the ioctl.
44 *
45 * The healthmon abstraction has a weak reference to the host filesystem mount
46 * so that the queueing and processing of the events do not pin the mount and
47 * cannot slow down the main filesystem. The healthmon object can exist past
48 * the end of the filesystem mount.
49 */
50
51 /* sign of a detached health monitor */
52 #define DETACHED_MOUNT_COOKIE ((uintptr_t)0)
53
54 /* Constrain the number of event objects that can build up in memory. */
55 #define XFS_HEALTHMON_MAX_EVENTS (SZ_32K / \
56 sizeof(struct xfs_healthmon_event))
57
58 /* Constrain the size of the output buffer for read_iter. */
59 #define XFS_HEALTHMON_MAX_OUTBUF SZ_64K
60
61 /* spinlock for atomically updating xfs_mount <-> xfs_healthmon pointers */
62 static DEFINE_SPINLOCK(xfs_healthmon_lock);
63
64 /* Grab a reference to the healthmon object for a given mount, if any. */
65 static struct xfs_healthmon *
xfs_healthmon_get(struct xfs_mount * mp)66 xfs_healthmon_get(
67 struct xfs_mount *mp)
68 {
69 struct xfs_healthmon *hm;
70
71 rcu_read_lock();
72 hm = rcu_dereference(mp->m_healthmon);
73 if (hm && !refcount_inc_not_zero(&hm->ref))
74 hm = NULL;
75 rcu_read_unlock();
76
77 return hm;
78 }
79
80 /*
81 * Release the reference to a healthmon object. If there are no more holders,
82 * free the health monitor after an RCU grace period to eliminate possibility
83 * of races with xfs_healthmon_get.
84 */
85 static void
xfs_healthmon_put(struct xfs_healthmon * hm)86 xfs_healthmon_put(
87 struct xfs_healthmon *hm)
88 {
89 if (refcount_dec_and_test(&hm->ref)) {
90 struct xfs_healthmon_event *event, *s;
91
92 list_for_each_entry_safe(event, s, &hm->event_list, entry) {
93 trace_xfs_healthmon_drop(hm, event);
94 kfree(event);
95 }
96
97 kfree(hm->unmount_event);
98 kfree(hm->buffer);
99 mutex_destroy(&hm->lock);
100 kfree_rcu_mightsleep(hm);
101 }
102 }
103
104 /* Attach a health monitor to an xfs_mount. Only one allowed at a time. */
105 STATIC int
xfs_healthmon_attach(struct xfs_mount * mp,struct xfs_healthmon * hm)106 xfs_healthmon_attach(
107 struct xfs_mount *mp,
108 struct xfs_healthmon *hm)
109 {
110 spin_lock(&xfs_healthmon_lock);
111 if (rcu_access_pointer(mp->m_healthmon) != NULL) {
112 spin_unlock(&xfs_healthmon_lock);
113 return -EEXIST;
114 }
115
116 refcount_inc(&hm->ref);
117 rcu_assign_pointer(mp->m_healthmon, hm);
118 hm->mount_cookie = (uintptr_t)mp->m_super;
119 spin_unlock(&xfs_healthmon_lock);
120
121 return 0;
122 }
123
124 /* Detach a xfs mount from a specific healthmon instance. */
125 STATIC void
xfs_healthmon_detach(struct xfs_healthmon * hm)126 xfs_healthmon_detach(
127 struct xfs_healthmon *hm)
128 {
129 struct xfs_mount *mp;
130
131 spin_lock(&xfs_healthmon_lock);
132 if (hm->mount_cookie == DETACHED_MOUNT_COOKIE) {
133 spin_unlock(&xfs_healthmon_lock);
134 return;
135 }
136
137 mp = XFS_M((struct super_block *)hm->mount_cookie);
138 rcu_assign_pointer(mp->m_healthmon, NULL);
139 hm->mount_cookie = DETACHED_MOUNT_COOKIE;
140 spin_unlock(&xfs_healthmon_lock);
141
142 /*
143 * Wake up any readers that might remain. This can happen if unmount
144 * races with the healthmon fd owner entering ->read_iter, having
145 * already emptied the event queue.
146 *
147 * In the ->release case there shouldn't be any readers because the
148 * only users of the waiter are read and poll.
149 */
150 wake_up_all(&hm->wait);
151
152 trace_xfs_healthmon_detach(hm);
153 xfs_healthmon_put(hm);
154 }
155
xfs_healthmon_bump_events(struct xfs_healthmon * hm)156 static inline void xfs_healthmon_bump_events(struct xfs_healthmon *hm)
157 {
158 hm->events++;
159 hm->total_events++;
160 }
161
xfs_healthmon_bump_lost(struct xfs_healthmon * hm)162 static inline void xfs_healthmon_bump_lost(struct xfs_healthmon *hm)
163 {
164 hm->lost_prev_event++;
165 hm->total_lost++;
166 }
167
168 /*
169 * If possible, merge a new event into an existing event. Returns whether or
170 * not it merged anything.
171 */
172 static bool
xfs_healthmon_merge_events(struct xfs_healthmon * hm,const struct xfs_healthmon_event * new)173 xfs_healthmon_merge_events(
174 struct xfs_healthmon *hm,
175 const struct xfs_healthmon_event *new)
176 {
177 struct xfs_healthmon_event *existing =
178 list_last_entry_or_null(&hm->event_list, struct
179 xfs_healthmon_event, entry);
180
181 if (!existing)
182 return false;
183
184 /* type and domain must match to merge events */
185 if (existing->type != new->type ||
186 existing->domain != new->domain)
187 return false;
188
189 switch (existing->type) {
190 case XFS_HEALTHMON_RUNNING:
191 case XFS_HEALTHMON_UNMOUNT:
192 /* should only ever be one of these events anyway */
193 return false;
194
195 case XFS_HEALTHMON_LOST:
196 existing->lostcount += new->lostcount;
197 goto out_merge;
198
199 case XFS_HEALTHMON_SICK:
200 case XFS_HEALTHMON_CORRUPT:
201 case XFS_HEALTHMON_HEALTHY:
202 switch (existing->domain) {
203 case XFS_HEALTHMON_FS:
204 existing->fsmask |= new->fsmask;
205 goto out_merge;
206 case XFS_HEALTHMON_AG:
207 case XFS_HEALTHMON_RTGROUP:
208 if (existing->group == new->group){
209 existing->grpmask |= new->grpmask;
210 goto out_merge;
211 }
212 return false;
213 case XFS_HEALTHMON_INODE:
214 if (existing->ino == new->ino &&
215 existing->gen == new->gen) {
216 existing->imask |= new->imask;
217 goto out_merge;
218 }
219 return false;
220 default:
221 ASSERT(0);
222 return false;
223 }
224 return false;
225
226 case XFS_HEALTHMON_SHUTDOWN:
227 /* yes, we can race to shutdown */
228 existing->flags |= new->flags;
229 goto out_merge;
230
231 case XFS_HEALTHMON_MEDIA_ERROR:
232 /* physically adjacent errors can merge */
233 if (existing->daddr + existing->bbcount == new->daddr) {
234 existing->bbcount += new->bbcount;
235 goto out_merge;
236 }
237 if (new->daddr + new->bbcount == existing->daddr) {
238 existing->daddr = new->daddr;
239 existing->bbcount += new->bbcount;
240 goto out_merge;
241 }
242 return false;
243
244 case XFS_HEALTHMON_BUFREAD:
245 case XFS_HEALTHMON_BUFWRITE:
246 case XFS_HEALTHMON_DIOREAD:
247 case XFS_HEALTHMON_DIOWRITE:
248 case XFS_HEALTHMON_DATALOST:
249 /* logically adjacent file ranges can merge */
250 if (existing->fino != new->fino ||
251 existing->fgen != new->fgen ||
252 existing->error != new->error)
253 return false;
254
255 if (existing->fpos + existing->flen == new->fpos) {
256 existing->flen += new->flen;
257 goto out_merge;
258 }
259
260 if (new->fpos + new->flen == existing->fpos) {
261 existing->fpos = new->fpos;
262 existing->flen += new->flen;
263 goto out_merge;
264 }
265 return false;
266 }
267
268 return false;
269
270 out_merge:
271 trace_xfs_healthmon_merge(hm, existing);
272 return true;
273 }
274
275 enum insert_where {
276 INSERT_HEAD,
277 INSERT_TAIL,
278 };
279
280 /* Add an event onto the start or the end of the queue. */
281 static inline void
__xfs_healthmon_insert(struct xfs_healthmon * hm,enum insert_where where,struct xfs_healthmon_event * event)282 __xfs_healthmon_insert(
283 struct xfs_healthmon *hm,
284 enum insert_where where,
285 struct xfs_healthmon_event *event)
286 {
287 struct timespec64 now;
288
289 lockdep_assert_held(&hm->lock);
290
291 ktime_get_coarse_real_ts64(&now);
292 event->time_ns = (now.tv_sec * NSEC_PER_SEC) + now.tv_nsec;
293
294 switch (where) {
295 case INSERT_HEAD:
296 trace_xfs_healthmon_insert_head(hm, event);
297
298 list_add(&event->entry, &hm->event_list);
299 break;
300 case INSERT_TAIL:
301 trace_xfs_healthmon_insert_tail(hm, event);
302
303 list_add_tail(&event->entry, &hm->event_list);
304 break;
305 }
306
307 xfs_healthmon_bump_events(hm);
308 wake_up(&hm->wait);
309 }
310
311 /* Deal with any previously lost events */
312 static int
xfs_healthmon_clear_lost_prev(struct xfs_healthmon * hm)313 xfs_healthmon_clear_lost_prev(
314 struct xfs_healthmon *hm)
315 {
316 struct xfs_healthmon_event lost_event = {
317 .type = XFS_HEALTHMON_LOST,
318 .domain = XFS_HEALTHMON_MOUNT,
319 .lostcount = hm->lost_prev_event,
320 };
321 struct xfs_healthmon_event *event = NULL;
322
323 if (xfs_healthmon_merge_events(hm, &lost_event)) {
324 wake_up(&hm->wait);
325 goto cleared;
326 }
327
328 if (hm->events < XFS_HEALTHMON_MAX_EVENTS)
329 event = kmemdup(&lost_event, sizeof(struct xfs_healthmon_event),
330 GFP_NOFS);
331 if (!event) {
332 xfs_healthmon_bump_lost(hm);
333 return -ENOMEM;
334 }
335
336 __xfs_healthmon_insert(hm, INSERT_TAIL, event);
337 cleared:
338 hm->lost_prev_event = 0;
339 return 0;
340 }
341
342 /*
343 * Push an event onto the end of the list after dealing with lost events and
344 * possibly full queues.
345 */
346 STATIC int
xfs_healthmon_push(struct xfs_healthmon * hm,const struct xfs_healthmon_event * template)347 xfs_healthmon_push(
348 struct xfs_healthmon *hm,
349 const struct xfs_healthmon_event *template)
350 {
351 struct xfs_healthmon_event *event = NULL;
352 int error = 0;
353
354 /*
355 * Locklessly check if the health monitor has already detached from the
356 * mount. If so, ignore the event. If we race with deactivation,
357 * we'll queue the event but never send it.
358 */
359 if (hm->mount_cookie == DETACHED_MOUNT_COOKIE)
360 return -ESHUTDOWN;
361
362 mutex_lock(&hm->lock);
363
364 /* Report previously lost events before we do anything else */
365 if (hm->lost_prev_event) {
366 error = xfs_healthmon_clear_lost_prev(hm);
367 if (error)
368 goto out_unlock;
369 }
370
371 /* Try to merge with the newest event */
372 if (xfs_healthmon_merge_events(hm, template)) {
373 wake_up(&hm->wait);
374 goto out_unlock;
375 }
376
377 /* Only create a heap event object if we're not already at capacity. */
378 if (hm->events < XFS_HEALTHMON_MAX_EVENTS)
379 event = kmemdup(template, sizeof(struct xfs_healthmon_event),
380 GFP_NOFS);
381 if (!event) {
382 /* No memory means we lose the event */
383 trace_xfs_healthmon_lost_event(hm);
384 xfs_healthmon_bump_lost(hm);
385 error = -ENOMEM;
386 goto out_unlock;
387 }
388
389 __xfs_healthmon_insert(hm, INSERT_TAIL, event);
390
391 out_unlock:
392 mutex_unlock(&hm->lock);
393 return error;
394 }
395
396 /*
397 * Report that the filesystem is being unmounted, then detach the xfs mount
398 * from this healthmon instance.
399 */
400 void
xfs_healthmon_unmount(struct xfs_mount * mp)401 xfs_healthmon_unmount(
402 struct xfs_mount *mp)
403 {
404 struct xfs_healthmon *hm = xfs_healthmon_get(mp);
405
406 if (!hm)
407 return;
408
409 trace_xfs_healthmon_report_unmount(hm);
410
411 /*
412 * Insert the unmount notification at the start of the event queue so
413 * that userspace knows the filesystem went away as soon as possible.
414 * There's nothing actionable for userspace after an unmount. Once
415 * we've inserted the unmount event, hm no longer owns that event.
416 */
417 mutex_lock(&hm->lock);
418 __xfs_healthmon_insert(hm, INSERT_HEAD, hm->unmount_event);
419 hm->unmount_event = NULL;
420 mutex_unlock(&hm->lock);
421
422 xfs_healthmon_detach(hm);
423 xfs_healthmon_put(hm);
424 }
425
426 /* Compute the reporting mask for non-unmount metadata health events. */
427 static inline unsigned int
metadata_event_mask(struct xfs_healthmon * hm,enum xfs_healthmon_type type,unsigned int old_mask,unsigned int new_mask)428 metadata_event_mask(
429 struct xfs_healthmon *hm,
430 enum xfs_healthmon_type type,
431 unsigned int old_mask,
432 unsigned int new_mask)
433 {
434 /* If we want all events, return all events. */
435 if (hm->verbose)
436 return new_mask;
437
438 switch (type) {
439 case XFS_HEALTHMON_SICK:
440 /* Always report runtime corruptions */
441 return new_mask;
442 case XFS_HEALTHMON_CORRUPT:
443 /* Only report new fsck errors */
444 return new_mask & ~old_mask;
445 case XFS_HEALTHMON_HEALTHY:
446 /* Only report healthy metadata that got fixed */
447 return new_mask & old_mask;
448 default:
449 ASSERT(0);
450 break;
451 }
452
453 return 0;
454 }
455
456 /* Report XFS_FS_SICK_* events to healthmon */
457 void
xfs_healthmon_report_fs(struct xfs_mount * mp,enum xfs_healthmon_type type,unsigned int old_mask,unsigned int new_mask)458 xfs_healthmon_report_fs(
459 struct xfs_mount *mp,
460 enum xfs_healthmon_type type,
461 unsigned int old_mask,
462 unsigned int new_mask)
463 {
464 struct xfs_healthmon_event event = {
465 .type = type,
466 .domain = XFS_HEALTHMON_FS,
467 };
468 struct xfs_healthmon *hm = xfs_healthmon_get(mp);
469
470 if (!hm)
471 return;
472
473 event.fsmask = metadata_event_mask(hm, type, old_mask, new_mask) &
474 ~XFS_SICK_FS_SECONDARY;
475 trace_xfs_healthmon_report_fs(hm, old_mask, new_mask, &event);
476
477 if (event.fsmask)
478 xfs_healthmon_push(hm, &event);
479
480 xfs_healthmon_put(hm);
481 }
482
483 /* Report XFS_SICK_(AG|RG)* flags to healthmon */
484 void
xfs_healthmon_report_group(struct xfs_group * xg,enum xfs_healthmon_type type,unsigned int old_mask,unsigned int new_mask)485 xfs_healthmon_report_group(
486 struct xfs_group *xg,
487 enum xfs_healthmon_type type,
488 unsigned int old_mask,
489 unsigned int new_mask)
490 {
491 struct xfs_healthmon_event event = {
492 .type = type,
493 .group = xg->xg_gno,
494 };
495 struct xfs_healthmon *hm = xfs_healthmon_get(xg->xg_mount);
496
497 if (!hm)
498 return;
499
500 switch (xg->xg_type) {
501 case XG_TYPE_RTG:
502 event.domain = XFS_HEALTHMON_RTGROUP;
503 event.grpmask = metadata_event_mask(hm, type, old_mask,
504 new_mask) &
505 ~XFS_SICK_RG_SECONDARY;
506 break;
507 case XG_TYPE_AG:
508 event.domain = XFS_HEALTHMON_AG;
509 event.grpmask = metadata_event_mask(hm, type, old_mask,
510 new_mask) &
511 ~XFS_SICK_AG_SECONDARY;
512 break;
513 default:
514 ASSERT(0);
515 break;
516 }
517
518 trace_xfs_healthmon_report_group(hm, old_mask, new_mask, &event);
519
520 if (event.grpmask)
521 xfs_healthmon_push(hm, &event);
522
523 xfs_healthmon_put(hm);
524 }
525
526 /* Report XFS_SICK_INO_* flags to healthmon */
527 void
xfs_healthmon_report_inode(struct xfs_inode * ip,enum xfs_healthmon_type type,unsigned int old_mask,unsigned int new_mask)528 xfs_healthmon_report_inode(
529 struct xfs_inode *ip,
530 enum xfs_healthmon_type type,
531 unsigned int old_mask,
532 unsigned int new_mask)
533 {
534 struct xfs_healthmon_event event = {
535 .type = type,
536 .domain = XFS_HEALTHMON_INODE,
537 .ino = I_INO(ip),
538 .gen = VFS_I(ip)->i_generation,
539 };
540 struct xfs_healthmon *hm = xfs_healthmon_get(ip->i_mount);
541
542 if (!hm)
543 return;
544
545 event.imask = metadata_event_mask(hm, type, old_mask, new_mask) &
546 ~XFS_SICK_INO_SECONDARY;
547 trace_xfs_healthmon_report_inode(hm, old_mask, event.imask, &event);
548
549 if (event.imask)
550 xfs_healthmon_push(hm, &event);
551
552 xfs_healthmon_put(hm);
553 }
554
555 /* Add a shutdown event to the reporting queue. */
556 void
xfs_healthmon_report_shutdown(struct xfs_mount * mp,uint32_t flags)557 xfs_healthmon_report_shutdown(
558 struct xfs_mount *mp,
559 uint32_t flags)
560 {
561 struct xfs_healthmon_event event = {
562 .type = XFS_HEALTHMON_SHUTDOWN,
563 .domain = XFS_HEALTHMON_MOUNT,
564 .flags = flags,
565 };
566 struct xfs_healthmon *hm = xfs_healthmon_get(mp);
567
568 if (!hm)
569 return;
570
571 trace_xfs_healthmon_report_shutdown(hm, flags);
572
573 xfs_healthmon_push(hm, &event);
574 xfs_healthmon_put(hm);
575 }
576
577 static inline enum xfs_healthmon_domain
media_error_domain(enum xfs_device fdev)578 media_error_domain(
579 enum xfs_device fdev)
580 {
581 switch (fdev) {
582 case XFS_DEV_DATA:
583 return XFS_HEALTHMON_DATADEV;
584 case XFS_DEV_LOG:
585 return XFS_HEALTHMON_LOGDEV;
586 case XFS_DEV_RT:
587 return XFS_HEALTHMON_RTDEV;
588 }
589
590 ASSERT(0);
591 return 0;
592 }
593
594 /* Add a media error event to the reporting queue. */
595 void
xfs_healthmon_report_media(struct xfs_mount * mp,enum xfs_device fdev,xfs_daddr_t daddr,uint64_t bbcount)596 xfs_healthmon_report_media(
597 struct xfs_mount *mp,
598 enum xfs_device fdev,
599 xfs_daddr_t daddr,
600 uint64_t bbcount)
601 {
602 struct xfs_healthmon_event event = {
603 .type = XFS_HEALTHMON_MEDIA_ERROR,
604 .domain = media_error_domain(fdev),
605 .daddr = daddr,
606 .bbcount = bbcount,
607 };
608 struct xfs_healthmon *hm = xfs_healthmon_get(mp);
609
610 if (!hm)
611 return;
612
613 trace_xfs_healthmon_report_media(hm, fdev, &event);
614
615 xfs_healthmon_push(hm, &event);
616 xfs_healthmon_put(hm);
617 }
618
file_ioerr_type(enum fserror_type action)619 static inline enum xfs_healthmon_type file_ioerr_type(enum fserror_type action)
620 {
621 switch (action) {
622 case FSERR_BUFFERED_READ:
623 return XFS_HEALTHMON_BUFREAD;
624 case FSERR_BUFFERED_WRITE:
625 return XFS_HEALTHMON_BUFWRITE;
626 case FSERR_DIRECTIO_READ:
627 return XFS_HEALTHMON_DIOREAD;
628 case FSERR_DIRECTIO_WRITE:
629 return XFS_HEALTHMON_DIOWRITE;
630 case FSERR_DATA_LOST:
631 return XFS_HEALTHMON_DATALOST;
632 case FSERR_METADATA:
633 /* filtered out by xfs_fs_report_error */
634 break;
635 }
636
637 ASSERT(0);
638 return -1;
639 }
640
641 /* Add a file io error event to the reporting queue. */
642 void
xfs_healthmon_report_file_ioerror(struct xfs_inode * ip,const struct fserror_event * p)643 xfs_healthmon_report_file_ioerror(
644 struct xfs_inode *ip,
645 const struct fserror_event *p)
646 {
647 struct xfs_healthmon_event event = {
648 .type = file_ioerr_type(p->type),
649 .domain = XFS_HEALTHMON_FILERANGE,
650 .fino = I_INO(ip),
651 .fgen = VFS_I(ip)->i_generation,
652 .fpos = p->pos,
653 .flen = p->len,
654 /* send positive error number to userspace */
655 .error = -p->error,
656 };
657 struct xfs_healthmon *hm = xfs_healthmon_get(ip->i_mount);
658
659 if (!hm)
660 return;
661
662 trace_xfs_healthmon_report_file_ioerror(hm, p);
663
664 xfs_healthmon_push(hm, &event);
665 xfs_healthmon_put(hm);
666 }
667
668 static inline void
xfs_healthmon_reset_outbuf(struct xfs_healthmon * hm)669 xfs_healthmon_reset_outbuf(
670 struct xfs_healthmon *hm)
671 {
672 hm->buftail = 0;
673 hm->bufhead = 0;
674 }
675
676 struct flags_map {
677 unsigned int in_mask;
678 unsigned int out_mask;
679 };
680
681 static const struct flags_map shutdown_map[] = {
682 { SHUTDOWN_META_IO_ERROR, XFS_HEALTH_SHUTDOWN_META_IO_ERROR },
683 { SHUTDOWN_LOG_IO_ERROR, XFS_HEALTH_SHUTDOWN_LOG_IO_ERROR },
684 { SHUTDOWN_FORCE_UMOUNT, XFS_HEALTH_SHUTDOWN_FORCE_UMOUNT },
685 { SHUTDOWN_CORRUPT_INCORE, XFS_HEALTH_SHUTDOWN_CORRUPT_INCORE },
686 { SHUTDOWN_CORRUPT_ONDISK, XFS_HEALTH_SHUTDOWN_CORRUPT_ONDISK },
687 { SHUTDOWN_DEVICE_REMOVED, XFS_HEALTH_SHUTDOWN_DEVICE_REMOVED },
688 };
689
690 static inline unsigned int
__map_flags(const struct flags_map * map,size_t array_len,unsigned int flags)691 __map_flags(
692 const struct flags_map *map,
693 size_t array_len,
694 unsigned int flags)
695 {
696 const struct flags_map *m;
697 unsigned int ret = 0;
698
699 for (m = map; m < map + array_len; m++) {
700 if (flags & m->in_mask)
701 ret |= m->out_mask;
702 }
703
704 return ret;
705 }
706
707 #define map_flags(map, flags) __map_flags((map), ARRAY_SIZE(map), (flags))
708
shutdown_mask(unsigned int in)709 static inline unsigned int shutdown_mask(unsigned int in)
710 {
711 return map_flags(shutdown_map, in);
712 }
713
714 static const unsigned int domain_map[] = {
715 [XFS_HEALTHMON_MOUNT] = XFS_HEALTH_MONITOR_DOMAIN_MOUNT,
716 [XFS_HEALTHMON_FS] = XFS_HEALTH_MONITOR_DOMAIN_FS,
717 [XFS_HEALTHMON_AG] = XFS_HEALTH_MONITOR_DOMAIN_AG,
718 [XFS_HEALTHMON_INODE] = XFS_HEALTH_MONITOR_DOMAIN_INODE,
719 [XFS_HEALTHMON_RTGROUP] = XFS_HEALTH_MONITOR_DOMAIN_RTGROUP,
720 [XFS_HEALTHMON_DATADEV] = XFS_HEALTH_MONITOR_DOMAIN_DATADEV,
721 [XFS_HEALTHMON_RTDEV] = XFS_HEALTH_MONITOR_DOMAIN_RTDEV,
722 [XFS_HEALTHMON_LOGDEV] = XFS_HEALTH_MONITOR_DOMAIN_LOGDEV,
723 [XFS_HEALTHMON_FILERANGE] = XFS_HEALTH_MONITOR_DOMAIN_FILERANGE,
724 };
725
726 static const unsigned int type_map[] = {
727 [XFS_HEALTHMON_RUNNING] = XFS_HEALTH_MONITOR_TYPE_RUNNING,
728 [XFS_HEALTHMON_LOST] = XFS_HEALTH_MONITOR_TYPE_LOST,
729 [XFS_HEALTHMON_SICK] = XFS_HEALTH_MONITOR_TYPE_SICK,
730 [XFS_HEALTHMON_CORRUPT] = XFS_HEALTH_MONITOR_TYPE_CORRUPT,
731 [XFS_HEALTHMON_HEALTHY] = XFS_HEALTH_MONITOR_TYPE_HEALTHY,
732 [XFS_HEALTHMON_UNMOUNT] = XFS_HEALTH_MONITOR_TYPE_UNMOUNT,
733 [XFS_HEALTHMON_SHUTDOWN] = XFS_HEALTH_MONITOR_TYPE_SHUTDOWN,
734 [XFS_HEALTHMON_MEDIA_ERROR] = XFS_HEALTH_MONITOR_TYPE_MEDIA_ERROR,
735 [XFS_HEALTHMON_BUFREAD] = XFS_HEALTH_MONITOR_TYPE_BUFREAD,
736 [XFS_HEALTHMON_BUFWRITE] = XFS_HEALTH_MONITOR_TYPE_BUFWRITE,
737 [XFS_HEALTHMON_DIOREAD] = XFS_HEALTH_MONITOR_TYPE_DIOREAD,
738 [XFS_HEALTHMON_DIOWRITE] = XFS_HEALTH_MONITOR_TYPE_DIOWRITE,
739 [XFS_HEALTHMON_DATALOST] = XFS_HEALTH_MONITOR_TYPE_DATALOST,
740 };
741
742 static inline bool
xfs_healthmon_check_outbuffer_space(const struct xfs_healthmon * hm)743 xfs_healthmon_check_outbuffer_space(const struct xfs_healthmon *hm)
744 {
745 return hm->bufhead + sizeof(struct xfs_health_monitor_event) <=
746 hm->bufsize;
747 }
748
749 /* Render event as a V0 structure */
750 STATIC int
xfs_healthmon_format_v0(struct xfs_healthmon * hm,const struct xfs_healthmon_event * event)751 xfs_healthmon_format_v0(
752 struct xfs_healthmon *hm,
753 const struct xfs_healthmon_event *event)
754 {
755 struct xfs_health_monitor_event hme = {
756 .time_ns = event->time_ns,
757 };
758
759 trace_xfs_healthmon_format(hm, event);
760
761 if (event->domain < 0 || event->domain >= ARRAY_SIZE(domain_map) ||
762 event->type < 0 || event->type >= ARRAY_SIZE(type_map))
763 return -EFSCORRUPTED;
764
765 hme.domain = domain_map[event->domain];
766 hme.type = type_map[event->type];
767
768 /* fill in the event-specific details */
769 switch (event->domain) {
770 case XFS_HEALTHMON_MOUNT:
771 switch (event->type) {
772 case XFS_HEALTHMON_LOST:
773 hme.e.lost.count = event->lostcount;
774 break;
775 case XFS_HEALTHMON_SHUTDOWN:
776 hme.e.shutdown.reasons = shutdown_mask(event->flags);
777 break;
778 default:
779 break;
780 }
781 break;
782 case XFS_HEALTHMON_FS:
783 hme.e.fs.mask = xfs_healthmon_fs_mask(event->fsmask);
784 break;
785 case XFS_HEALTHMON_RTGROUP:
786 hme.e.group.mask = xfs_healthmon_rtgroup_mask(event->grpmask);
787 hme.e.group.gno = event->group;
788 break;
789 case XFS_HEALTHMON_AG:
790 hme.e.group.mask = xfs_healthmon_perag_mask(event->grpmask);
791 hme.e.group.gno = event->group;
792 break;
793 case XFS_HEALTHMON_INODE:
794 hme.e.inode.mask = xfs_healthmon_inode_mask(event->imask);
795 hme.e.inode.ino = event->ino;
796 hme.e.inode.gen = event->gen;
797 break;
798 case XFS_HEALTHMON_DATADEV:
799 case XFS_HEALTHMON_LOGDEV:
800 case XFS_HEALTHMON_RTDEV:
801 hme.e.media.daddr = event->daddr;
802 hme.e.media.bbcount = event->bbcount;
803 break;
804 case XFS_HEALTHMON_FILERANGE:
805 hme.e.filerange.ino = event->fino;
806 hme.e.filerange.gen = event->fgen;
807 hme.e.filerange.pos = event->fpos;
808 hme.e.filerange.len = event->flen;
809 hme.e.filerange.error = abs(event->error);
810 break;
811 default:
812 break;
813 }
814
815 ASSERT(xfs_healthmon_check_outbuffer_space(hm));
816
817 /* copy formatted object to the outbuf */
818 if (xfs_healthmon_check_outbuffer_space(hm)) {
819 memcpy(hm->buffer + hm->bufhead, &hme, sizeof(hme));
820 hm->bufhead += sizeof(hme);
821 }
822
823 return 0;
824 }
825
826 /* How many bytes are waiting in the outbuf to be copied? */
827 static inline size_t
xfs_healthmon_outbuf_bytes(struct xfs_healthmon * hm)828 xfs_healthmon_outbuf_bytes(
829 struct xfs_healthmon *hm)
830 {
831 if (hm->bufhead > hm->buftail)
832 return hm->bufhead - hm->buftail;
833 return 0;
834 }
835
836 /*
837 * Do we have something for userspace to read? This can mean unmount events,
838 * events pending in the queue, or pending bytes in the outbuf.
839 */
840 static inline bool
xfs_healthmon_has_eventdata(struct xfs_healthmon * hm)841 xfs_healthmon_has_eventdata(
842 struct xfs_healthmon *hm)
843 {
844 /*
845 * If the health monitor is already detached from the xfs_mount, we
846 * want reads to return 0 bytes even if there are no events, because
847 * userspace interprets that as EOF. If we race with deactivation,
848 * read_iter will take the necessary locks to discover that there are
849 * no events to send.
850 */
851 if (hm->mount_cookie == DETACHED_MOUNT_COOKIE)
852 return true;
853
854 /*
855 * Either there are events waiting to be formatted into the buffer, or
856 * there's unread bytes in the buffer.
857 */
858 return hm->events > 0 || xfs_healthmon_outbuf_bytes(hm) > 0;
859 }
860
861 /* Try to copy the rest of the outbuf to the iov iter. */
862 STATIC ssize_t
xfs_healthmon_copybuf(struct xfs_healthmon * hm,struct iov_iter * to)863 xfs_healthmon_copybuf(
864 struct xfs_healthmon *hm,
865 struct iov_iter *to)
866 {
867 size_t to_copy;
868 size_t w = 0;
869
870 trace_xfs_healthmon_copybuf(hm, to);
871
872 to_copy = xfs_healthmon_outbuf_bytes(hm);
873 if (to_copy) {
874 w = copy_to_iter(hm->buffer + hm->buftail, to_copy, to);
875 if (!w)
876 return -EFAULT;
877
878 hm->buftail += w;
879 }
880
881 /*
882 * Nothing left to copy? Reset the output buffer cursors to the start
883 * since there's no live data in the buffer.
884 */
885 if (xfs_healthmon_outbuf_bytes(hm) == 0)
886 xfs_healthmon_reset_outbuf(hm);
887 return w;
888 }
889
890 /*
891 * Return a health monitoring event for formatting into the output buffer if
892 * there's enough space in the outbuf and an event waiting for us. Caller
893 * must hold i_rwsem on the healthmon file.
894 */
895 static inline struct xfs_healthmon_event *
xfs_healthmon_format_pop(struct xfs_healthmon * hm)896 xfs_healthmon_format_pop(
897 struct xfs_healthmon *hm)
898 {
899 struct xfs_healthmon_event *event;
900
901 /*
902 * Don't bother if there's not enough space to format even one event in
903 * the outbuffer.
904 */
905 if (!xfs_healthmon_check_outbuffer_space(hm))
906 return NULL;
907
908 mutex_lock(&hm->lock);
909 event = list_first_entry_or_null(&hm->event_list,
910 struct xfs_healthmon_event, entry);
911 if (event) {
912 list_del_init(&event->entry);
913 hm->events--;
914
915 trace_xfs_healthmon_pop(hm, event);
916 }
917 mutex_unlock(&hm->lock);
918 return event;
919 }
920
921 /* Allocate formatting buffer */
922 STATIC int
xfs_healthmon_alloc_outbuf(struct xfs_healthmon * hm,size_t user_bufsize)923 xfs_healthmon_alloc_outbuf(
924 struct xfs_healthmon *hm,
925 size_t user_bufsize)
926 {
927 void *outbuf;
928 size_t bufsize =
929 min(XFS_HEALTHMON_MAX_OUTBUF, max(PAGE_SIZE, user_bufsize));
930
931 outbuf = kzalloc(bufsize, GFP_KERNEL);
932 if (!outbuf) {
933 if (bufsize == PAGE_SIZE)
934 return -ENOMEM;
935
936 bufsize = PAGE_SIZE;
937 outbuf = kzalloc(bufsize, GFP_KERNEL);
938 if (!outbuf)
939 return -ENOMEM;
940 }
941
942 hm->buffer = outbuf;
943 hm->bufsize = bufsize;
944 hm->bufhead = 0;
945 hm->buftail = 0;
946
947 return 0;
948 }
949
950 /*
951 * Convey queued event data to userspace. First copy any remaining bytes in
952 * the outbuf, then format the oldest event into the outbuf and copy that too.
953 */
954 STATIC ssize_t
xfs_healthmon_read_iter(struct kiocb * iocb,struct iov_iter * to)955 xfs_healthmon_read_iter(
956 struct kiocb *iocb,
957 struct iov_iter *to)
958 {
959 struct file *file = iocb->ki_filp;
960 struct inode *inode = file_inode(file);
961 struct xfs_healthmon *hm = file->private_data;
962 struct xfs_healthmon_event *event;
963 size_t copied = 0;
964 ssize_t ret = 0;
965
966 if (file->f_flags & O_NONBLOCK) {
967 if (!xfs_healthmon_has_eventdata(hm) || !inode_trylock(inode))
968 return -EAGAIN;
969 } else {
970 ret = wait_event_interruptible(hm->wait,
971 xfs_healthmon_has_eventdata(hm));
972 if (ret)
973 return ret;
974
975 inode_lock(inode);
976 }
977
978 if (hm->bufsize == 0) {
979 ret = xfs_healthmon_alloc_outbuf(hm, iov_iter_count(to));
980 if (ret)
981 goto out_unlock;
982 }
983
984 trace_xfs_healthmon_read_start(hm);
985
986 /*
987 * If there's anything left in the output buffer, copy that before
988 * formatting more events.
989 */
990 ret = xfs_healthmon_copybuf(hm, to);
991 if (ret < 0)
992 goto out_unlock;
993 copied += ret;
994
995 while (iov_iter_count(to) > 0) {
996 /* Format the next events into the outbuf until it's full. */
997 while ((event = xfs_healthmon_format_pop(hm)) != NULL) {
998 ret = xfs_healthmon_format_v0(hm, event);
999 kfree(event);
1000 if (ret)
1001 goto out_unlock;
1002 }
1003
1004 /* Copy anything formatted into outbuf to userspace */
1005 ret = xfs_healthmon_copybuf(hm, to);
1006 if (ret <= 0)
1007 break;
1008
1009 copied += ret;
1010 }
1011
1012 out_unlock:
1013 trace_xfs_healthmon_read_finish(hm);
1014 inode_unlock(inode);
1015 return copied ?: ret;
1016 }
1017
1018 /* Poll for available events. */
1019 STATIC __poll_t
xfs_healthmon_poll(struct file * file,struct poll_table_struct * wait)1020 xfs_healthmon_poll(
1021 struct file *file,
1022 struct poll_table_struct *wait)
1023 {
1024 struct xfs_healthmon *hm = file->private_data;
1025 __poll_t mask = 0;
1026
1027 poll_wait(file, &hm->wait, wait);
1028
1029 if (xfs_healthmon_has_eventdata(hm))
1030 mask |= EPOLLIN;
1031 return mask;
1032 }
1033
1034 /* Free the health monitoring information. */
1035 STATIC int
xfs_healthmon_release(struct inode * inode,struct file * file)1036 xfs_healthmon_release(
1037 struct inode *inode,
1038 struct file *file)
1039 {
1040 struct xfs_healthmon *hm = file->private_data;
1041
1042 trace_xfs_healthmon_release(hm);
1043
1044 /*
1045 * We might be closing the healthmon file before the filesystem
1046 * unmounts, because userspace processes can terminate at any time and
1047 * for any reason. Null out xfs_mount::m_healthmon so that another
1048 * process can create another health monitor file.
1049 */
1050 xfs_healthmon_detach(hm);
1051 xfs_healthmon_put(hm);
1052 return 0;
1053 }
1054
1055 /* Validate ioctl parameters. */
1056 static inline bool
xfs_healthmon_validate(const struct xfs_health_monitor * hmo)1057 xfs_healthmon_validate(
1058 const struct xfs_health_monitor *hmo)
1059 {
1060 if (hmo->flags & ~XFS_HEALTH_MONITOR_ALL)
1061 return false;
1062 if (hmo->format != XFS_HEALTH_MONITOR_FMT_V0)
1063 return false;
1064 if (memchr_inv(&hmo->pad, 0, sizeof(hmo->pad)))
1065 return false;
1066 return true;
1067 }
1068
1069 /* Emit some data about the health monitoring fd. */
1070 static void
xfs_healthmon_show_fdinfo(struct seq_file * m,struct file * file)1071 xfs_healthmon_show_fdinfo(
1072 struct seq_file *m,
1073 struct file *file)
1074 {
1075 struct xfs_healthmon *hm = file->private_data;
1076
1077 mutex_lock(&hm->lock);
1078 seq_printf(m, "state:\t%s\ndev:\t%d:%d\nformat:\tv0\nevents:\t%llu\nlost:\t%llu\n",
1079 hm->mount_cookie == DETACHED_MOUNT_COOKIE ?
1080 "dead" : "alive",
1081 MAJOR(hm->dev), MINOR(hm->dev),
1082 hm->total_events,
1083 hm->total_lost);
1084 mutex_unlock(&hm->lock);
1085 }
1086
1087 /* Reconfigure the health monitor. */
1088 STATIC long
xfs_healthmon_reconfigure(struct file * file,unsigned int cmd,void __user * arg)1089 xfs_healthmon_reconfigure(
1090 struct file *file,
1091 unsigned int cmd,
1092 void __user *arg)
1093 {
1094 struct xfs_health_monitor hmo;
1095 struct xfs_healthmon *hm = file->private_data;
1096
1097 if (copy_from_user(&hmo, arg, sizeof(hmo)))
1098 return -EFAULT;
1099
1100 if (!xfs_healthmon_validate(&hmo))
1101 return -EINVAL;
1102
1103 mutex_lock(&hm->lock);
1104 hm->verbose = !!(hmo.flags & XFS_HEALTH_MONITOR_VERBOSE);
1105 mutex_unlock(&hm->lock);
1106
1107 return 0;
1108 }
1109
1110 /* Does the fd point to the same filesystem as the one we're monitoring? */
1111 STATIC long
xfs_healthmon_file_on_monitored_fs(struct file * file,unsigned int cmd,void __user * arg)1112 xfs_healthmon_file_on_monitored_fs(
1113 struct file *file,
1114 unsigned int cmd,
1115 void __user *arg)
1116 {
1117 struct xfs_health_file_on_monitored_fs hms;
1118 struct xfs_healthmon *hm = file->private_data;
1119 struct inode *hms_inode;
1120
1121 if (copy_from_user(&hms, arg, sizeof(hms)))
1122 return -EFAULT;
1123
1124 if (hms.flags)
1125 return -EINVAL;
1126
1127 CLASS(fd, hms_fd)(hms.fd);
1128 if (fd_empty(hms_fd))
1129 return -EBADF;
1130
1131 hms_inode = file_inode(fd_file(hms_fd));
1132 mutex_lock(&hm->lock);
1133 if (hm->mount_cookie != (uintptr_t)hms_inode->i_sb) {
1134 mutex_unlock(&hm->lock);
1135 return -ESTALE;
1136 }
1137
1138 mutex_unlock(&hm->lock);
1139 return 0;
1140 }
1141
1142 /* Handle ioctls for the health monitoring thread. */
1143 STATIC long
xfs_healthmon_ioctl(struct file * file,unsigned int cmd,unsigned long p)1144 xfs_healthmon_ioctl(
1145 struct file *file,
1146 unsigned int cmd,
1147 unsigned long p)
1148 {
1149 void __user *arg = (void __user *)p;
1150
1151 switch (cmd) {
1152 case XFS_IOC_HEALTH_MONITOR:
1153 return xfs_healthmon_reconfigure(file, cmd, arg);
1154 case XFS_IOC_HEALTH_FD_ON_MONITORED_FS:
1155 return xfs_healthmon_file_on_monitored_fs(file, cmd, arg);
1156 default:
1157 break;
1158 }
1159
1160 return -ENOTTY;
1161 }
1162
1163 static const struct file_operations xfs_healthmon_fops = {
1164 .owner = THIS_MODULE,
1165 .show_fdinfo = xfs_healthmon_show_fdinfo,
1166 .read_iter = xfs_healthmon_read_iter,
1167 .poll = xfs_healthmon_poll,
1168 .release = xfs_healthmon_release,
1169 .unlocked_ioctl = xfs_healthmon_ioctl,
1170 };
1171
1172 /*
1173 * Create a health monitoring file. Returns an index to the fd table or a
1174 * negative errno.
1175 */
1176 long
xfs_ioc_health_monitor(struct file * file,struct xfs_health_monitor __user * arg)1177 xfs_ioc_health_monitor(
1178 struct file *file,
1179 struct xfs_health_monitor __user *arg)
1180 {
1181 struct xfs_health_monitor hmo;
1182 struct xfs_healthmon_event *running_event;
1183 struct xfs_healthmon *hm;
1184 struct xfs_inode *ip = XFS_I(file_inode(file));
1185 struct xfs_mount *mp = ip->i_mount;
1186 int ret;
1187
1188 /*
1189 * The only intended user of the health monitoring system should be the
1190 * xfs_healer daemon running on behalf of the whole filesystem in the
1191 * initial user namespace. IOWs, we don't allow unprivileged userspace
1192 * (they can use fsnotify) nor do we allow containers.
1193 */
1194 if (!capable(CAP_SYS_ADMIN))
1195 return -EPERM;
1196 if (I_INO(ip) != mp->m_sb.sb_rootino)
1197 return -EPERM;
1198 if (current_user_ns() != &init_user_ns)
1199 return -EPERM;
1200
1201 if (copy_from_user(&hmo, arg, sizeof(hmo)))
1202 return -EFAULT;
1203
1204 if (!xfs_healthmon_validate(&hmo))
1205 return -EINVAL;
1206
1207 hm = kzalloc_obj(*hm);
1208 if (!hm)
1209 return -ENOMEM;
1210 hm->dev = mp->m_super->s_dev;
1211 refcount_set(&hm->ref, 1);
1212 INIT_LIST_HEAD(&hm->event_list);
1213
1214 mutex_init(&hm->lock);
1215 init_waitqueue_head(&hm->wait);
1216
1217 if (hmo.flags & XFS_HEALTH_MONITOR_VERBOSE)
1218 hm->verbose = true;
1219
1220 /* Queue up the first event that lets the client know we're running. */
1221 running_event = kzalloc_obj(struct xfs_healthmon_event, GFP_NOFS);
1222 if (!running_event) {
1223 ret = -ENOMEM;
1224 goto out_hm;
1225 }
1226 running_event->type = XFS_HEALTHMON_RUNNING;
1227 running_event->domain = XFS_HEALTHMON_MOUNT;
1228 mutex_lock(&hm->lock);
1229 __xfs_healthmon_insert(hm, INSERT_HEAD, running_event);
1230 mutex_unlock(&hm->lock);
1231
1232 /*
1233 * Preallocate the unmount event so that we can't fail to notify the
1234 * filesystem later. This is key for triggering fast exit of the
1235 * xfs_healer daemon.
1236 */
1237 hm->unmount_event = kzalloc_obj(struct xfs_healthmon_event, GFP_NOFS);
1238 if (!hm->unmount_event) {
1239 ret = -ENOMEM;
1240 goto out_hm;
1241 }
1242 hm->unmount_event->type = XFS_HEALTHMON_UNMOUNT;
1243 hm->unmount_event->domain = XFS_HEALTHMON_MOUNT;
1244
1245 /*
1246 * Try to attach this health monitor to the xfs_mount. The monitor is
1247 * considered live and will receive events if this succeeds.
1248 */
1249 ret = xfs_healthmon_attach(mp, hm);
1250 if (ret)
1251 goto out_hm;
1252
1253 /*
1254 * Create the anonymous file and install a fd for it. If it succeeds,
1255 * the file owns hm and can go away at any time, so we must not access
1256 * it again. This must go last because we can't undo a fd table
1257 * installation.
1258 */
1259 ret = anon_inode_getfd("xfs_healthmon", &xfs_healthmon_fops, hm,
1260 O_CLOEXEC | O_RDONLY);
1261 if (ret < 0)
1262 goto out_mp;
1263
1264 trace_xfs_healthmon_create(mp->m_super->s_dev, hmo.flags, hmo.format);
1265
1266 return ret;
1267
1268 out_mp:
1269 xfs_healthmon_detach(hm);
1270 out_hm:
1271 ASSERT(refcount_read(&hm->ref) == 1);
1272 xfs_healthmon_put(hm);
1273 return ret;
1274 }
1275