HOWTO for the DouBle device driver Version 0.4		Nov 1994
----------------------------------------------
Last Modification: 14 April 1995 - version 0.4l

1.0 INTRODUCTION
1.1 WHAT IS DOUBLE
1.2 WHAT DOUBLE IS NOT
1.3 QUICK INTERNAL OVERVIEW
1.4 NEW FEATURES

2.0 INSTALLATION
2.1 KERNEL PATCHING
2.2 UTILITIES AND DEVICES

3.0 USAGE
3.1 MAKING A COMPRESSED DEVICE
3.2 MOUNTING
3.3 USING COMPRESSED DEVICES
3.4 DISMOUNTING
3.5 CHECKING
3.6 OTHER UTILITIES

4.0 OPTIMIZATION
4.1 CHECKING AND MOUNTING
4.2 COMPRESSION
4.3 DEFAULT VALUES
4.4 SECURITY
4.5 SPEED

5.0 COMPATIBILITY
5.1 BUGS
5.2 ACKNOWLEDGEMENTS
5.3 AUTHORS
5.4 FINAL REMARKS


1.0 INTRODUCTION
    ------------
Despite its different purpose, DouBle was originally inspired from the
loop driver, written and copyright by Theodore Ts'o. A few versions later,
it probably doesn't look quite the same anymore...
This HOWTO will attempt to guide you through installation, usage and
optimization.


1.1 WHAT IS DOUBLE
    --------------
Double is a block device driver for Linux, that does on-the-fly compression.
It's also been called a "fs-independent on-the-fly compression device driver".
This sometimes lead to confusion because it is not a filesystem (see
section 1.2).

Applications include swap-space compression (it does not make too much
sense in most cases because it's slow, but it works), or virtually anything
using block devices - most importantly transparent filesystem compression.


1.2 WHAT DOUBLE IS NOT
    ------------------
Double is *only* a block device driver. It is not a filesystem, and knows
(almost) nothing about filesystems and their structure. Therefore, the
driver won't make a difference between files, inodes, superblocks or
whatever (I don't really know about filesystems myself).


1.3 QUICK INTERNAL OVERVIEW
    -----------------------
The DouBle device driver acts as an interface between the physical
(compressed) data on a device or a regular file, and a pseudo
"DouBle" block device, where non compressed data is written/read:

<client> <-> <double device> <-> <double driver> <-> <regular device>

<regular device> is either a block device (such as a disk partition) or
a regular file on an existing file system.
Before it can be used, this device (or file) needs to be formatted (see 3.1).
Data on the device (or file) is compressed and cannot be accessed directly.
It is divided in small blocks (often 512 or 1024 bytes).

<double device> is a virtual block device, where non compressed data can be
read/written - usually written first :). The major number for DouBle devices
is 19.
The double device needs to be "mounted" (see 3.2).

<client> is either a filesystem, or any block device "client" (One could
do a tar on a double device). 
Any request going to <double device> is (de)compressed and piped to/from
the <regular device> transparently:

The <double driver> does all the witchcraft.

The driver:
-----------
The driver transparently divides the <double device> in clusters (for
instance 16 blocks or 8192 bytes). Each cluster is compressed and written to
as few blocks as necessary to hold either the compressed cluster or the non
compressed cluster (in case of overrun). For that purpose, compressed devices
contain several tables (hence the formating step): 

The physical file/device contains a header (a), a bitmap (b) and a
block allocation table (c) - referred to as BAT. In addition, regular files
used as devices also contain a block map table (d).

(a) The header contains a Magic number and relevant informations on
the size and number of blocks and clusters.

(b) The bitmap tries to remember which blocks have been allocated.

(c) The BAT contains information on the type of compression, and on
which blocks clusters are made of: each cluster is made of
as many smaller blocks as necessary (1 to cluster_size/block_size).

(d) The block map table is used by the driver to access a real block
from the offset on a regular file.


1.4 NEW FEATURES
    ------------

1 - double 0.4k is a followup to previous 0.4 versions of DouBle.
See CHANGES for details. A list of new features common to all 0.4 versions
follows:
2 - A clean bit, reset by dbck, has been added in order to improve
auto-checking. dbck does more extensive checking, and now optionally
repairs compressed devices.
3 - MSDOS/UMSDOS regular files can now be used as compressed devices
This is probably a bit slower, though.
4 - Version 0.4 should behave a lot better when devices run out of space.
This is only true when "mount -t dble" is used *and* an ext2-fs is mounted
on the compressed device. Briefly:

	- When available space drops below 10%, the device is remounted
	with an option so that blocks released by the ext2-fs get cleared.
	- Writes become synchronous when available space is less than 5%.
	- Files become read-only when little (less than 100 KB)
	space remains.
	- The fs becomes read-only when there is less than 50 KB left.

Unfortunately, these features are useless when devices run out of space
under heavy disk load - when the amount of disk buffers ready to be written
is already larger than the remaining available space.


2.0 INSTALLATION
    ------------

WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
!                                                                     !
!   Improper installation or usage may yield undesirable results.     !
!   I take no responsibility for data lost because of this driver.    !
!                                                                     !
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING

The DouBle device driver for Linux is usually available from:

ftp://sunsite.unc.edu/pub/Linux/kernel/patches/diskdrives/double-X.X.tar.gz
ftp://tsx-11.mit.edu/pub/linux/ALPHA/double/double-X.X.tar.gz

The latest alpha release can usually be obtained from:

ftp://achaz.saclay.cea.fr/pub/double/double-X.X.tar.gz (I'm running this
site. Please don't mess with it, but do tell me when there's a problem there)

