tree:
https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
head: 7d05f2ecdd40cd928efc3feb0bfdc965aa5c89a9
commit: c950c6b7b34112061fc6acd30dc906f095a95a3d [59/70] btrfs: extent-tree: kill BUG_ON()
in __btrfs_free_extent() and do better comment
config: powerpc64-randconfig-r003-20200820 (attached as .config)
compiler: clang version 12.0.0 (
https://github.com/llvm/llvm-project
4deda57106f7c9b982a49cb907c33e3966c8de7f)
reproduce (this is a W=1 build):
wget
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O
~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc64 cross compiling tool for clang build
# apt-get install binutils-powerpc64-linux-gnu
git checkout c950c6b7b34112061fc6acd30dc906f095a95a3d
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All warnings (new ones prefixed by >>):
> fs/btrfs/extent-tree.c:3158:8: warning: format specifies type
'unsigned long' but the argument has type 'unsigned int' [-Wformat]
sizeof(*ei) + sizeof(*bi));
^~~~~~~~~~~~~~~~~~~~~~~~~
fs/btrfs/ctree.h:3104:41: note: expanded from macro 'btrfs_crit'
btrfs_printk(fs_info, KERN_CRIT fmt, ##args)
~~~ ^~~~
1 warning generated.
#
https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git/commit/?i...
git remote add kdave
https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git
git fetch --no-tags kdave for-next
git checkout c950c6b7b34112061fc6acd30dc906f095a95a3d
vim +3158 fs/btrfs/extent-tree.c
2932
2933 /*
2934 * Real work happens here to drop one or more refs of @node.
2935 *
2936 * The work is mostly done in two parts:
2937 * 1. Locate the extent refs.
2938 * It's either inlined in EXTENT/METADATA_ITEM or in keyed SHARED_* item.
2939 * Locate it then reduces the refs number or remove the ref line completely.
2940 *
2941 * 2. Update the refs count in EXTENT/METADATA_ITEM
2942 *
2943 * Due to the above two operations and possible optimizations, the function
2944 * is a little hard to read, but with the following examples, the result
2945 * of this function should be pretty easy to get.
2946 *
2947 * Example:
2948 * *** Inlined backref case ***
2949 * In extent tree we have:
2950 * item 0 key (13631488 EXTENT_ITEM 1048576) itemoff 16201 itemsize 82
2951 * refs 2 gen 6 flags DATA
2952 * extent data backref root FS_TREE objectid 258 offset 0 count 1
2953 * extent data backref root FS_TREE objectid 257 offset 0 count 1
2954 *
2955 * This function get called with
2956 * node->bytenr = 13631488, node->num_bytes = 1048576
2957 * root_objectid = FS_TREE, owner_objectid = 257, owner_offset = 0,
2958 * refs_to_drop = 1
2959 * Then we should get some like:
2960 * item 0 key (13631488 EXTENT_ITEM 1048576) itemoff 16201 itemsize 82
2961 * refs 1 gen 6 flags DATA
2962 * extent data backref root FS_TREE objectid 258 offset 0 count 1
2963 *
2964 * *** Keyed backref case ***
2965 * In extent tree we have:
2966 * item 0 key (13631488 EXTENT_ITEM 1048576) itemoff 3971 itemsize 24
2967 * refs 754 gen 6 flags DATA
2968 * [...]
2969 * item 2 key (13631488 EXTENT_DATA_REF <HASH>) itemoff 3915 itemsize 28
2970 * extent data backref root FS_TREE objectid 866 offset 0 count 1
2971 * This function get called with
2972 * node->bytenr = 13631488, node->num_bytes = 1048576
2973 * root_objectid = FS_TREE, owner_objectid = 866, owner_offset = 0,
2974 * refs_to_drop = 1
2975 * Then we should get some like:
2976 * item 0 key (13631488 EXTENT_ITEM 1048576) itemoff 3971 itemsize 24
2977 * refs 753 gen 6 flags DATA
2978 * And that (13631488 EXTENT_DATA_REF <HASH>) get removed.
2979 */
2980 static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
2981 struct btrfs_delayed_ref_node *node, u64 parent,
2982 u64 root_objectid, u64 owner_objectid,
2983 u64 owner_offset, int refs_to_drop,
2984 struct btrfs_delayed_extent_op *extent_op)
2985 {
2986 struct btrfs_fs_info *info = trans->fs_info;
2987 struct btrfs_key key;
2988 struct btrfs_path *path;
2989 struct btrfs_root *extent_root = info->extent_root;
2990 struct extent_buffer *leaf;
2991 struct btrfs_extent_item *ei;
2992 struct btrfs_extent_inline_ref *iref;
2993 int ret;
2994 int is_data;
2995 int extent_slot = 0;
2996 int found_extent = 0;
2997 int num_to_del = 1;
2998 u32 item_size;
2999 u64 refs;
3000 u64 bytenr = node->bytenr;
3001 u64 num_bytes = node->num_bytes;
3002 int last_ref = 0;
3003 bool skinny_metadata = btrfs_fs_incompat(info, SKINNY_METADATA);
3004
3005 path = btrfs_alloc_path();
3006 if (!path)
3007 return -ENOMEM;
3008
3009 path->leave_spinning = 1;
3010
3011 is_data = owner_objectid >= BTRFS_FIRST_FREE_OBJECTID;
3012
3013 if (unlikely(!is_data && refs_to_drop != 1)) {
3014 btrfs_crit(info,
3015 "invalid refs_to_drop, dropping more than 1 refs for tree block %llu
refs_to_drop %u",
3016 node->bytenr, refs_to_drop);
3017 ret = -EINVAL;
3018 btrfs_abort_transaction(trans, ret);
3019 goto out;
3020 }
3021
3022 if (is_data)
3023 skinny_metadata = false;
3024
3025 ret = lookup_extent_backref(trans, path, &iref, bytenr, num_bytes,
3026 parent, root_objectid, owner_objectid,
3027 owner_offset);
3028 if (ret == 0) {
3029 /*
3030 * Either the inline backref or the SHARED_DATA_REF/
3031 * SHARED_BLOCK_REF is found
3032 *
3033 * Here is a quick path to locate EXTENT/METADATA_ITEM.
3034 * It's possible the EXTENT/METADATA_ITEM is near current slot.
3035 */
3036 extent_slot = path->slots[0];
3037 while (extent_slot >= 0) {
3038 btrfs_item_key_to_cpu(path->nodes[0], &key,
3039 extent_slot);
3040 if (key.objectid != bytenr)
3041 break;
3042 if (key.type == BTRFS_EXTENT_ITEM_KEY &&
3043 key.offset == num_bytes) {
3044 found_extent = 1;
3045 break;
3046 }
3047 if (key.type == BTRFS_METADATA_ITEM_KEY &&
3048 key.offset == owner_objectid) {
3049 found_extent = 1;
3050 break;
3051 }
3052
3053 /* Quick path didn't find the EXTEMT/METADATA_ITEM */
3054 if (path->slots[0] - extent_slot > 5)
3055 break;
3056 extent_slot--;
3057 }
3058
3059 if (!found_extent) {
3060 if (unlikely(iref)) {
3061 btrfs_crit(info,
3062 "invalid iref, no EXTENT/METADATA_ITEM found but has inline extent
ref");
3063 btrfs_abort_transaction(trans, -EUCLEAN);
3064 goto err_dump;
3065 }
3066 /* Must be SHARED_* item, remove the backref first */
3067 ret = remove_extent_backref(trans, path, NULL,
3068 refs_to_drop,
3069 is_data, &last_ref);
3070 if (ret) {
3071 btrfs_abort_transaction(trans, ret);
3072 goto out;
3073 }
3074 btrfs_release_path(path);
3075 path->leave_spinning = 1;
3076
3077
3078 /* Slow path to locate EXTENT/METADATA_ITEM */
3079 key.objectid = bytenr;
3080 key.type = BTRFS_EXTENT_ITEM_KEY;
3081 key.offset = num_bytes;
3082
3083 if (!is_data && skinny_metadata) {
3084 key.type = BTRFS_METADATA_ITEM_KEY;
3085 key.offset = owner_objectid;
3086 }
3087
3088 ret = btrfs_search_slot(trans, extent_root,
3089 &key, path, -1, 1);
3090 if (ret > 0 && skinny_metadata && path->slots[0]) {
3091 /*
3092 * Couldn't find our skinny metadata item,
3093 * see if we have ye olde extent item.
3094 */
3095 path->slots[0]--;
3096 btrfs_item_key_to_cpu(path->nodes[0], &key,
3097 path->slots[0]);
3098 if (key.objectid == bytenr &&
3099 key.type == BTRFS_EXTENT_ITEM_KEY &&
3100 key.offset == num_bytes)
3101 ret = 0;
3102 }
3103
3104 if (ret > 0 && skinny_metadata) {
3105 skinny_metadata = false;
3106 key.objectid = bytenr;
3107 key.type = BTRFS_EXTENT_ITEM_KEY;
3108 key.offset = num_bytes;
3109 btrfs_release_path(path);
3110 ret = btrfs_search_slot(trans, extent_root,
3111 &key, path, -1, 1);
3112 }
3113
3114 if (ret) {
3115 btrfs_err(info,
3116 "umm, got %d back from search, was looking for %llu",
3117 ret, bytenr);
3118 if (ret > 0)
3119 btrfs_print_leaf(path->nodes[0]);
3120 }
3121 if (ret < 0) {
3122 btrfs_abort_transaction(trans, ret);
3123 goto out;
3124 }
3125 extent_slot = path->slots[0];
3126 }
3127 } else if (WARN_ON(ret == -ENOENT)) {
3128 btrfs_print_leaf(path->nodes[0]);
3129 btrfs_err(info,
3130 "unable to find ref byte nr %llu parent %llu root %llu owner %llu offset
%llu",
3131 bytenr, parent, root_objectid, owner_objectid,
3132 owner_offset);
3133 btrfs_abort_transaction(trans, ret);
3134 goto out;
3135 } else {
3136 btrfs_abort_transaction(trans, ret);
3137 goto out;
3138 }
3139
3140 leaf = path->nodes[0];
3141 item_size = btrfs_item_size_nr(leaf, extent_slot);
3142 if (unlikely(item_size < sizeof(*ei))) {
3143 ret = -EINVAL;
3144 btrfs_print_v0_err(info);
3145 btrfs_abort_transaction(trans, ret);
3146 goto out;
3147 }
3148 ei = btrfs_item_ptr(leaf, extent_slot,
3149 struct btrfs_extent_item);
3150 if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID &&
3151 key.type == BTRFS_EXTENT_ITEM_KEY) {
3152 struct btrfs_tree_block_info *bi;
3153 if (unlikely(item_size < sizeof(*ei) + sizeof(*bi))) {
3154 btrfs_crit(info,
3155 "invalid extent item size for key (%llu, %u, %llu) owner %llu, has %u expect
>= %lu",
3156 key.objectid, key.type, key.offset,
3157 owner_objectid, item_size,
3158 sizeof(*ei) + sizeof(*bi));
3159 btrfs_abort_transaction(trans, -EUCLEAN);
3160 goto err_dump;
3161 }
3162 bi = (struct btrfs_tree_block_info *)(ei + 1);
3163 WARN_ON(owner_objectid != btrfs_tree_block_level(leaf, bi));
3164 }
3165
3166 refs = btrfs_extent_refs(leaf, ei);
3167 if (refs < refs_to_drop) {
3168 btrfs_crit(info,
3169 "trying to drop %d refs but we only have %Lu for bytenr %Lu",
3170 refs_to_drop, refs, bytenr);
3171 btrfs_abort_transaction(trans, -EUCLEAN);
3172 goto err_dump;
3173 }
3174 refs -= refs_to_drop;
3175
3176 if (refs > 0) {
3177 if (extent_op)
3178 __run_delayed_extent_op(extent_op, leaf, ei);
3179 /*
3180 * In the case of inline back ref, reference count will
3181 * be updated by remove_extent_backref
3182 */
3183 if (iref) {
3184 if (unlikely(!found_extent)) {
3185 btrfs_crit(info,
3186 "invalid iref, got inlined extent ref but no EXTENT/METADATA_ITEM
found");
3187 btrfs_abort_transaction(trans, -EUCLEAN);
3188 goto err_dump;
3189 }
3190 } else {
3191 btrfs_set_extent_refs(leaf, ei, refs);
3192 btrfs_mark_buffer_dirty(leaf);
3193 }
3194 if (found_extent) {
3195 ret = remove_extent_backref(trans, path, iref,
3196 refs_to_drop, is_data,
3197 &last_ref);
3198 if (ret) {
3199 btrfs_abort_transaction(trans, ret);
3200 goto out;
3201 }
3202 }
3203 } else {
3204 /* In this branch refs == 1 */
3205 if (found_extent) {
3206 if (is_data && refs_to_drop !=
3207 extent_data_ref_count(path, iref)) {
3208 btrfs_crit(info,
3209 "invalid refs_to_drop, current refs %u refs_to_drop %u",
3210 extent_data_ref_count(path, iref),
3211 refs_to_drop);
3212 btrfs_abort_transaction(trans, -EUCLEAN);
3213 goto err_dump;
3214 }
3215 if (iref) {
3216 if (path->slots[0] != extent_slot) {
3217 btrfs_crit(info,
3218 "invalid iref, extent item key (%llu %u %llu) doesn't has wanted
iref",
3219 key.objectid, key.type,
3220 key.offset);
3221 btrfs_abort_transaction(trans, -EUCLEAN);
3222 goto err_dump;
3223 }
3224 } else {
3225 /*
3226 * No inline ref, we must at SHARED_* item,
3227 * And it's single ref, it must be:
3228 * | extent_slot ||extent_slot + 1|
3229 * [ EXTENT/METADATA_ITEM ][ SHARED_* ITEM ]
3230 */
3231 if (path->slots[0] != extent_slot + 1) {
3232 btrfs_crit(info,
3233 "invalid SHARED_* item, previous item is not EXTENT/METADATA_ITEM");
3234 btrfs_abort_transaction(trans, -EUCLEAN);
3235 goto err_dump;
3236 }
3237 path->slots[0] = extent_slot;
3238 num_to_del = 2;
3239 }
3240 }
3241
3242 last_ref = 1;
3243 ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
3244 num_to_del);
3245 if (ret) {
3246 btrfs_abort_transaction(trans, ret);
3247 goto out;
3248 }
3249 btrfs_release_path(path);
3250
3251 if (is_data) {
3252 ret = btrfs_del_csums(trans, info->csum_root, bytenr,
3253 num_bytes);
3254 if (ret) {
3255 btrfs_abort_transaction(trans, ret);
3256 goto out;
3257 }
3258 }
3259
3260 ret = add_to_free_space_tree(trans, bytenr, num_bytes);
3261 if (ret) {
3262 btrfs_abort_transaction(trans, ret);
3263 goto out;
3264 }
3265
3266 ret = btrfs_update_block_group(trans, bytenr, num_bytes, 0);
3267 if (ret) {
3268 btrfs_abort_transaction(trans, ret);
3269 goto out;
3270 }
3271 }
3272 btrfs_release_path(path);
3273
3274 out:
3275 btrfs_free_path(path);
3276 return ret;
3277 err_dump:
3278 /*
3279 * Leaf dump can take up a lot of dmesg buffer since default nodesize
3280 * is already 16K.
3281 * So we only do full leaf dump for debug build.
3282 */
3283 if (IS_ENABLED(CONFIG_BTRFS_DEBUG)) {
3284 btrfs_crit(info, "path->slots[0]=%d extent_slot=%d",
3285 path->slots[0], extent_slot);
3286 btrfs_print_leaf(path->nodes[0]);
3287 }
3288
3289 btrfs_free_path(path);
3290 return -EUCLEAN;
3291 }
3292
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org