--- /tmp/hdparm-9.28/wiper/wiper.sh 2010-03-09 15:17:37.000000000 +0100 +++ wiper.sh 2010-03-17 19:46:03.637525890 +0100 @@ -344,7 +344,7 @@ rawdev="" elif [ "`get_major $fsdev`" -ne "`get_major $rawdev`" ]; then ## sanity check rawdev="" -elif [ "`get_major $fsdev`" -ne "8" ]; then ## "SCSI" drives only; no LVM confusion for now +elif [ "`get_major $fsdev`" -ne "8" -a "`get_major $fsdev`" -ne "254" ]; then ## "SCSI" drives only; accept LVM confusion echo "$rawdev: does not appear to be a SCSI/SATA SSD, aborting." >&2 exit 1 elif ! $HDPARM -I $rawdev | $GREP -i '[ ][*][ ]*Data Set Management TRIM supported' &>/dev/null ; then @@ -364,6 +364,49 @@ ## fsoffset=`$HDPARM -g "$fsdev" | $GAWK 'END {print $NF}'` +## LVM patch: +tmpdev="" +hdparm_fibmap_offset=0 +dmtable=(`dmsetup table $fsdev`) +if [ ${dmtable[2]} == "linear" ]; then + #get pv name + tmpdev=`echo $fsdev | sed 's/\/dev\/mapper\///'` + pvname=`echo $tmpdev | sed 's/-.*/ /'` + echo "pvname" $pvname + # get dev of lvm partition + pv=`pvscan` + oldIFS=$IFS + IFS=$'\n' + for item in $pv; do + if [[ $item =~ $pvname ]]; then + vg=$item + fi + done + IFS=$oldIFS + items=($vg) + dev=${items[1]} + #echo "found: " $dev + + # get fsoffset for dev and to current fsoffset + fsoffset=`$HDPARM -g "$dev" | $GAWK 'END {print $NF}'` + + fsoffset=$(($fsoffset+${dmtable[4]})) + echo "new fsoffset:" $fsoffset + + if [ $method == "online" ]; then + if [ "`$HDPARM -V`" == "hdparm v9.27" ]; then + hdparm_fibmap_offset=$fsoffset + else + echo "/dev/mapper/$tmpdev: unknown if online method works on logical volumes" + echo "Only tested for hdparm v9.27---aborting!" + exit 1 + fi + fi +else + echo "$rawdev: does not have linear structure, aborting." >&2 + exit 1 +fi + ## Next step is to determine what type of filesystem we are dealing with (fstype): ## if [ "$fsdir" = "" ]; then @@ -539,6 +582,9 @@ fi sync_disks fi + if [ -n "$tmpdev" ]; then + $RM -f "/dev/$tmpdev" + fi [ $1 -eq 0 ] && echo "Done." [ $1 -eq 0 ] || echo "Aborted." >&2 exit $1 @@ -577,6 +623,12 @@ echo fi +# Fix to let hdparm 9.27 find an LVM device +if [ -n "$tmpdev" ]; then + # removed in do_cleanup() + /bin/cp -a "/dev/mapper/$tmpdev" /dev +fi + ## Finally, we are now ready to TRIM something! ## ## Feed the "get_trimlist" output into a gawk program which will @@ -608,7 +660,7 @@ nsectors += count; while (count > 0) { this_count = (count > 65535) ? 65535 : count - printf "%u:%u ", lba, this_count + printf "%u:%u \n", lba, this_count if (verbose > 1) printf "%u:%u ", lba, this_count > "/dev/stderr" lba += this_count @@ -618,7 +670,7 @@ } (method == "online") { ## Output from "hdparm --fibmap", in absolute sectors: if (NF == 4 && $2 ~ "^[1-9][0-9]*$") - append_range($2,$4) + append_range($2 + hdparm_fibmap_offset,$4) next } (method == "xfs_offline") { ## Output from xfs_db: @@ -695,6 +747,25 @@ -v verbose="$verbose" \ -v xfs_blksects="$xfs_blksects" \ -v xfs_agoffsets="$xfs_agoffsets" \ - "$GAWKPROG" | $TRIM + -v hdparm_fibmap_offset="$hdparm_fibmap_offset" \ + "$GAWKPROG" | + ( + ranges=0 + i=0 + while read range; do + if ((i == 512)); then + [ $verbose -gt 0 ] && echo -e "Trim ranges:"$ranges"\n" + echo $ranges | $TRIM + ranges="" + i=0 + fi + ranges=$ranges" "$range + ((i++)) + done + if [ -n "$ranges" ]; then + [ $verbose -gt 0 ] && echo -e "Trim ranges:"$ranges"\n" + echo $ranges | $TRIM + fi + ) do_cleanup $?