#!/bin/sh
#
# Call fstrim on mounted partitions to maintain write performance.
# This is only relevant for SSD drives, see
# http://wiki.ubuntuusers.de/SSD/TRIM
set -e

# needs /proc
[ -r /proc/mounts ] || exit 0

# these file systems support trimming
SUPPORTED_FS="ext3 ext4 xfs btrfs"

# arguments: <haystack> <needle>
contains() {
    [ "${1#*$2}" != "$1" ]
}

# As long as there are bugs like https://launchpad.net/bugs/1259829 we only run
# fstrim on Intel and Samsung drives; with --no-model-check it will run on all
# drives instead.
if [ "$1" = "--no-model-check" ]; then
    NO_MODEL_CHECK=1
fi

DONE=''
while read DEV MOUNT FSTYPE OPTIONS REST; do
    # only consider /dev/*
    [ "${DEV#/dev}" != "$DEV" ] || continue
    # ignore mounts with "discard", they TRIM already
    if contains "$OPTIONS" discard; then continue; fi
    # only consider supported file systems
    if ! contains "$SUPPORTED_FS" "$FSTYPE"; then continue; fi
    # ignore temporary devices which already went away
    [ -e "$DEV" ] || continue

    # did we see this already? we need to resolve symlinks
    # for/dev/disks/by-{label,uuid}, etc.; ignore if the device does not exist
    # any more
    REALDEV=`readlink -f $DEV` || continue
    if contains "$DONE" " $REALDEV "; then continue; fi
    DONE="$DONE $REALDEV "

    #echo "device $DEV real $REALDEV mountpoint $MOUNT fstype $FSTYPE"

    # check if that device supports trim; this does not work for devmapper or
    # mdadm, though, so just call fstrim on those without the extra check and
    # ignore errors; for cryptsetup and LVM you also need extra configuration
    # options to propagate discards, which the admin might have turned off
    unset SILENT_FAILURE
    if [ "${REALDEV#/dev/dm-}" != "$REALDEV" ]; then
        #echo "device $DEV is on devmapper, skipping TRIM feature check"
        SILENT_FAILURE=1
    elif [ "${REALDEV#/dev/md}" != "$REALDEV" ]; then
        #echo "device $DEV is on mdadm, skipping TRIM feature check"
        SILENT_FAILURE=1
    elif ! type hdparm >/dev/null 2>&1; then
        #echo "hdparm not available, cannot TRIM"
        exit 0
    else
        HDPARM="`hdparm -I $REALDEV`" 2>/dev/null || continue
        if [ -z "$NO_MODEL_CHECK" ]; then
            if ! contains "$HDPARM" "Intel" && \
               ! contains "$HDPARM" "INTEL" && \
               ! contains "$HDPARM" "Samsung" && \
               ! contains "$HDPARM" "SAMSUNG" && \
               ! contains "$HDPARM" "OCZ" && \
               ! contains "$HDPARM" "SanDisk" && \
               ! contains "$HDPARM" "Patriot"; then
                #echo "device $DEV is not a drive that is known-safe for trimming"
                continue
            fi
        fi
        if ! contains "$HDPARM" "TRIM"; then
            #echo "device $DEV does not support trimming"
            continue
        fi
    fi

    if [ -n "$SILENT_FAILURE" ]; then
        fstrim $MOUNT 2>/dev/null || true
    else
        fstrim $MOUNT
    fi
done < /proc/mounts