NOTE: This site was recently unreachable for 2 weeks - network administrators
had decided to firewall the whole network. They have agreed to step back, but
only temporarily ... do not rely on this site in the future.

ftp://julia.physik.fu-berlin.de/pub/linux/double/double-X.X.tar.gz

THIS DISTRIBUTION INCLUDES:
---------------------------

- patches against kernel 1.2.5.
- A set of utilities (sources only), with man pages.

Warning: DO NOT use double-0.4l with kernels older than 1.2.4, even if
         they patch cleanly...

IF YOU HAVE BEEN USING OLDER VERSIONS OF DOUBLE:
------------------------------------------------
Some data structure have changed between versions 0.2, 0.3 and 0.4.
Therefore, most utilities, particularly "mkdble", "dbmode" and "dbck" need
to be recompiled with version 0.4. It's best to make them all, just in case.
In addition, you may not be able to go back to version 0.2x of the driver
once you have started using newer versions.

Install as you like, but you could do it as follows (steps labelled with a
"*" can be ignored when upgrading from 0.3, or early 0.4):


2.1 KERNEL PATCHING
    ---------------

1 cd to /usr/src and tar xvfz double-0.4.tar.gz
-----------------------------------------------

2 Patch the kernel (Linux >= 1.2.4), from /usr/src:
---------------------------------------------------
patch -p0 <double/double-0.4.patch

You may have to update arch/i386/config.in manually.

The driver uses 2 definitions in config.in:
if CONFIG_DOUBLE is defined, the driver will be compiled into the kernel.
Double won't work without it.

if CONFIG_DBLE_FS is defined, mount/umount/df support for DouBle devices
will be enabled. CONFIG_DBLE_FS is most recommended, but not necessary to
the driver. The utilities dbmount and dbumount can still be used instead.

3 making
--------
cd linux
make config; make dep; make clean; make zlilo - or whatever you need to
build a new kernel.

4 reboot
--------
You should see "DouBle: 8 devices, 66 buffers 198K." or something
similar. If not check previous steps.


2.2 * UTILITIES AND DEVICES
      ---------------------

