| #! /bin/bash | 
 | # SPDX-License-Identifier: GPL-2.0 | 
 | # Copyright (c) 2016, Oracle and/or its affiliates.  All Rights Reserved. | 
 | # | 
 | # FS QA Test No. 176 | 
 | # | 
 | # See how well reflink handles reflinking a file with a million extents. | 
 | # | 
 | . ./common/preamble | 
 | _begin_fstest auto clone punch | 
 |  | 
 | # Import common functions. | 
 | . ./common/filter | 
 | . ./common/attr | 
 | . ./common/reflink | 
 |  | 
 | _require_scratch_reflink | 
 | _require_cp_reflink | 
 | _require_xfs_io_command "fpunch" | 
 | _require_test_program "punch-alternating" | 
 |  | 
 | rm -f "$seqres.full" | 
 |  | 
 | echo "Format and mount" | 
 | _scratch_mkfs > "$seqres.full" 2>&1 | 
 | _scratch_mount >> "$seqres.full" 2>&1 | 
 |  | 
 | testdir="$SCRATCH_MNT/test-$seq" | 
 | mkdir "$testdir" | 
 |  | 
 | # Setup for one million blocks, but we'll accept stress testing down to | 
 | # 2^17 blocks... that should be plenty for anyone. | 
 | fnr=20 | 
 | free_blocks=$(stat -f -c '%a' "$testdir") | 
 | blksz=$(_get_block_size "$testdir") | 
 | space_avail=$((free_blocks * blksz)) | 
 | calc_space() { | 
 | 	blocks_needed=$(( 2 ** (fnr + 1) )) | 
 | 	space_needed=$((blocks_needed * blksz * 5 / 4)) | 
 | } | 
 | calc_space | 
 | while test $space_needed -gt $space_avail; do | 
 | 	fnr=$((fnr - 1)) | 
 | 	calc_space | 
 | done | 
 | test $fnr -lt 17 && _notrun "Insufficient space for stress test; would only create $blocks_needed extents." | 
 |  | 
 | echo "Create a many-block file" | 
 | echo "creating $blocks_needed blocks..." >> "$seqres.full" | 
 | $XFS_IO_PROG -f -c "pwrite -S 0x61 -b 4194304 0 $((2 ** (fnr + 1) * blksz))" "$testdir/file1" >> "$seqres.full" | 
 | echo "punching..." >> "$seqres.full" | 
 | "$here/src/punch-alternating" "$testdir/file1" >> "$seqres.full" | 
 | echo "...done" >> "$seqres.full" | 
 | _scratch_cycle_mount | 
 |  | 
 | echo "Reflink the big file" | 
 | bytes=$((blocks_needed * blksz)) | 
 | echo "reflinking $((blocks_needed / 2)) blocks, $((bytes / 2)) bytes" >> "$seqres.full" | 
 | _reflink_range "$testdir/file1" 0 "$testdir/file2" 0 $bytes >> "$seqres.full" | 
 |  | 
 | # success, all done | 
 | status=0 | 
 | exit |