#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2019 SUSE Linux Products GmbH. All Rights Reserved. # # FS QA Test 194 # # Test if btrfs can handle large device ids. # # The regression is introduced by kernel commit ab4ba2e13346 ("btrfs: # tree-checker: Verify dev item"). # The fix is titled: "btrfs: tree-checker: Fix wrong check on max devid" # seq=`basename $0` seqres=$RESULT_DIR/$seq echo "QA output created by $seq" here=`pwd` tmp=/tmp/$$ status=1 # failure is the default! trap "_cleanup; exit \$status" 0 1 2 3 15 _cleanup() { cd / rm -f $tmp.* } # get standard environment, filters and checks . ./common/rc . ./common/filter # remove previous $seqres.full before test rm -f $seqres.full # real QA test starts here # Modify as appropriate. _supported_fs btrfs _require_scratch_dev_pool 2 _scratch_dev_pool_get 2 # Here we use 4k node size to reduce runtime (explained near _scratch_mkfs call) # To use the minimal node size (4k) we need 4K page size. if [ $(get_page_size) != 4096 ]; then _notrun "This test need 4k page size" fi device_1=$(echo $SCRATCH_DEV_POOL | awk '{print $1}') device_2=$(echo $SCRATCH_DEV_POOL | awk '{print $2}') echo device_1=$device_1 device_2=$device_2 >> $seqres.full # The wrong check limit is based on the max item size (BTRFS_MAX_DEVS() macro), # and max item size is based on node size, so smaller node size will result # much shorter runtime. So here we use minimal node size (4K) to reduce runtime. _scratch_mkfs -n 4k >> $seqres.full _scratch_mount # For 4k nodesize, the wrong limit is calculated by: # ((4096 - 101 - 25 - 80) / 32) + 1 # | | | | |- sizeof(btrfs_stripe) # | | | |- sizeof(btrfs_chunk) # | | |- sizeof(btrfs_item) # | |- sizeof(btrfs_header) # |- node size # Which is 122. # # The old limit is wrong because it doesn't take devid holes into consideration. # We can have large devid, but still have only 1 device. # # Add and remove device in a loop, each iteration will increase devid by 2. # So by 64 iterations, we will definitely hit that 122 limit. for (( i = 0; i < 64; i++ )); do $BTRFS_UTIL_PROG device add -f $device_2 $SCRATCH_MNT $BTRFS_UTIL_PROG device del $device_1 $SCRATCH_MNT $BTRFS_UTIL_PROG device add -f $device_1 $SCRATCH_MNT $BTRFS_UTIL_PROG device del $device_2 $SCRATCH_MNT done _scratch_dev_pool_put echo "Silence is golden" # success, all done status=0 exit