5 * Make block devices with major=19, minor=0-7:
-----------------------------------------------
mknod -m 611 /dev/double0 b 19 0
mknod -m 611 /dev/double1 b 19 1
........
mknod -m 611 /dev/double7 b 19 7
(you don't have to make all of them, unless you actually need 8 devices)

6 * IF you have used the CONFIG_DBLE_FS option
----------------------------------------------
If you want to use that option, you need to make the following block devices
as well:
major = 19, minor = 128-135 i.e.:
mknod -m 611 /dev/cdouble0 b 19 128
mknod -m 611 /dev/cdouble1 b 19 129
........
mknod -m 611 /dev/cdouble7 b 19 135

"cdouble" devices actually mirror the "doubleN" devices with minors 0 to 7.
These devices should not be used for accessing data on the DouBle device.
They are useful only with mount/umount (see 3.2 & 4.1).


7 Make the utilities in ./double
--------------------------------
* version 0.3 users: dbck, dbmode and their man pages have changed in
version 0.4, and dbfrag has been added.

make
make install, or
mv mkdble dbmount dbumount dbck dbmode dbfrag /sbin (or wherever you like).

The dbstat and dbdebug utilities should not be necessary.

Note that there are now man pages, for most of these utilities.
You can move them to /usr/man/man8.

You're ready to go !


3.0  USAGE
     -----

DouBle 0.4 comes with a choice of 5 different compression algorithms.

- LZW is still included, but reading is really slow.

- A derivative of the predictor used in PPP.  Although it does not give the
best compression, it is faster than LZW. I'll include an improved algorithm
in a future version (0.5 I hope). Like the other algorithms, it is patented.
However, it was published well before being patented, which makes me think
it should be considered public domain (this may not be the opinion of a
lawyer).

- LZRW2 and LZRW3A, written by Ross Williams.  They both yield a good
speed*compression. LZRW2 is faster, LZRW3A compresses better...

- LZV, by Hermann Vogt. This algorithm has similarities with LZRW, it
is fast and compresses well. It is now the default algorithm in mkdble.

- Version 0.4 provides optional support for some fs-like operations (but the
driver is not a filesystem). There is support for write-super, put_super,
read_super and statfs, with a fs type named "dble" (see also 3.2 & 4.1).
This involves patches to the kernel that I was not really happy with when
I wrote them. Therefore, this is only an option, and the driver can also be
used without fs support.
Now that I have forgotten how ugly these patches really are I would strongly
recommend using this option which is not only more convenient but also makes
the driver more efficient.


3.1 MAKING A COMPRESSED DEVICE
    --------------------------

This formatting step is required whether you are going to use a block device
or a regular file. The "mkdble" utility will take care of that - check out
its man page.

Let's see dummy examples:
 
mkdble /path/dbfile 1000	or
mkdble /dev/hdb2 1000
 
Either of these will create a 1Mb device, with default values for compression,
block and cluster sizes.
After the creation of headers, there's around 1.9MB virtual disk
space available. Headers are smaller on a real device (as opposed to a
regular file). See "mkdble.8" for more details.
It's always better to use a smaller compression factor than the default,
such as 1.7 and a good compression algorithm (see section 4).


3.2 MOUNTING
    --------

Once the compressed device has been formatted, one needs to let
the driver have access to it. That's what I'm calling "mounting". When the
device is mounted, non-compressed data is read/written on a "doubleN"
pseudo block device and compressed data is transparently read/written
on the compressed device.

There are two ways to mount a compressed device. Choose one or the
other, but remember "mount -t dble" *is* better.

- dbmount
---------
The syntax for dbmount is fairly straightforward. Check the man page.
With our previous example in mind it could be:
dbmount /path/dbfile /dev/double0

This will work whether or not the CONFIG_DBLE_FS option was enabled in the
kernel.
Note: "cdouble" devices, with minor numbers >= 128 are not intended for use
with db(u)mount.


- with the CONFIG_DBLE_FS option
--------------------------------

This is where the cdouble[0-7] devices come up.
This option was designed to mimic filesystem mounting. It is also described
in the "dbmount" man page. Briefly, there is support for a _pseudo_
filesystem named "dble". This was only designed for using mount and umount
and some filesystem features that improve performance.

mount -t dble /path/dbfile /dev/cdouble0           or
mount -t dble /dev/hdb2 /dev/cdouble0

So what's the advantage of using mount over dbmount ? There are several:
- auto-mounting/dismounting. See also section 4.1 
- df will report mounted devices and the amount of space available.
- the driver has been optimized for devices with "mount".
- out of space conditions are taken care of more gracefully.

Note: mount -t dble will not work with /dev/double[0-7].


3.3 USING COMPRESSED DEVICES
    ------------------------

Once a compressed device is mounted on a pseudo block device (doubleN, or
cdoubleN), the doubleN block device behaves just like any other block
device. You'll probably want to make a filesystem:

mkfs -t ext2 [options] /dev/double0 [size]
The optional "size" argument is the value reported by dbmount.

DO NOT USE "cdouble" devices here. THEY SHOULD ONLY BE USED FOR:
mount -t dble (3.2) and umount (3.4).

Then, you'll want to mount this new filesystem:
mount -t ext2 /dev/double0 /mnt

Next thing, you'll probably want to run df:

If you have used mount -t dble, you'll see 2 new entries:
/path/dbfile   ....   /dev/cdouble0
/dev/double0   ....   /mnt

Figures on "cdouble0" are relevant to the compressed side of the device.
You just have to make sure that "space used" never comes too close to 100%.
If it does, the compression factor you have chosen in "mkdble" was too high.
Quite naturally, figures on "double0" will show usage on the filesystem.

If you have used dbmount, there will only be one new entry:
/dev/double0 ..... /mnt

In this case, you'll have to use "dbck" or "dbmode" to follow disk usage on
the compressed side of the device.

Enjoy !


3.4 DISMOUNTING
    -----------
As one would expect, dismounting is the reverse procedure.

- You need to dismount the filesystem first:

umount /dev/double0     or umount /mnt

-> This is where you'll want to "fsck" it, just for fun: fsck /dev/double0.
Hope it's clean :)

- Then you need to dismount with the same (u) command that you used for
mounting. That's either:
dbumount /dev/double0  (if you have used dbmount)
or
umount /dev/cdouble0  or umount /path/dbfile (if you have used mount -t dble).

-> This is where you'll want to try "dbck": dbck /path/dbfile. Hope it's clean
too !


3.5 CHECKING
    --------

- dbck checks a compressed device/file for errors, much like fsck would
check a filesystem:
dbck /path/dbfile

dbck optionally repairs devices and will set the clean bit when the device
has been cleaned.
dbck has a couple of options - check the man page.
Notes: It is mandatory to dbumount (or umount) before running dbck.
dbck on a mounted device may result in segmentation fault, but you're not
supposed to try :)


