#!/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: %s ... " "$size_str"
# Read 'size' bytes in one syscall and count actual bytes read
bytes_read=$(dd status=none if=/dev/zero count=1 bs="$size" 2>/dev/null | wc -c)
# Check if we got fewer bytes than requested (short read)
if [ "$prev_size" -gt 0 ] && [ "$bytes_read" -lt "$size" ]; then
echo "LIMIT REACHED"
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 %s - %d bytes ... " "$initial_high_str" "$subtracted"
# Test if this size works - check if we get all bytes
bytes_read=$(dd status=none if=/dev/zero count=1 bs="$mid" 2>/dev/null | wc -c)
if [ "$bytes_read" -eq "$mid" ]; then
echo "OK"
low=$mid
else
echo "FAIL"
high=$mid
fi
done
echo ""
echo "======================================="
echo " MAXIMUM SYSCALL I/O SIZE: $low bytes"
echo "======================================="
printf " Decimal: %d\n" "$low"
printf " Hex: 0x%x\n" "$low"
echo ""
exit 0
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