#!/bin/bash if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" # todo: we should make this be a service which sets the /sys/ value # before the mount target or something like that, because if you hot # plug a drive in, its ata number will change on reboot, meaning you # have to remember to run this again and then reboot again. # example from t8 kernel # Sep 01 14:35:01 watson kernel: ata7.00: status: { DRDY } # Sep 01 14:35:01 watson kernel: ata7.00: failed command: WRITE FPDMA QUEUED # Sep 01 14:35:01 watson kernel: ata7.00: cmd 61/08:c0:b8:bf:ff/00:00:01:00:00/40 tag 24 ncq 4096 out # https://wiki.archlinux.org/index.php/Solid_state_drive#Resolving_NCQ_errors # evo-870 doesnt get along well with d16. # Dmesg gives us an ata number we could disable specifically on the command line, but I've had that number change on me between oses, so reenabling ncq debug=false if [[ $1 == debug ]]; then debug=true fi upgrub=true if [[ $1 == no-upgrub ]]; then upgrub=false fi regex='^.*-part[0-9]*$' for path in /dev/disk/by-id/ata-Samsung_SSD_870*; do if [[ ! $path =~ $regex ]]; then byid=$path break fi done if [[ ! -e $byid ]]; then if $debug; then echo "samsung 870 not plugged in or not found"; fi exit 0 fi dev=$(readlink $byid) if [[ ! $dev ]]; then exit 1 fi dev=${dev##*/} depth=$(cat /sys/block/$dev/device/queue_depth) if [[ $depth != 0 ]]; then if grep -qF libata.force=noncq /proc/cmdline; then echo $0: warning, cant change queue_depth due to globally disabled ncq else if $debug; then echo "updating to 1 if not: cat /sys/block/$dev/device/queue_depth" cat /sys/block/$dev/device/queue_depth fi echo 1 >/sys/block/$dev/device/queue_depth fi fi sys=$(readlink /sys/block/$dev) ata=${sys#*/*/*/*/ata} ata=${ata%%/*} arg=libata.force=${ata}.00:noncq if ! grep "^GRUB_CMDLINE_LINUX_DEFAULT=.*[\" ]${arg//./\\.}[\" ]" /etc/default/grub; then sed -ri "s/([\" ])libata.force=[^ ]+ */\1/g;s/^GRUB_CMDLINE_LINUX_DEFAULT=\"(.*)/GRUB_CMDLINE_LINUX_DEFAULT=\"$arg \1/" /etc/default/grub if $upgrub; then echo "$0: warning: grub updated. you may want to reboot" if type -P update-grub2 &>/dev/null; then update-grub2 else update-grub fi fi fi