3.6 OTHER UTILITIES
    ---------------

Very briefly:
dbmode is a utility to change current or default compression algorithms,
and to display information about a device (see man page).

dbfrag is a utility to check fragmentation of a non-mounted compressed
block device (see man page). This will be useful to improve the allocation
scheme in the future.

The following two utilities are included for debugging purposes and should
not be needed other than for fun or bug reports.
- dbdebug changes debugging level on a DouBle device (resulting in MANY
kernel messages kernel):
dbdebug /dev/double0 5

- dbstat reports the number of read/write accesses made and how often buffers
were already loaded when requested:
dbstat /dev/double0   (dbstat will cumulate information on all devices).


4.0  OPTIMIZATION
     ------------

The following paragraphs will focus on ways to fine tune the DouBle driver.

Before going into specifics, bear in mind that the CONFIG_DBLE_FS option will
help improve efficiency, security and ease of use. 


4.1 CHECKING AND MOUNTING
    ---------------------

Once you have everything under control, you'll probably want to have
compressed devices mounted at startup.
On most Linux systems this is a two step process.

- The root partition is mounted read-only and partitions are checked by
the /etc/rc script, with a command like: fsck -A -av
- Then, the root partition is re-mounted read-write and partitions in
/etc/fstab are mounted.

Because compressed devices need to be mounted twice auto-mounting and checking
compressed devices is a little more difficult.
Briefly the order must be as follows:
1 - check compressed device (with dbck)
2 - dble mount compressed device (with dbmount or mount -t dble)
3 - run fsck on double device
4 - optionally dble remount compressed device
5 - mount filesystem

First, you may want to check compressed devices with dbck. This MUST be
done before anything else !

Then, the compressed device must be mounted in order to fsck the filesystem
on it.

Finally, the filesystem can be mounted.

This can be achieved several ways. For more details on mounting compressed
devices on regular files, skip to subsection (B), below. For devices on
partitions, stay tuned.

A) Auto-mounting compressed partitions
 -------------------------------------

If you want partitions on compressed devices checked, they need to be mounted
with "dbmount" (not mount !) before the fsck. You could have in /etc/rc:
dbmount /dev/hda3 /dev/double0
fsck -A -av

With the DBLE_FS option set, DouBle devices can be put in /etc/fstab.
If DBLE_FS is disabled, you'll have to use dbmount.

