x(EINVAL,                       remove_with_metadata_missing_unimplemented)\
        x(EINVAL,                       remove_would_lose_data)                 \
        x(EINVAL,                       no_resize_with_buckets_nouse)           \
+       x(EINVAL,                       inode_unpack_error)                     \
+       x(EINVAL,                       varint_decode_error)                    \
        x(EROFS,                        erofs_trans_commit)                     \
        x(EROFS,                        erofs_no_writes)                        \
        x(EROFS,                        erofs_journal_err)                      \
 
 #define BLK_STS_REMOVED                ((__force blk_status_t)128)
 
+#include <linux/blk_types.h>
 const char *bch2_blk_status_to_str(blk_status_t);
 
 #endif /* _BCACHFES_ERRCODE_H */
 
        u8 *p;
 
        if (in >= end)
-               return -1;
+               return -BCH_ERR_inode_unpack_error;
 
        if (!*in)
-               return -1;
+               return -BCH_ERR_inode_unpack_error;
 
        /*
         * position of highest set bit indicates number of bytes:
        bytes   = byte_table[shift - 1];
 
        if (in + bytes > end)
-               return -1;
+               return -BCH_ERR_inode_unpack_error;
 
        p = (u8 *) be + 16 - bytes;
        memcpy(p, in, bytes);
                return ret;                                             \
                                                                        \
        if (field_bits > sizeof(unpacked->_name) * 8)                   \
-               return -1;                                              \
+               return -BCH_ERR_inode_unpack_error;                     \
                                                                        \
        unpacked->_name = field[1];                                     \
        in += ret;
                                                                        \
        unpacked->_name = v[0];                                         \
        if (v[1] || v[0] != unpacked->_name)                            \
-               return -1;                                              \
+               return -BCH_ERR_inode_unpack_error;                     \
        fieldnr++;
 
        BCH_INODE_FIELDS_v2()
                                                                        \
        unpacked->_name = v[0];                                         \
        if (v[1] || v[0] != unpacked->_name)                            \
-               return -1;                                              \
+               return -BCH_ERR_inode_unpack_error;                     \
        fieldnr++;
 
        BCH_INODE_FIELDS_v3()
 
 #include <valgrind/memcheck.h>
 #endif
 
+#include "errcode.h"
 #include "varint.h"
 
 /**
        u64 v;
 
        if (unlikely(in + bytes > end))
-               return -1;
+               return -BCH_ERR_varint_decode_error;
 
        if (likely(bytes < 9)) {
                __le64 v_le = 0;
        unsigned bytes = ffz(*in) + 1;
 
        if (unlikely(in + bytes > end))
-               return -1;
+               return -BCH_ERR_varint_decode_error;
 
        if (likely(bytes < 9)) {
                v >>= bytes;