Strict limit of write cache / 0s sync time policy for usb devices by default

I’ll add here my final solution. Now, I have zero problem with any usb devices and the speed is good, and the progress bar is accurate on the GUI.

File: /etc/udev/rules.d/99-usb-sync.rules

KERNEL!="sd[a-z]", GOTO="limit_write_cache_end"
ENV{ID_USB_TYPE}!="disk", GOTO="limit_write_cache_end"
ACTION!="add|change", GOTO="limit_write_cache_end"


# If it is identified as a thumb drive / usb-stick force sync for udisks2
# ENV{ID_DRIVE_THUMB}=="1", ENV{ID_FS_USAGE}=="filesystem", ENV{ID_FS_TYPE}!=vfat, ENV{UDISKS_MOUNT_OPTIONS_DEFAULTS}+="sync", ENV{UDISKS_MOUNT_OPTIONS_ALLOW}+="sync", GOTO="limit_write_cache_end"

# 09 -> exclude speed of hubs
ATTRS{bDeviceClass}!="09", ATTRS{speed}=="10000", RUN+="/usr/local/bin/usb_bdi_limit %s{speed} %k", GOTO="limit_write_cache_end"
ATTRS{bDeviceClass}!="09", ATTRS{speed}=="5000",  RUN+="/usr/local/bin/usb_bdi_limit %s{speed} %k", GOTO="limit_write_cache_end"
ATTRS{bDeviceClass}!="09", ATTRS{speed}=="480",   RUN+="/usr/local/bin/usb_bdi_limit %s{speed} %k", GOTO="limit_write_cache_end"
ATTRS{bDeviceClass}!="09", ATTRS{speed}=="12",    RUN+="/usr/local/bin/usb_bdi_limit %s{speed} %k", GOTO="limit_write_cache_end"

LABEL="limit_write_cache_end"

File: /usr/local/bin/usb_bdi_limit

#!/usr/bin/env bash

LANG=C
LC_NUMERIC=C

SPEED="$1"
BLOCKDEVICE="$2"
KERNEL_MAJOR_VERSION=$(uname -r | awk -F'.' '{print $1}')


if [[ $KERNEL_MAJOR_VERSION -ge 6 ]]; then

    # the following rules are introduced with kernel 6.1
    # https://docs.kernel.org/admin-guide/abi-testing.html#abi-sys-class-bdi-bdi-strict-limit
    # https://docs.kernel.org/admin-guide/abi-testing.html#abi-sys-class-bdi-bdi-max-bytes

    BUFFER_TIME="0.05"
    SAFETY_FACTOR="1.3"
    BUFFER_SIZE=$(printf '%.0f' `echo "( ($SPEED / 8) * $BUFFER_TIME * $SAFETY_FACTOR) * 1024 * 1024" | bc`)

    # for x in 12 480 5000 10000; do echo -n "$x -> " ;printf "%.0f\n" ` echo "(($x / 8) * 0.05 * 1.3) * 1024 * 1024" | bc`; done
    # 62915
    # 4089446
    # 42593157
    # 85196800

    [[ -n $(which hdparm) ]] && $(which hdparm) -W 0 /dev/$BLOCKDEVICE
    echo "$BUFFER_SIZE" > /sys/block/$BLOCKDEVICE/bdi/max_bytes
    echo 1 > /sys/block/$BLOCKDEVICE/bdi/strict_limit

    echo ""

elif [[ $KERNEL_MAJOR_VERSION -le 5 ]]; then
    # the following rule is introduced with kernel 2.6
    # https://docs.kernel.org/admin-guide/abi-testing.html#abi-sys-class-bdi-bdi-max-ratio

    # 1% of available RAM ->  8046522kB -> 80.465kB -> 80MB
    echo 1 > /sys/block/$BLOCKDEVICE/bdi/max_ratio

fi
3 Likes