a - If you want to stick to dbmount, it's been done already.
All you need to do is to include one entry for each filesystem on compressed
devices in /etc/fstab:
/dev/double0	/mnt 	ext2	defaults

In this case, You *will* have to umount and dbumount manually before
shutdown !

b - You'd rather take advantage of the full benefit of using the DBLE_FS
option. In this case, you need to dismount compressed devices first (because
they were "db"mounted for the fsck):
dbumount /dev/double0

Then, new entries in /etc/fstab are needed in order to:
- mount the compressed device as a "dble" fs.
- mount the "double" device as an ordinary filesystem. Example:
/dev/hda3	/dev/cdouble0	dble	defaults
/dev/double0	/mnt		ext2	defaults

Lines must be in this order !

dismounting will be auto-magically done in the reverse order when you shutdown.

As a working example, this is what I have added to my /etc/rc file:

# check compressed device
dbck -av /dev/hdb2
# check fs before mounting
dbmount /dev/hdb2 /dev/double2 # I have one compressed partition on /dev/hdb2
# This will check all filesystems in my /etc/fstab, including /dev/double2
fsck -A -av
# dbumount /dev/double2, so that it can be mounted with mount
dbumount /dev/double2

And this is what I have in my /etc/fstab file:

/dev/hdb2	/dev/cdouble2	dble	defaults
/dev/double2	/home		ext2	defaults


B Auto-mounting compressed files
--------------------------------

This is the most particular case, and I had conveniently forgotten it in
early versions of this document (thanks to Peter Collins for reminding me):
- In order to be checked, the fs on which the compressed file is, must be
mounted read-only (or not mounted at all).
- In order for the filesystem on the compressed file to be checked (and
possibly changed) the file must be opened read-write (and the filesystem
mounted).

Some people have suggested changes to dbmount in order to make it mount
devices read-only. It may work, but I don't really like the idea of fsck
checking a filesystem which is effectively on a read-only file !
Additionally, that does not solve the case of a compressed file on a not-yet
mounted filesystem.

Therefore, I'd rather keep it simple. This is what I suggest:
- do not put the compressed filesystem in /etc/fstab at all.
- let the /etc/rc script check and mount all the normal filesystems.
- when everything else is up, mount the compressed files as follows:

a - with dbmount

add something like the following to your /etc/rc (after other filesystems
have been mounted):
dbck /path/dbfile
dbmount /path/dbfile /dev/double0
fsck -t ext2 -av /dev/double0
mount -t ext2 /dev/double0 /mnt

You *will* have to umount/dbumount manually before shutdown !

b - better - with mount -t dble 

add something like the following to your /etc/rc (after other filesystems
have been mounted):

dbck /path/dbfile
mount -t dble /path/dbfile /dev/cdouble0
fsck -t ext2 -av /dev/double0
mount -t ext2 /dev/double0 /mnt

Two entries will be added by mount to your /etc/mtab file and dismounting
should therefore be auto-magically done at shutdown !


4.2 COMPRESSION
    -----------

See also 4.3

The default compression factor of 2.0 is nothing but a dream
------------------------------------------------------------
Although I hope version 0.4 will behave better than previous versions,
it is important to use a value SMALLER than the average compression factor
expected from the data and the choice of an algorithm.

The default algorithm is not the best compressor
------------------------------------------------
LZV now is the default algorithm used by mkdble.
According to benchmarks I have done with DouBle-0.4e, this is how the
algorithms included approximately compared (as far as compression goes) - your
mileage may vary:

best       : LZW > LZRW3A > LZV > LZRW2 >> PREDICTOR >> NO COMPRESSION : worst
compression: 1.8-   1.7-    1.7-   1.6-    1.3-            1.0
range      : 2.0    1.9     1.8    1.8     1.5

Note: Before choosing an algorithm, have a look at the speed comparison and
check patent restrictions that apply to you.
It is easy to make a DouBle device use a different algorithm (see mkdble
arguments and dbmode) and the default value could even be changed in the
source file: mkdble.c (replace code 11 with 1, 10, 12 or 13).

