Hi Qu,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on kdave/for-next]
[also build test WARNING on v5.8 next-20200810]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url:
https://github.com/0day-ci/linux/commits/Qu-Wenruo/btrfs-Enhanced-runtime...
base:
https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
config: arm-randconfig-r025-20200810 (attached as .config)
compiler: clang version 12.0.0 (
https://github.com/llvm/llvm-project
3a34228bff6fdf45b50cb57cf5fb85d659eeb672)
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 arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm
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 >>):
In file included from fs/btrfs/extent-tree.c:20:
In file included from fs/btrfs/tree-log.h:9:
fs/btrfs/ctree.h:2265:8: warning: 'const' type qualifier on return type has no
effect [-Wignored-qualifiers]
size_t __const btrfs_get_num_csums(void);
^~~~~~~~
In file included from fs/btrfs/extent-tree.c:28:
fs/btrfs/sysfs.h:16:14: warning: 'const' type qualifier on return type has no
effect [-Wignored-qualifiers]
const char * const btrfs_feature_set_name(enum btrfs_feature_set set);
^~~~~~
> fs/btrfs/extent-tree.c:3157:8: warning: format specifies type
'unsigned long' but the argument has type 'unsigned int' [-Wformat]
sizeof(*ei) + sizeof(*bi));
^~~~~~~~~~~~~~~~~~~~~~~~~
fs/btrfs/ctree.h:3101:41: note: expanded from macro 'btrfs_crit'
btrfs_printk(fs_info, KERN_CRIT fmt, ##args)
~~~ ^~~~
3 warnings generated.
vim +3157 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 goto err_dump_abort;
3064 }
3065 /* Must be SHARED_* item, remove the backref first */
3066 ret = remove_extent_backref(trans, path, NULL,
3067 refs_to_drop,
3068 is_data, &last_ref);
3069 if (ret) {
3070 btrfs_abort_transaction(trans, ret);
3071 goto out;
3072 }
3073 btrfs_release_path(path);
3074 path->leave_spinning = 1;
3075
3076
3077 /* Slow path to locate EXTENT/METADATA_ITEM */
3078 key.objectid = bytenr;
3079 key.type = BTRFS_EXTENT_ITEM_KEY;
3080 key.offset = num_bytes;
3081
3082 if (!is_data && skinny_metadata) {
3083 key.type = BTRFS_METADATA_ITEM_KEY;
3084 key.offset = owner_objectid;
3085 }
3086
3087 ret = btrfs_search_slot(trans, extent_root,
3088 &key, path, -1, 1);
3089 if (ret > 0 && skinny_metadata && path->slots[0]) {
3090 /*
3091 * Couldn't find our skinny metadata item,
3092 * see if we have ye olde extent item.
3093 */
3094 path->slots[0]--;
3095 btrfs_item_key_to_cpu(path->nodes[0], &key,
3096 path->slots[0]);
3097 if (key.objectid == bytenr &&
3098 key.type == BTRFS_EXTENT_ITEM_KEY &&
3099 key.offset == num_bytes)
3100 ret = 0;
3101 }
3102
3103 if (ret > 0 && skinny_metadata) {
3104 skinny_metadata = false;
3105 key.objectid = bytenr;
3106 key.type = BTRFS_EXTENT_ITEM_KEY;
3107 key.offset = num_bytes;
3108 btrfs_release_path(path);
3109 ret = btrfs_search_slot(trans, extent_root,
3110 &key, path, -1, 1);
3111 }
3112
3113 if (ret) {
3114 btrfs_err(info,
3115 "umm, got %d back from search, was looking for %llu",
3116 ret, bytenr);
3117 if (ret > 0)
3118 btrfs_print_leaf(path->nodes[0]);
3119 }
3120 if (ret < 0) {
3121 btrfs_abort_transaction(trans, ret);
3122 goto out;
3123 }
3124 extent_slot = path->slots[0];
3125 }
3126 } else if (WARN_ON(ret == -ENOENT)) {
3127 btrfs_print_leaf(path->nodes[0]);
3128 btrfs_err(info,
3129 "unable to find ref byte nr %llu parent %llu root %llu owner %llu offset
%llu",
3130 bytenr, parent, root_objectid, owner_objectid,
3131 owner_offset);
3132 btrfs_abort_transaction(trans, ret);
3133 goto out;
3134 } else {
3135 btrfs_abort_transaction(trans, ret);
3136 goto out;
3137 }
3138
3139 leaf = path->nodes[0];
3140 item_size = btrfs_item_size_nr(leaf, extent_slot);
3141 if (unlikely(item_size < sizeof(*ei))) {
3142 ret = -EINVAL;
3143 btrfs_print_v0_err(info);
3144 btrfs_abort_transaction(trans, ret);
3145 goto out;
3146 }
3147 ei = btrfs_item_ptr(leaf, extent_slot,
3148 struct btrfs_extent_item);
3149 if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID &&
3150 key.type == BTRFS_EXTENT_ITEM_KEY) {
3151 struct btrfs_tree_block_info *bi;
3152 if (unlikely(item_size < sizeof(*ei) + sizeof(*bi))) {
3153 btrfs_crit(info,
3154 "invalid extent item size for key (%llu, %u, %llu) owner %llu, has %u expect
>= %lu",
3155 key.objectid, key.type, key.offset,
3156 owner_objectid, item_size,
3157 sizeof(*ei) + sizeof(*bi));
3158 goto
err_dump_abort;
3159 }
3160 bi = (struct btrfs_tree_block_info *)(ei + 1);
3161 WARN_ON(owner_objectid != btrfs_tree_block_level(leaf, bi));
3162 }
3163
3164 refs = btrfs_extent_refs(leaf, ei);
3165 if (refs < refs_to_drop) {
3166 btrfs_crit(info,
3167 "trying to drop %d refs but we only have %Lu for bytenr %Lu",
3168 refs_to_drop, refs, bytenr);
3169 goto err_dump_abort;
3170 }
3171 refs -= refs_to_drop;
3172
3173 if (refs > 0) {
3174 if (extent_op)
3175 __run_delayed_extent_op(extent_op, leaf, ei);
3176 /*
3177 * In the case of inline back ref, reference count will
3178 * be updated by remove_extent_backref
3179 */
3180 if (iref) {
3181 if (unlikely(!found_extent)) {
3182 btrfs_crit(info,
3183 "invalid iref, got inlined extent ref but no EXTENT/METADATA_ITEM
found");
3184 goto err_dump_abort;
3185 }
3186 } else {
3187 btrfs_set_extent_refs(leaf, ei, refs);
3188 btrfs_mark_buffer_dirty(leaf);
3189 }
3190 if (found_extent) {
3191 ret = remove_extent_backref(trans, path, iref,
3192 refs_to_drop, is_data,
3193 &last_ref);
3194 if (ret) {
3195 btrfs_abort_transaction(trans, ret);
3196 goto out;
3197 }
3198 }
3199 } else {
3200 /* In this branch refs == 1 */
3201 if (found_extent) {
3202 if (is_data && refs_to_drop !=
3203 extent_data_ref_count(path, iref)) {
3204 btrfs_crit(info,
3205 "invalid refs_to_drop, current refs %u refs_to_drop %u",
3206 extent_data_ref_count(path, iref),
3207 refs_to_drop);
3208 goto err_dump_abort;
3209 }
3210 if (iref) {
3211 if (path->slots[0] != extent_slot) {
3212 btrfs_crit(info,
3213 "invalid iref, extent item key (%llu %u %llu) doesn't has wanted
iref",
3214 key.objectid, key.type,
3215 key.offset);
3216 goto err_dump_abort;
3217 }
3218 } else {
3219 /*
3220 * No inline ref, we must at SHARED_* item,
3221 * And it's single ref, it must be:
3222 * | extent_slot ||extent_slot + 1|
3223 * [ EXTENT/METADATA_ITEM ][ SHARED_* ITEM ]
3224 */
3225 if (path->slots[0] != extent_slot + 1) {
3226 btrfs_crit(info,
3227 "invalid SHARED_* item, previous item is not EXTENT/METADATA_ITEM");
3228 goto err_dump_abort;
3229 }
3230 path->slots[0] = extent_slot;
3231 num_to_del = 2;
3232 }
3233 }
3234
3235 last_ref = 1;
3236 ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
3237 num_to_del);
3238 if (ret) {
3239 btrfs_abort_transaction(trans, ret);
3240 goto out;
3241 }
3242 btrfs_release_path(path);
3243
3244 if (is_data) {
3245 ret = btrfs_del_csums(trans, info->csum_root, bytenr,
3246 num_bytes);
3247 if (ret) {
3248 btrfs_abort_transaction(trans, ret);
3249 goto out;
3250 }
3251 }
3252
3253 ret = add_to_free_space_tree(trans, bytenr, num_bytes);
3254 if (ret) {
3255 btrfs_abort_transaction(trans, ret);
3256 goto out;
3257 }
3258
3259 ret = btrfs_update_block_group(trans, bytenr, num_bytes, 0);
3260 if (ret) {
3261 btrfs_abort_transaction(trans, ret);
3262 goto out;
3263 }
3264 }
3265 btrfs_release_path(path);
3266
3267 out:
3268 btrfs_free_path(path);
3269 return ret;
3270 err_dump_abort:
3271 /*
3272 * Leaf dump can take up a lot of dmesg buffer since default nodesize
3273 * is already 16K.
3274 * So we only do full leaf dump for debug build.
3275 */
3276 if (IS_ENABLED(CONFIG_BTRFS_DEBUG)) {
3277 btrfs_crit(info, "path->slots[0]=%d extent_slot=%d",
3278 path->slots[0], extent_slot);
3279 btrfs_print_leaf(path->nodes[0]);
3280 }
3281
3282 btrfs_abort_transaction(trans, -EUCLEAN);
3283 btrfs_free_path(path);
3284 return -EUCLEAN;
3285 }
3286
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org