#!/usr/bin/env bash . $(dirname $(readlink -e "${BASH_SOURCE[0]}"))/bcachefs-test-libs.sh config-scratch-devs 16G config-scratch-devs 4G test_snapshots_simple() { NR_SNAPS=1 bcachefs_antagonist run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt pushd /mnt for i in `seq 0 $NR_SNAPS`; do dd if=/dev/zero of=/mnt/foo bs=1M count=1 oflag=direct bcachefs subvolume snapshot snap-$i done popd umount /mnt sleep 0.2 bcachefs fsck -n ${ktest_scratch_dev[0]} exit for i in `seq 0 $NR_SNAPS|sort -r`; do umount /mnt sleep 0.2 bcachefs fsck -n ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt echo "deleting snap-$i" bcachefs subvolume delete /mnt/snap-$i df -h /mnt done umount /mnt sleep 0.2 mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt umount /mnt check_counters ${ktest_scratch_dev[0]} } test_files_many() { #bcachefs_antagonist run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt for i in $(seq 0 1000001); do echo $i > /mnt/$i done umount /mnt sleep 0.2 time mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt umount /mnt check_counters ${ktest_scratch_dev[0]} } d_test_snapshots_many() { #bcachefs_antagonist run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt cd /mnt for i in $(seq 0 1000001); do bcachefs subvolume snapshot "snap_$(date -u +%F-%H%M%_S%N)" echo $i > snap_number done umount /mnt sleep 0.2 mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt umount /mnt check_counters ${ktest_scratch_dev[0]} } test_dbench() { # so wait doesn't hang [[ $(jobs -p) != "" ]] && kill $(jobs -p) NR_SNAPS=10 run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt ( cd /mnt for i in `seq 0 $NR_SNAPS`; do sleep 1 bcachefs subvolume snapshot snap-$i done ) & dbench -S -t $NR_SNAPS 1 -D /mnt/ wait df -h /mnt for i in `seq 0 $NR_SNAPS|sort -r`; do echo "deleting snap-$i" bcachefs subvolume delete /mnt/snap-$i df -h /mnt done umount /mnt sleep 0.2 #bcachefs fsck -n ${ktest_scratch_dev[0]} mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt df -h /mnt umount /mnt check_counters ${ktest_scratch_dev[0]} } test_reflink() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt pushd /mnt cp -a /usr . bcachefs subvolume snapshot snap-$i cp -r --reflink usr usr2 popd umount /mnt check_counters ${ktest_scratch_dev[0]} } d_test_finsert() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt pushd /mnt dd if=/dev/zero of=foo bs=1M count=8 oflag=direct bcachefs subvolume snapshot snap-$i xfs_io -c "finsert 1024 1024" foo popd umount /mnt check_counters ${ktest_scratch_dev[0]} } d_test_snapshots_fio() { # so wait doesn't hang [[ $(jobs -p) != "" ]] && kill $(jobs -p) run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt fallocate -l500M /mnt/fiotest ( cd /mnt for i in `seq 0 10`; do sleep 2 bcachefs subvolume snapshot snap-$i done ) & fio --eta=always \ --eta-interval=1s \ --exitall_on_error=1 \ --randrepeat=0 \ --ioengine=libaio \ --iodepth=64 \ --iodepth_batch=16 \ --direct=1 \ --numjobs=1 \ --verify=crc32c \ --verify_fatal=1 \ --verify_async=1 \ --filename=/mnt/fiotest \ --filesize=1G \ --io_size=12G \ --fallocate=none \ --name=randwrite \ --rw=randwrite \ --bsrange=4k-32k || true wait df -h /mnt for i in `seq 0 10`; do fio --eta=always \ --eta-interval=1s \ --exitall_on_error=1 \ --randrepeat=0 \ --ioengine=libaio \ --iodepth=64 \ --iodepth_batch=16 \ --direct=1 \ --numjobs=1 \ --verify=crc32c \ --verify_only=1 \ --filename=/mnt/snap-$i/fiotest \ --filesize=1G \ --io_size=12G \ --fallocate=none \ --name=randwrite \ --rw=randwrite \ --bsrange=4k-32k || true done for i in `seq 0 10|sort -r`; do umount /mnt sleep 0.1 mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt echo "deleting snap-$i" cd /mnt bcachefs subvolume delete snap-$i df -h /mnt cd / done umount /mnt sleep 0.1 mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt df -h /mnt umount /mnt check_counters ${ktest_scratch_dev[0]} } test_subvol_create() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 touch /mnt/foo mv /mnt/foo /mnt/subvolume_1 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_delete() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 rm -rf /mnt/subvolume_1 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_create_delete() { bcachefs_antagonist run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/foo dd if=/dev/zero of=/mnt/foo/bar bs=100M count=1 oflag=direct bcachefs subvolume delete /mnt/foo bcachefs subvolume create /mnt/foo dd if=/dev/zero of=/mnt/foo/bar bs=100M count=1 oflag=direct umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} } test_subvol_snapshot_create() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 bcachefs subvolume snapshot /mnt/subvolume_1 /mnt/snapshot_1 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_snapshot_create_ro() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 bcachefs subvolume snapshot -r /mnt/subvolume_1 /mnt/snapshot_1 ! touch /mnt/snapshot_1/foo umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_snapshot_delete() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 bcachefs subvolume snapshot /mnt/subvolume_1 /mnt/snapshot_1 bcachefs subvolume delete /mnt/snapshot_1 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_snapshot_delete_create() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 bcachefs subvolume snapshot /mnt/subvolume_1 /mnt/snapshot_1 bcachefs subvolume delete /mnt/snapshot_1 bcachefs subvolume snapshot /mnt/subvolume_1 /mnt/snapshot_1 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } d_test_subvol_snapshot_rm() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 bcachefs subvolume snapshot /mnt/subvolume_1 /mnt/snapshot_1 rm -r /mnt/snapshot_1 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } # Create a subvolume, then snapshot the parent subvolume, then move the child # subvolume: test_mkdir_mv_snapshot() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt mkdir /mnt/dir1 bcachefs subvolume snapshot /mnt/ /mnt/snap1 mv /mnt/dir1 /mnt/dir2 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_mv_snapshot() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/sub1 bcachefs subvolume snapshot /mnt/ /mnt/snap1 mv /mnt/sub1 /mnt/sub2 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } # Test moving a subvol to another subvol test_subvol_mv_subvol() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/sub1 bcachefs subvolume create /mnt/sub2 mv /mnt/sub1 /mnt/sub2 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_snapshot_reuse_snapshot_name() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 bcachefs subvolume snapshot /mnt/subvolume_1 /mnt/snapshot_1 bcachefs subvolume delete /mnt/snapshot_1 bcachefs subvolume snapshot /mnt/subvolume_1 /mnt/snapshot_1 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_delete_snapshot_of_deleted_subvol() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/subvolume_1 bcachefs subvolume snapshot /mnt/subvolume_1 /mnt/snapshot_1 rm -rf /mnt/subvolume_1 bcachefs subvolume delete /mnt/snapshot_1 umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_snapshot_delete_repeat() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt for i in $(seq 1 64); do bcachefs subvolume snapshot /mnt/$i bcachefs subvolume delete /mnt/$i done umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_subvol_snapshot_delete_fio() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt for i in $(seq 1 10); do #run_fio_randrw --filesize=500M --bs=4k dd if=/dev/zero of=/mnt/test bs=4k count=1024 oflag=direct bcachefs subvolume snapshot /mnt/$i done for i in $(seq 1 10); do umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt done umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} check_counters ${ktest_scratch_dev[0]} } test_snapshot_copygc() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt for i in $(seq 1 4); do run_fio_randrw --filesize=1000M --loops=4 --bs=4k bcachefs subvolume snapshot /mnt/$i done bcachefs fs usage -h /mnt umount /mnt check_counters ${ktest_scratch_dev[0]} } test_snapshot_many_overwrite() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt for i in $(seq 1 100); do echo foo > /mnt/test bcachefs subvolume snapshot /mnt/snap.$i done bcachefs fs usage -h /mnt umount /mnt check_counters ${ktest_scratch_dev[0]} } test_snapshot_prjquota() { run_quiet "" bcachefs format -f --errors=panic --prjquota ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt echo foo > /mnt/test bcachefs subvolume snapshot /mnt/snap.$i bcachefs fs usage -h /mnt umount /mnt mount -t bcachefs ${ktest_scratch_dev[0]} /mnt umount /mnt check_counters ${ktest_scratch_dev[0]} } md5sum_file() { md5sum $1|cut -d\ -f1 } check_snapshot_md5sum() { local i=$1 local sum=/mnt/fiotest.sum.$i echo "checking $sum" if [[ ! $(<$sum) = $(md5sum_file /mnt/snap.$i/fiotest) ]]; then echo "md5sums do not match for $sum and /mnt/snap.$i/fiotest" echo $(<$sum) md5sum_file /mnt/snap.$i/fiotest return 1 fi } check_snapshot_md5sums() { local snap for snap in $(ls /mnt|grep '^snap.' || true); do echo "about to check $snap" check_snapshot_md5sum ${snap##snap.} done } run_snapshot_fio() { local filename=$1 shift fio --exitall_on_error=1 \ --minimal \ --randrepeat=1 \ --ioengine=libaio \ --iodepth=64 \ --iodepth_batch=16 \ --direct=1 \ --numjobs=1 \ --thread \ --verify=meta \ --verify_fatal=1 \ --overwrite=1 \ --filesize=500M \ --io_size=200M \ --bsrange=4k-64k \ --name=randrw \ --stats=0 \ --disable_bw=1 \ --rw=randrw \ --filename=$filename \ "$@" } test_snapshot_sums() { run_quiet "" bcachefs format -f --errors=panic --prjquota ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt local i for i in $(seq 0 10); do run_snapshot_fio /mnt/fiotest md5sum_file /mnt/fiotest > /mnt/fiotest.sum.$i echo "creating snapshot $i" bcachefs subvolume snapshot /mnt/snap.$i done check_snapshot_md5sums local snap for snap in $(echo /mnt/snap.*|sort -R); do umount /mnt mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt bcachefs subvolume delete $snap check_snapshot_md5sums done umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} } test_snapshot_rw() { run_quiet "" bcachefs format -f --errors=panic ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt local i for i in $(seq 0 10); do [[ -f /mnt/fiotest ]] && run_snapshot_fio /mnt/fiotest --verify_only=1 run_snapshot_fio /mnt/fiotest echo "creating snapshot $i" bcachefs subvolume snapshot /mnt/snap.$i md5sum_file /mnt/snap.$i/fiotest > /mnt/fiotest.sum.$i for snap in /mnt/snap.*; do local j=${snap##/mnt/snap.} check_snapshot_md5sum $j run_snapshot_fio /mnt/snap.$j/fiotest --verify_only=1 run_snapshot_fio /mnt/snap.$j/fiotest md5sum_file /mnt/snap.$j/fiotest > /mnt/fiotest.sum.$j done done check_snapshot_md5sums local snap for snap in $(echo /mnt/snap.*|sort -R); do umount /mnt mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt bcachefs subvolume delete $snap sleep 1 check_snapshot_md5sums done umount /mnt bcachefs fsck -n ${ktest_scratch_dev[0]} } test_snapshot_implicit_source() { run_quiet "" bcachefs format -f ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt mkdir /mnt/d bcachefs subvolume snapshot /mnt/d/snp1 umount /mnt mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt umount /mnt } test_delete_subvol_nested() { run_quiet "" bcachefs format -f ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/a bcachefs subvolume create /mnt/a/b ! bcachefs subvolume delete /mnt/a umount /mnt bcachefs fsck -ny ${ktest_scratch_dev[0]} } test_snapshot_file_delete() { run_quiet "" bcachefs format -f --shard_inode_numbers=0 ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt #dd if=/dev/zero of=/mnt/foo bs=4k count=8 oflag=direct touch /mnt/foo bcachefs subvolume snapshot /mnt/snapshot rm /mnt/snapshot/foo rm /mnt/foo umount /mnt mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt umount /mnt } test_subvol_mv() { run_quiet "" bcachefs format -f ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt bcachefs subvolume create /mnt/a bcachefs subvolume create /mnt/a/b mv /mnt/a/b /mnt umount /mnt bcachefs fsck ${ktest_scratch_dev[0]} } test_subvol_rmdir_empty_snapshot() { run_quiet "" bcachefs format -f ${ktest_scratch_dev[0]} mount -t bcachefs ${ktest_scratch_dev[0]} /mnt cd /mnt bcachefs subvolume create ./sub cd sub bcachefs subvolume create ./sub2 bcachefs subvolume snapshot . ./snap rmdir ./snap cd / umount /mnt bcachefs fsck ${ktest_scratch_dev[0]} } test_snapshot_reflink() { run_quiet "" bcachefs format -f ${ktest_scratch_dev[0]} mount -t bcachefs -o noinline_data ${ktest_scratch_dev[0]} /mnt cp /usr/bin/cp /mnt/file #echo Test > /mnt/file bcachefs subvolume snapshot /mnt/snapshot cp --reflink=always /mnt/snapshot/file /mnt/file1 rm /mnt/file cp --reflink=always /mnt/snapshot/file /mnt/file2 md5sum /mnt/file* /mnt/snapshot/file /usr/bin/cp umount /mnt mount -t bcachefs -o fsck ${ktest_scratch_dev[0]} /mnt umount /mnt } main "$@"