udev-usb-sync/README.md

113 lines
3.8 KiB
Markdown
Raw Normal View History

2023-03-05 12:13:16 +01:00
# Disable write cache for usb storage devices
2023-03-05 07:54:25 +01:00
[Manjaro Forum topic][0]
2023-03-05 06:57:39 +01:00
2023-03-05 07:24:52 +01:00
## Linux filesystem cache
2023-03-05 07:12:21 +01:00
Linux agressively caches files in order to improve overall performance.
When copying large amount of files to an USB storage this often results in some wait time until the device can be safely removed.
How long you have to wait depends on your system and the quality of the USB storage device.
Numerous issues regarding this has resulted in various suggestions involving sysctl tweaks and trim.
udev rule to disable write-cache
2023-03-05 07:24:52 +01:00
## udev rule to disable write-cache
2023-03-05 08:03:13 +01:00
2023-03-05 07:12:21 +01:00
In another place one user threw in an udev rule which would disable write-cache for devices when they were added and while it was just an idea - it triggered my curiosity.
I dug into the intricacies of udev and found a method to only target USB storage devices.
2023-08-29 17:47:14 +02:00
* Documentation for https://wiki.archlinux.org/title/udev
2023-03-05 08:08:19 +01:00
2023-08-29 17:47:14 +02:00
The rule has gotten a major overhaul and now consist of the rule, a config file and a script
2023-03-05 07:12:21 +01:00
2023-08-29 17:47:14 +02:00
### The rule **/etc/udev/rules.d/99-usb-sync.rules**
2023-03-05 07:12:21 +01:00
```
# rule to disable write cache for usb storage
# requires hdparm to be installed
2023-08-29 17:47:14 +02:00
ACTION=="add|change", KERNEL=="sd[a-z]", ENV{ID_USB_TYPE}=="disk", RUN+="/usr/bin/hdparm -W 0 /dev/%K"
2023-07-23 08:27:26 +02:00
#
# the following rules is introduced with kernel 6.2
# 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-ratio
# https://docs.kernel.org/admin-guide/abi-testing.html#abi-sys-class-bdi-bdi-max-bytes
2023-08-29 17:47:14 +02:00
ACTION=="add|change", KERNEL=="sd[a-z]", ENV{ID_USB_TYPE}=="disk", RUN+="/usr/bin/udev-usb-sync %k"
```
### The config **/etc/usb-dev-sync/udev-usb-sync.conf**
```
# default values
#use_tweaks=1
#max_bytes=16777216
#max_ratio=50
#strict_limit=1
```
### The script **/usr/bin/udev-usb-sync**
```
#!/usr/bin/bash
#
# script to tweak USB storage device filesystem sync
#
# sources /etc/usb-dev-sync/usb-dev-sync.conf
#
use_tweaks=1
max_bytes=16777216
2023-08-29 17:48:25 +02:00
max_ratio=50
2023-08-29 17:47:14 +02:00
strict_limit=1
# read user config
source /etc/udev-usb-sync/udev-usb-sync.conf
if [[ "$use_tweaks" = 0 ]]; then
exit 0
fi
if [[ -z "$1" ]]; then
exit 1
fi
echo "$max_bytes" > "/sys/block/$1/bdi/max_bytes"
2023-08-29 17:48:25 +02:00
echo "$max_ratio" > "/sys/block/$1/bdi/max_ratio"
2023-08-29 17:47:14 +02:00
echo "$strict_limit" > "/sys/block/$1/bdi/strict_limit"
2023-03-05 07:12:21 +01:00
```
2023-08-29 17:47:14 +02:00
The rule activates when udev detects
2023-03-05 07:12:21 +01:00
* add or change
2023-03-06 16:01:22 +01:00
* kernel event for disk devices **sd[a-z]**
2023-08-29 17:47:14 +02:00
* only if the device environment **ID_USB_TYPE=='disk'**
* run
- **hdparm -W 0 /dev/%k** (disable write cache if supported)
- **udev-usb-sync %k**
- applies defaults
- read config and apply user values
- if use_tweaks=0 the script exits
- if use_tweaks=1 the applies the values (default or config)
Create a file in **/etc/udev/rules.d/99-usb-sync.rules** and paste the rule into it.
Create a file in **/etc/udev-usb-sync/udev-usb-sync.conf** and paste the default values.
Create a file in **/usr/bin/udev-usb-sync** and paste the script content.
2023-03-05 07:12:21 +01:00
2023-03-05 12:17:08 +01:00
Install **hdparm** package.
2023-03-05 07:12:21 +01:00
sudo pacman -Syu hdparm
2023-08-29 17:47:14 +02:00
Reload udev
sudo udevadm control --reload
Then plug an usb device - open in your file manager - copy a huge amout of files to the device - when the copy is done - click eject in the file manager - note how quick the device is ejected.
2023-03-05 07:12:21 +01:00
2023-10-16 06:40:01 +02:00
For those preferring the package manager, I have created a [PKGBUILD][4] which will pull the **hdparm** dependency upon installation.
2023-03-05 07:12:21 +01:00
pamac build udev-usb-sync
2023-03-05 07:18:04 +01:00
Another idea by [@megavolt][1] at [Manjaro Forum][2] which does not require hdparm.
2023-03-05 07:54:25 +01:00
[0]: https://forum.manjaro.org/t/root-tip-how-to-bypass-write-cache-for-usb-storage-devices/135566
2023-03-05 07:18:04 +01:00
[1]: https://forum.manjaro.org/u/megavolt
2023-03-06 15:53:49 +01:00
[2]: https://forum.manjaro.org/t/decrease-dirty-bytes-for-more-reliable-usb-transfer/120798/4
[4]: https://aur.archlinux.org/packages/udev-usb-sync