There is no other mean to measure the compression factor than trial and
error. This is what I recommend:
- Make a device with a compression factor of 1.6.
- Start using it and after some time, use dbck to see what compression
was achieved. If it is less than 1.6, make it again, with a lower value.
With LZ* algorithms however, chances are you could do better by moving
compressed files (such as .zip, .gz, .Z, .jpg ...) to another partition. 
If it is more than 1.7, you can make it again as well with a larger
compression factor (but it is safe to leave it unchanged).

- when the mount -t dble option is used, df will report block usage on the
double device. It is safe to have more blocks used on the device than on
the filesystem that uses it, as long as the compression ratio (reported by
dbck) remains satisfactory. It is dangerous however, to let the block usage
on the compressed device reach 100%.
In the beginning, you'll see usage increase steadily. You'll also notice
that it does not decrease when you delete files. That's perfectly normal
(see explanation below). It will eventually stabilize, hopefully before
it's full. If not, make it again with a smaller compression factor value
(I said trial and error).

If you are not interested in understanding why that is, skip to the next
section.

The reason for that strange behavior is that most filesystems don't actually
clear blocks when files are removed. File contents are still on the device,
but are dereferenced from inodes and directories. The filesystem will not
overwrite these blocks as long as it does not need space. Therefore, blocks
that are free from the filesystem point of view no longer are from the device
point of view.
The reason it's OK is that the filesystem will eventually use this space
when new files are written. Finally, there'll be a steady state when each
filesystem block has been allocated at least once. All you need to make sure
of is that this is below 100% usage on the compressed device.

In version 0.4, some level of cooperation between DouBle and the ext2-fs has
been introduced in order to obtain a more secure behavior. When compressed
space usage grows over 90%, DouBle will ask the ext2-fs to start clearing
unused blocks.

Practically, one can also make usage report drop manually (use with care):
Let's assume after some time using a compressed device,
df reports 1000 available blocks on /dev/cdouble0 (compressed)
and 2000 available blocks on /dev/double0, mounted on /mnt (non compressed).
Chances are that after:
dd if=/dev/zero of=foobar bs=1024 count=1500
df will report more than 1000 blocks on the compressed device (/dev/cdouble0)
df will report ~500 available blocks on /mnt (/dev/double0).

Indeed, dd creates a 1500 Kb file "foobar" on the filesystem. This file
is filled with zeros, which compress very well. For that purpose, the
filesystem uses blocks that were previously allocated then released.
Data previously written to these filesystem blocks was presumably more
complex and was using more compressed blocks. Therefore the compressed
device now uses fewer blocks than before for "foobar" and there are more
compressed blocks available than before!
If you try the above example yourself make sure that:
- foobar is smaller than available space on the filesystem (here 1500 vs. 2000).
-> foobar is smaller than ~2 x available space on the compressed device.
don't forget to delete foobar after the experiment.



4.3 DEFAULT VALUES
    --------------
These are the default values used by mkdble:
compression factor: 2.0
cluster size: 10240 bytes
block size: 1024 bytes
compression algorithm: LZV (code 11)

Default block and cluster size are only a compromise.
Compression can be increased 4 to 8% by using 512 or 256-bytes blocks,
speed will decrease 4 to 8% as well. On most MS-DOS filesystems, files have
512-bytes blocks. It is recommended to use 512-bytes blocks or less on these
files (better compression, no speed change).

In most cases, the cluster size should have little effect on speed and
thus the bigger, the better. 10240 bytes is currently the maximum. decreasing
this value to 5120 would result in 7 to 12% compression loss.
You may want to decrease the cluster size if you are going to do mainly
random access, or if you notice too much disk thrashing on the compressed
device. This may particularly occur on SCSI disks.

Note: the cluster size is not related to filesystem block size. I know
it might be confusing, but one should not be tempted to reduce its size
on a filesystem containing small files.


4.4 DATA SECURITY
    -------------

The most important thing with a compressed device is to not let it run
out of space. In that purpose:
- Choose an appropriate compression factor and algorithm when creating
the device.
- Do not store too many compressed files (.gz, .zip, .Z, .jpg...) on it.
- run dbck, or dbmode (df is easier if you are using mount -t dble ...)
frequently, to check available space on compressed devices.

In this release, the driver should recover better from errors resulting
from running out of space. It can't be totally reliable however, so please
be careful.


4.5 SPEED
    -----

The purpose of this driver is to transparently make more disk space
available. Access to a compressed device is generally slower than to a normal
block device. However, there are ways to increase speed.

