#!/bin/sh # # Find the maximum I/O size for a single read/write syscall # Uses binary search after detecting the approximate limit by doubling # # Works on Linux, BSD, and other POSIX systems set -eu # Start with 1 MB size=$((1024 * 1024)) prev_size=0 echo 'Finding maximum syscall I/O size...' echo 'Starting from 1 MB and doubling until limit is reached' echo while true; do # Convert size to human-readable format if [ "$size" -lt $((1024 * 1024)) ]; then size_kb=$((size / 1024)) size_str="$size_kb KB" elif [ "$size" -lt $((1024 * 1024 * 1024)) ]; then size_mb=$((size / 1024 / 1024)) size_str="$size_mb MB" else size_gb=$((size / 1024 / 1024 / 1024)) size_str="$size_gb GB" fi printf "Testing size: $size_str ... " # Read 'size' bytes in one syscall and count actual bytes read # Check if we got fewer bytes than requested (short read) if dd status=noxfer if=/dev/zero of=/dev/null count=1 bs="$size" 2>&1 | grep -q '^0+[0-9]'; then echo 'LIMIT REACHED' break fi echo OK # Save current size for next iteration prev_size=$size # Double the size for next iteration new_size=$((size * 2)) # Check for overflow (when doubling causes a negative number or smaller value) if [ "$new_size" -le "$size" ]; then echo echo 'Reached maximum representable size without hitting limit' echo "Maximum tested size: $size bytes ($size_str)" exit 0 fi size=$new_size done echo echo "Starting binary search between $prev_size and $size bytes..." echo # Binary search for exact limit low=$prev_size high=$size initial_high=$high # Calculate human-readable format for initial_high if [ "$initial_high" -lt $((1024 * 1024)) ]; then initial_high_kb=$((initial_high / 1024)) initial_high_str="${initial_high_kb} KB" elif [ "$initial_high" -lt $((1024 * 1024 * 1024)) ]; then initial_high_mb=$((initial_high / 1024 / 1024)) initial_high_str="${initial_high_mb} MB" else initial_high_gb=$((initial_high / 1024 / 1024 / 1024)) initial_high_str="${initial_high_gb} GB" fi while [ $((high - low)) -gt 1 ]; do mid=$(((low + high) / 2)) # Calculate how much we subtracted from initial_high subtracted=$((initial_high - mid)) printf " Trying $initial_high_str - $subtracted bytes ... " # Test if this size works - check if we get all bytes if dd status=noxfer if=/dev/zero of=/dev/null count=1 bs="$mid" 2>&1 | grep -q '^0+[0-9]'; then echo FAIL high=$mid else echo OK low=$mid fi done echo echo '=======================================' echo " MAXIMUM SYSCALL I/O SIZE: $low bytes" echo '=======================================' echo " Decimal: $low" printf " Hex: 0x%x\n" "$low" echo