GNU Linux-libre 6.9.1-gnu
[releases.git] / fs / bcachefs / errcode.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include "bcachefs.h"
4 #include "errcode.h"
5 #include "trace.h"
6
7 #include <linux/errname.h>
8
9 static const char * const bch2_errcode_strs[] = {
10 #define x(class, err) [BCH_ERR_##err - BCH_ERR_START] = #err,
11         BCH_ERRCODES()
12 #undef x
13         NULL
14 };
15
16 static unsigned bch2_errcode_parents[] = {
17 #define x(class, err) [BCH_ERR_##err - BCH_ERR_START] = class,
18         BCH_ERRCODES()
19 #undef x
20 };
21
22 const char *bch2_err_str(int err)
23 {
24         const char *errstr;
25
26         err = abs(err);
27
28         BUG_ON(err >= BCH_ERR_MAX);
29
30         if (err >= BCH_ERR_START)
31                 errstr = bch2_errcode_strs[err - BCH_ERR_START];
32         else if (err)
33                 errstr = errname(err);
34         else
35                 errstr = "(No error)";
36         return errstr ?: "(Invalid error)";
37 }
38
39 bool __bch2_err_matches(int err, int class)
40 {
41         err     = abs(err);
42         class   = abs(class);
43
44         BUG_ON(err      >= BCH_ERR_MAX);
45         BUG_ON(class    >= BCH_ERR_MAX);
46
47         while (err >= BCH_ERR_START && err != class)
48                 err = bch2_errcode_parents[err - BCH_ERR_START];
49
50         return err == class;
51 }
52
53 int __bch2_err_class(int bch_err)
54 {
55         int std_err = -bch_err;
56         BUG_ON((unsigned) std_err >= BCH_ERR_MAX);
57
58         while (std_err >= BCH_ERR_START && bch2_errcode_parents[std_err - BCH_ERR_START])
59                 std_err = bch2_errcode_parents[std_err - BCH_ERR_START];
60
61         trace_error_downcast(bch_err, std_err, _RET_IP_);
62
63         return -std_err;
64 }
65
66 const char *bch2_blk_status_to_str(blk_status_t status)
67 {
68         if (status == BLK_STS_REMOVED)
69                 return "device removed";
70         return blk_status_to_str(status);
71 }