Before going into specifics, one needs to know that IDE and SCSI disks
behave differently. I believe data transfer is done by the CPU on IDE, but
not on SCSI. This means that with a slow CPU and/or IDE you're better off
using a fast compressor (but you don't get as good compression). With a fast
CPU and/or SCSI, it's usually better to use a better compression algorithm
that will use the CPU while waiting for I/Os to complete.

Also, I've noticed that Double was getting slower with time on SCSI drives,
but not as much on IDE ones.

Because the default block size under Linux is 1024 bytes, compressed
devices with a block sizes of 1024 bytes are fastest (~8% faster than with
256 bytes-blocks on IDE).
Note: In most cases, MS-DOS files used as compressed devices have
512-bytes blocks. Therefore, access to these files is be a bit slow,
but does not get slower with 512 byte blocks (but compression improves).

Buffer caches within the driver will compensate for speed differences due
to block size. For better performance, the number of internal buffers
(particularly DB_NR_BH in linux/include/linux/double.h) can be increased.
Unfortunately, the driver buffers are not shared with kernel buffers -
They are allocated for the sole benefit of the DouBle driver.

Block devices are faster than regular files used as compressed devices.
The reason in that any read/write operation on a regular file goes through
additional kernel layers.

Finally, speed is also dependent on the compression algorithm used. According
to benchmarks I did on a Cyrix486 + IDE  and on a 486/DX266 + SCSI with
DouBle-0.4e - values give time compared to normal filesystem on the same device:

fastest: LZV = LZRW2 > NO COMPRESSION = PREDICTOR > LZRW3A >> LZW :slowest

IDE
writing: 1.1    1.1        1.2            1.2        1.3      1.5
reading: 1.5    1.8        1.8            2.1        2.1      3.9

SCSI
writing: 2.6    2.6        3.1            2.9        2.7      2.7
reading: 2.6    2.7        3.1            2.8        2.8      3.1

Notes:
- your mileage may vary, particularly as devices are getting older.
- writing on a normal filesystem was 2-fold faster with SCSI than IDE,
reading speed was similar.


5.0 COMPATIBILITY
    -------------

- Double is not compatible with any other compression driver, that I know of.
- Double is not compatible with filesystems that do not implement the "bmap"
system call.


5.1 BUGS
    ----

- running dbck on a mounted compressed device is likely to yield a segmentation
fault, but you're not supposed to do that.
- using the driver is not as safe as not using it...
- I/O errors or power failures may yield unrecoverable fs corruption.


5.2 ACKNOWLEDGMENTS
    ---------------

Leo Broukhis <leo@fuso.zycad.com> and Jean-Loup Gailly <jloup@chorus.fr>
have been contributing a kind and precious expertise in the choice of
compression algorithms.
Thomas Graichen <graichen@sirius.physik.fu-berlin.de> has been most
helpful in making suggestions and comprehensive tests of this driver,
which have resulted in several improvements.
Michael Beck <beck@informatik.hu-berlin.de> has made useful suggestions.
Richard <kunze@informatik.uni-hannover.de> has provided the LZV
algorithm written by Hermann Vogt.
Many other people have provided useful reports; I hope you will continue
to help me improve the DouBle driver.


5.3 AUTHORS
    -------

Jean-Marc Verbavatz (Jan 1994) <verbavatz@achaz.saclay.cea.fr>

Parts of the driver source were adapted from the loop driver copyright
by Theodore Ts'o.

LZV was written by Hermann Vogt <herm@pirx.han.de>.

The LZRW2, LZRW3-A algorithms were written by Ross Williams.

The predictor algorithm was originally written by Dave Rand, updated by
a couple of other people (see file pred.c), most recently for by
Peter Trattler <peter@sztma.tu-graz.ac.at>

Didier Genard <dig@swn.sni.be> has contributed many of the recent
improvements to the DouBle driver. 


5.4 FINAL REMARKS
    -------------

Feel free to get in touch with me for any question, suggestion or bug report.
I always try to help as I can and to consider suggestions.
Never assume thet someone else has reported a bug before you - You may
actually be the first!

Thank you for using the DouBle device driver; Enjoy !

Jean-Marc Verbavatz <jmv@achaz.saclay.cea.fr>
