Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcachefs: Errcode tracepoint, documentation

Add a tracepoint for downcasting private errors to standard errors, so
they can be recovered even when not logged; also, add some
documentation.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>

+59 -6
+30
Documentation/filesystems/bcachefs/errorcodes.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + bcachefs private error codes 4 + ---------------------------- 5 + 6 + In bcachefs, as a hard rule we do not throw or directly use standard error 7 + codes (-EINVAL, -EBUSY, etc.). Instead, we define private error codes as needed 8 + in fs/bcachefs/errcode.h. 9 + 10 + This gives us much better error messages and makes debugging much easier. Any 11 + direct uses of standard error codes you see in the source code are simply old 12 + code that has yet to be converted - feel free to clean it up! 13 + 14 + Private error codes may subtype another error code, this allows for grouping of 15 + related errors that should be handled similarly (e.g. transaction restart 16 + errors), as well as specifying which standard error code should be returned at 17 + the bcachefs module boundary. 18 + 19 + At the module boundary, we use bch2_err_class() to convert to a standard error 20 + code; this also emits a trace event so that the original error code be 21 + recovered even if it wasn't logged. 22 + 23 + Do not reuse error codes! Generally speaking, a private error code should only 24 + be thrown in one place. That means that when we see it in a log message we can 25 + see, unambiguously, exactly which file and line number it was returned from. 26 + 27 + Try to give error codes names that are as reasonably descriptive of the error 28 + as possible. Frequently, the error will be logged at a place far removed from 29 + where the error was generated; good names for error codes mean much more 30 + descriptive and useful error messages.
+9 -6
fs/bcachefs/errcode.c
··· 2 2 3 3 #include "bcachefs.h" 4 4 #include "errcode.h" 5 + #include "trace.h" 5 6 6 7 #include <linux/errname.h> 7 8 ··· 50 49 return err == class; 51 50 } 52 51 53 - int __bch2_err_class(int err) 52 + int __bch2_err_class(int bch_err) 54 53 { 55 - err = -err; 56 - BUG_ON((unsigned) err >= BCH_ERR_MAX); 54 + int std_err = -bch_err; 55 + BUG_ON((unsigned) std_err >= BCH_ERR_MAX); 57 56 58 - while (err >= BCH_ERR_START && bch2_errcode_parents[err - BCH_ERR_START]) 59 - err = bch2_errcode_parents[err - BCH_ERR_START]; 57 + while (std_err >= BCH_ERR_START && bch2_errcode_parents[std_err - BCH_ERR_START]) 58 + std_err = bch2_errcode_parents[std_err - BCH_ERR_START]; 60 59 61 - return -err; 60 + trace_error_downcast(bch_err, std_err, _RET_IP_); 61 + 62 + return -std_err; 62 63 } 63 64 64 65 const char *bch2_blk_status_to_str(blk_status_t status)
+1
fs/bcachefs/errcode.h
··· 78 78 x(ENOMEM, ENOMEM_fs_name_alloc) \ 79 79 x(ENOMEM, ENOMEM_fs_other_alloc) \ 80 80 x(ENOMEM, ENOMEM_dev_alloc) \ 81 + x(ENOMEM, ENOMEM_disk_accounting) \ 81 82 x(ENOSPC, ENOSPC_disk_reservation) \ 82 83 x(ENOSPC, ENOSPC_bucket_alloc) \ 83 84 x(ENOSPC, ENOSPC_disk_label_add) \
+19
fs/bcachefs/trace.h
··· 1431 1431 TP_ARGS(c, str) 1432 1432 ); 1433 1433 1434 + TRACE_EVENT(error_downcast, 1435 + TP_PROTO(int bch_err, int std_err, unsigned long ip), 1436 + TP_ARGS(bch_err, std_err, ip), 1437 + 1438 + TP_STRUCT__entry( 1439 + __array(char, bch_err, 32 ) 1440 + __array(char, std_err, 32 ) 1441 + __array(char, ip, 32 ) 1442 + ), 1443 + 1444 + TP_fast_assign( 1445 + strscpy(__entry->bch_err, bch2_err_str(bch_err), sizeof(__entry->bch_err)); 1446 + strscpy(__entry->std_err, bch2_err_str(std_err), sizeof(__entry->std_err)); 1447 + snprintf(__entry->ip, sizeof(__entry->ip), "%ps", (void *) ip); 1448 + ), 1449 + 1450 + TP_printk("%s -> %s %s", __entry->bch_err, __entry->std_err, __entry->ip) 1451 + ); 1452 + 1434 1453 #endif /* _TRACE_BCACHEFS_H */ 1435 1454 1436 1455 /* This part must be outside protection */