[dm-devel] [PATCH v5] DM: dm-inplace-compress: inplace compressed DM target

Ram Pai linuxram at us.ibm.com
Mon Mar 13 21:30:40 UTC 2017


This  patch   provides   a   generic  device-mapper  compression device.
Originally written by Shaohua Li.
https://www.redhat.com/archives/dm-devel/2013-December/msg00143.html

I have optimized and hardened the code.

I have not received any negative comments till now.  Feel confident with the
code.  Please consider merging the code upstream.


Testing:
-------
This compression block device  is   tested in  the  following scenarios
a) backing a ext4/xfs/btrfs filesystem 
b) backing swap

Ran 'badblocks' test on the compressed block device.
Thoroughly stress tested on PPC64 and x86 system.

I have included a test-script that I used to test the block device.

Version v5:
	Modified the parameter list format to use token=value.
	Fixed a coding issue noted by Julia Lawall.
	Fixed data corruption issue when compressed size was same as the
	original data.
	Modified the allowed maximum I/O size to be as large as two pages,
	without  which  larger  size  I/O  need  larger  size  buffers to 
	temporarily hold  compressed data. This can lead  to inability to 
	satisfy memory allocation requests.

Version v4:
	fixed kbuild errors; hopefully they are all taken care off.
       	  - no reference to zero_page
	  - convert all divide and mod operations to bit operations

Version v3:
	Fixed  sector  alignment  bugs  exposed  while   testing on x86.
	Explicitly set the maximum request size  to 128K.  Without which
	range  locking  failed,  causing  I/Os  to  stamp   each  other.
	Fixed an occasional data corruption  caused by wrong size of the
	compression buffer.
	Added  a   parameter   while  creation  of  the   block  device, 
	to  not  sleep   during  memory  allocations. This can be useful
       	if the device is used as a swap device.

Version v2:
	All patches are merged into a single patch.
	Major code re-arrangement.
	Data and metablocks allocated based on the length of the device
	map rather than the size of the backing device.
        Size   of   each entry   in  the bitmap array is explicitly set
	 to 32bits.
	Attempt  to  reuse  the  provided  bio  buffer  space   instead
	 of allocating a new one.

Version v1:
	Comments from Alasdair have been incorporated.
	https://www.redhat.com/archives/dm-devel/2013-December/msg00144.html


Ram Pai (1):
  From: Shaohua Li <shli at kernel.org>

 Documentation/device-mapper/dm-inplace-compress.txt |  174 +
 drivers/md/Kconfig                                  |    6 
 drivers/md/Makefile                                 |    2 
 drivers/md/dm-inplace-compress.c                    | 2295 ++++++++++++++++++++
 drivers/md/dm-inplace-compress.h                    |  194 +
 5 files changed, 2671 insertions(+)



---------- Test script -------------
#!/bin/bash
# a test program to verify the correctness of
# the dm-inplace-compression target
# - Ram Pai

compdevname="__compdev"
usage()
{
	echo 
	echo 
        echo "$1:  -d <device path> [ -h ] [ -c <compdevicename> ]"
        echo "-d <device path> path to the block device to "
	echo "	back the compression device"
	echo "-c <compdevicename>  some unique name of the compress"
	echo " device name to be used. Defaults to $compdevname"
        echo "-h help"
	echo 
	echo 
        return
}

getsize()
{
	#the target will spew out the maximum size that
	#it can accommodate for the device. So start with
	#insane number and let it fail.
	insane=999999999999999999990009
	dmsetup create $2 --table \
		"0 $insane inplacecompress device=$1, \
		writethrough,compressor=lzo" 2>/dev/null
	echo $(dmesg | \
	   grep 'dm-inplace-compress:  This device can accommodate at most'\
	   | tail -1 | awk '{print $(NF-1)}')
}

MYNAME=$(basename $0)
OPTIND=0
while getopts "d:c:h" args $OPTIONS
do
     case "$args" in
        d)      device=$OPTARG
                ;;
        c)      compdevname=$OPTARG
                ;;
        *)      usage $MYNAME
                exit 1
                ;;
        esac
done

if [ -z "$device" ]
then
	usage $MYNAME
	exit 1;
fi

if [ ! -b "$device" ]
then
	usage $MYNAME
	echo ERROR: $device is not a block device
	exit 1;
fi

if [ -b "/dev/mapper/$compdevname" ]
then
	echo "WARNING: $compdevname already exist"
	usage $MYNAME
fi

echo -n "ANY DATA ON $device WILL BE LOST. Continue using $device?: y/n:"
read yesorno
if [ "$yesorno" != "y" ]
then
	echo "Ok, exiting"
	exit 1;
fi

dmsetup targets | grep inplacecompress > /dev/null
if [ $? -ne 0 ]
then
	echo "Please enable dminplacecompress target in the kernel"
	echo "Try modprobe dm-inplace-compress.ko"
	exit 1
fi



#clean and init the device
dd if=/dev/zero of=$device count=100 2> /dev/null

dmsetup remove $compdevname 2> /dev/null
size=$(getsize $device $compdevname)
if [ ! -n $size ]
then
	echo "FAILURE: determining the maximum possible size of the device"
	exit 1
fi

ret=0
for mode in writethrough writeback=2
do
 for i in lzo 842
 do
	cat /proc/crypto  | grep -w "$i$" > /dev/null
	if [ $? -ne 0 ]
	then
		continue
	fi

	echo "Testing: $i $mode....:"

	#generate the device
	dmsetup create $compdevname --table "0 $size inplacecompress device=$device, $mode ,compressor=$i"
	if [ $? -ne 0 ]
	then
		echo "FAILURE: creating the device"
		exit 1
	fi

	badblocks -wsv /dev/mapper/$compdevname
	if [ $? -ne 0 ]
	then
		echo "FAILURE:"
		ret=1
	fi

	##
	##
	## ADD MORE TESTS HERE
	##
	##

	echo "PASS"
	dmsetup remove $compdevname
 done
done

if [ $ret -eq 0 ]
then
	echo CONGRATS IT WORKS
	exit 0
else
	echo FAIL
	exit 0
fi
------------------------




More information about the dm-devel mailing list