02 Aug, 2014

1 commit

  • Add support for quickly loading a repetitive pattern into the
    dm-switch target.

    In the "set_regions_mappings" message, the user may now use "Rn,m" as
    one of the arguments. "n" and "m" are hexadecimal numbers. The "Rn,m"
    argument repeats the last "n" arguments in the following "m" slots.

    For example:
    dmsetup message switch 0 set_region_mappings 1000:1 :2 R2,10
    is equivalent to
    dmsetup message switch 0 set_region_mappings 1000:1 :2 :1 :2 :1 :2 :1 :2 \
    :1 :2 :1 :2 :1 :2 :1 :2 :1 :2

    Requested-by: Jay Wang
    Tested-by: Jay Wang
    Signed-off-by: Mikulas Patocka
    Signed-off-by: Mike Snitzer

    Mikulas Patocka
     

21 May, 2014

1 commit

  • Commit 85ad643b ("dm thin: add timeout to stop out-of-data-space mode
    holding IO forever") introduced a fixed 60 second timeout. Users may
    want to either disable or modify this timeout.

    Allow the out-of-data-space timeout to be configured using the
    'no_space_timeout' dm-thin-pool module param. Setting it to 0 will
    disable the timeout, resulting in IO being queued until more data space
    is added to the thin-pool.

    Signed-off-by: Mike Snitzer
    Cc: stable@vger.kernel.org # 3.14+

    Mike Snitzer
     

28 Mar, 2014

1 commit

  • dm-era is a target that behaves similar to the linear target. In
    addition it keeps track of which blocks were written within a user
    defined period of time called an 'era'. Each era target instance
    maintains the current era as a monotonically increasing 32-bit
    counter.

    Use cases include tracking changed blocks for backup software, and
    partially invalidating the contents of a cache to restore cache
    coherency after rolling back a vendor snapshot.

    dm-era is primarily expected to be paired with the dm-cache target.

    Signed-off-by: Joe Thornber
    Signed-off-by: Mike Snitzer

    Joe Thornber
     

07 Mar, 2014

1 commit


06 Mar, 2014

1 commit

  • If a thin metadata operation fails the current transaction will abort,
    whereby causing potential for IO layers up the stack (e.g. filesystems)
    to have data loss. As such, set THIN_METADATA_NEEDS_CHECK_FLAG in the
    thin metadata's superblock which:
    1) requires the user verify the thin metadata is consistent (e.g. use
    thin_check, etc)
    2) suggests the user verify the thin data is consistent (e.g. use fsck)

    The only way to clear the superblock's THIN_METADATA_NEEDS_CHECK_FLAG is
    to run thin_repair.

    On metadata operation failure: abort current metadata transaction, set
    pool in read-only mode, and now set the needs_check flag.

    As part of this change, constraints are introduced or relaxed:
    * don't allow a pool to transition to write mode if needs_check is set
    * don't allow data or metadata space to be resized if needs_check is set
    * if a thin pool's metadata space is exhausted: the kernel will now
    force the user to take the pool offline for repair before the kernel
    will allow the metadata space to be extended.

    Also, update Documentation to include information about when the thin
    provisioning target commits metadata, how it handles metadata failures
    and running out of space.

    Signed-off-by: Mike Snitzer
    Signed-off-by: Joe Thornber

    Mike Snitzer
     

17 Jan, 2014

1 commit

  • The cache's policy may have been established using the "default" alias,
    which is currently the "mq" policy but the default policy may change in
    the future. It is useful to know exactly which policy is being used.

    Add a 'real' member to the dm_cache_policy_type structure and have the
    "default" dm_cache_policy_type point to the real "mq"
    dm_cache_policy_type. Update dm_cache_policy_get_name() to check if
    real is set, if so report the name of the real policy (not the alias).

    Requested-by: Jonathan Brassow
    Signed-off-by: Mike Snitzer

    Mike Snitzer
     

10 Jan, 2014

1 commit

  • Improve cache_status to emit:
    /
    /
    ...

    Adding the block sizes allows for easier calculation of the overall size
    of both the metadata and cache devices. Adding
    provides useful context for how much of the cache is used.

    Unfortunately these additions to the status will require updates to
    users' scripts that monitor the cache status. But these changes help
    provide more comprehensive information about the cache device and will
    simplify tools that are being developed to manage dm-cache devices --
    because they won't need to issue 3 operations to cobble together the
    information that we can easily provide via a single status ioctl.

    While updating the status documentation in cache.txt spaces were
    tabify'd.

    Requested-by: Jonathan Brassow
    Signed-off-by: Mike Snitzer
    Acked-by: Joe Thornber

    Mike Snitzer
     

07 Jan, 2014

2 commits

  • Internally the mq policy maintains a promotion threshold variable. If
    the hit count of a block not in the cache goes above this threshold it
    gets promoted to the cache.

    This patch introduces three new tunables that allow you to tweak the
    promotion threshold by adding a small value. These adjustments depend
    on the io type:

    read_promote_adjustment: READ io, default 4
    write_promote_adjustment: WRITE io, default 8
    discard_promote_adjustment: READ/WRITE io to a discarded block, default 1

    If you're trying to quickly warm a new cache device you may wish to
    reduce these to encourage promotion. Remember to switch them back to
    their defaults after the cache fills though.

    Signed-off-by: Joe Thornber
    Signed-off-by: Mike Snitzer

    Joe Thornber
     
  • If the pool runs out of data or metadata space, the pool can either
    queue or error the IO destined to the data device. The default is to
    queue the IO until more space is added.

    An admin may now configure the pool to error IO when no space is
    available by setting the 'error_if_no_space' feature when loading the
    thin-pool table.

    Signed-off-by: Mike Snitzer
    Acked-by: Joe Thornber

    Mike Snitzer
     

11 Dec, 2013

1 commit


13 Nov, 2013

1 commit


12 Nov, 2013

2 commits

  • Cache block invalidation is removing an entry from the cache without
    writing it back. Cache blocks can be invalidated via the
    'invalidate_cblocks' message, which takes an arbitrary number of cblock
    ranges:
    invalidate_cblocks [|-]*

    E.g.
    dmsetup message my_cache 0 invalidate_cblocks 2345 3456-4567 5678-6789

    Signed-off-by: Joe Thornber
    Signed-off-by: Mike Snitzer

    Joe Thornber
     
  • "Passthrough" is a dm-cache operating mode (like writethrough or
    writeback) which is intended to be used when the cache contents are not
    known to be coherent with the origin device. It behaves as follows:

    * All reads are served from the origin device (all reads miss the cache)
    * All writes are forwarded to the origin device; additionally, write
    hits cause cache block invalidates

    This mode decouples cache coherency checks from cache device creation,
    largely to avoid having to perform coherency checks while booting. Boot
    scripts can create cache devices in passthrough mode and put them into
    service (mount cached filesystems, for example) without having to worry
    about coherency. Coherency that exists is maintained, although the
    cache will gradually cool as writes take place.

    Later, applications can perform coherency checks, the nature of which
    will depend on the type of the underlying storage. If coherency can be
    verified, the cache device can be transitioned to writethrough or
    writeback mode while still warm; otherwise, the cache contents can be
    discarded prior to transitioning to the desired operating mode.

    Signed-off-by: Joe Thornber
    Signed-off-by: Heinz Mauelshagen
    Signed-off-by: Morgan Mears
    Signed-off-by: Mike Snitzer

    Joe Thornber
     

10 Nov, 2013

2 commits

  • There are now two multiqueues for in cache blocks. A clean one and a
    dirty one.

    writeback_work comes from the dirty one. Demotions come from the clean
    one.

    There are two benefits:
    - Performance improvement, since demoting a clean block is a noop.
    - The cache cleans itself when io load is light.

    Signed-off-by: Joe Thornber
    Signed-off-by: Heinz Mauelshagen
    Signed-off-by: Mike Snitzer

    Joe Thornber
     
  • dm-crypt can already activate TCRYPT (TrueCrypt compatible) containers
    in LRW or XTS block encryption mode.

    TCRYPT containers prior to version 4.1 use CBC mode with some additional
    tweaks, this patch adds support for these containers.

    This new mode is implemented using special IV generator named TCW
    (TrueCrypt IV with whitening). TCW IV only supports containers that are
    encrypted with one cipher (Tested with AES, Twofish, Serpent, CAST5 and
    TripleDES).

    While this mode is legacy and is known to be vulnerable to some
    watermarking attacks (e.g. revealing of hidden disk existence) it can
    still be useful to activate old containers without using 3rd party
    software or for independent forensic analysis of such containers.

    (Both the userspace and kernel code is an independent implementation
    based on the format documentation and it completely avoids use of
    original source code.)

    The TCW IV generator uses two additional keys: Kw (whitening seed, size
    is always 16 bytes - TCW_WHITENING_SIZE) and Kiv (IV seed, size is
    always the IV size of the selected cipher). These keys are concatenated
    at the end of the main encryption key provided in mapping table.

    While whitening is completely independent from IV, it is implemented
    inside IV generator for simplification.

    The whitening value is always 16 bytes long and is calculated per sector
    from provided Kw as initial seed, xored with sector number and mixed
    with CRC32 algorithm. Resulting value is xored with ciphertext sector
    content.

    IV is calculated from the provided Kiv as initial IV seed and xored with
    sector number.

    Detailed calculation can be found in the Truecrypt documentation for
    version < 4.1 and will also be described on dm-crypt site, see:
    http://code.google.com/p/cryptsetup/wiki/DMCrypt

    The experimental support for activation of these containers is already
    present in git devel brach of cryptsetup.

    Signed-off-by: Milan Broz
    Signed-off-by: Mike Snitzer

    Milan Broz
     

06 Sep, 2013

1 commit

  • Support the collection of I/O statistics on user-defined regions of
    a DM device. If no regions are defined no statistics are collected so
    there isn't any performance impact. Only bio-based DM devices are
    currently supported.

    Each user-defined region specifies a starting sector, length and step.
    Individual statistics will be collected for each step-sized area within
    the range specified.

    The I/O statistics counters for each step-sized area of a region are
    in the same format as /sys/block/*/stat or /proc/diskstats but extra
    counters (12 and 13) are provided: total time spent reading and
    writing in milliseconds. All these counters may be accessed by sending
    the @stats_print message to the appropriate DM device via dmsetup.

    The creation of DM statistics will allocate memory via kmalloc or
    fallback to using vmalloc space. At most, 1/4 of the overall system
    memory may be allocated by DM statistics. The admin can see how much
    memory is used by reading
    /sys/module/dm_mod/parameters/stats_current_allocated_bytes

    See Documentation/device-mapper/statistics.txt for more details.

    Signed-off-by: Mikulas Patocka
    Signed-off-by: Mike Snitzer
    Signed-off-by: Alasdair G Kergon

    Mikulas Patocka
     

23 Aug, 2013

3 commits


12 Jul, 2013

1 commit

  • Pull device-mapper changes from Alasdair G Kergon:
    "Add a device-mapper target called dm-switch to provide a multipath
    framework for storage arrays that dynamically reconfigure their
    preferred paths for different device regions.

    Fix a bug in the verity target that prevented its use with some
    specific sizes of devices.

    Improve some locking mechanisms in the device-mapper core and bufio.

    Add Mike Snitzer as a device-mapper maintainer.

    A few more clean-ups and fixes"

    * tag 'dm-3.11-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm:
    dm: add switch target
    dm: update maintainers
    dm: optimize reorder structure
    dm: optimize use SRCU and RCU
    dm bufio: submit writes outside lock
    dm cache: fix arm link errors with inline
    dm verity: use __ffs and __fls
    dm flakey: correct ctr alloc failure mesg
    dm verity: remove pointless comparison
    dm: use __GFP_HIGHMEM in __vmalloc
    dm verity: fix inability to use a few specific devices sizes
    dm ioctl: set noio flag to avoid __vmalloc deadlock
    dm mpath: fix ioctl deadlock when no paths

    Linus Torvalds
     

11 Jul, 2013

1 commit

  • dm-switch is a new target that maps IO to underlying block devices
    efficiently when there is a large number of fixed-sized address regions
    but there is no simple pattern to allow for a compact mapping
    representation such as dm-stripe.

    Though we have developed this target for a specific storage device, Dell
    EqualLogic, we have made an effort to keep it as general purpose as
    possible in the hope that others may benefit.

    Originally developed by Jim Ramsay. Simplified by Mikulas Patocka.

    Signed-off-by: Jim Ramsay
    Signed-off-by: Mikulas Patocka
    Signed-off-by: Alasdair G Kergon

    Jim Ramsay
     

05 Jul, 2013

1 commit

  • Pull trivial tree updates from Jiri Kosina:
    "The usual stuff from trivial tree"

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial: (34 commits)
    treewide: relase -> release
    Documentation/cgroups/memory.txt: fix stat file documentation
    sysctl/net.txt: delete reference to obsolete 2.4.x kernel
    spinlock_api_smp.h: fix preprocessor comments
    treewide: Fix typo in printk
    doc: device tree: clarify stuff in usage-model.txt.
    open firmware: "/aliasas" -> "/aliases"
    md: bcache: Fixed a typo with the word 'arithmetic'
    irq/generic-chip: fix a few kernel-doc entries
    frv: Convert use of typedef ctl_table to struct ctl_table
    sgi: xpc: Convert use of typedef ctl_table to struct ctl_table
    doc: clk: Fix incorrect wording
    Documentation/arm/IXP4xx fix a typo
    Documentation/networking/ieee802154 fix a typo
    Documentation/DocBook/media/v4l fix a typo
    Documentation/video4linux/si476x.txt fix a typo
    Documentation/virtual/kvm/api.txt fix a typo
    Documentation/early-userspace/README fix a typo
    Documentation/video4linux/soc-camera.txt fix a typo
    lguest: fix CONFIG_PAE -> CONFIG_x86_PAE in comment
    ...

    Linus Torvalds
     

26 Jun, 2013

1 commit

  • MD: Remember the last sync operation that was performed

    This patch adds a field to the mddev structure to track the last
    sync operation that was performed. This is especially useful when
    it comes to what is recorded in mismatch_cnt in sysfs. If the
    last operation was "data-check", then it reports the number of
    descrepancies found by the user-initiated check. If it was a
    "repair" operation, then it is reporting the number of
    descrepancies repaired. etc.

    Signed-off-by: Jonathan Brassow
    Signed-off-by: NeilBrown

    Jonathan Brassow
     

14 Jun, 2013

1 commit

  • DM RAID: Add ability to restore transiently failed devices on resume

    This patch adds code to the resume function to check over the devices
    in the RAID array. If any are found to be marked as failed and their
    superblocks can be read, an attempt is made to reintegrate them into
    the array. This allows the user to refresh the array with a simple
    suspend and resume of the array - rather than having to load a
    completely new table, allocate and initialize all the structures and
    throw away the old instantiation.

    Signed-off-by: Jonathan Brassow
    Signed-off-by: NeilBrown

    Jonathan Brassow
     

28 May, 2013

1 commit


24 Apr, 2013

1 commit

  • DM RAID: Add message/status support for changing sync action

    This patch adds a message interface to dm-raid to allow the user to more
    finely control the sync actions being performed by the MD driver. This
    gives the user the ability to initiate "check" and "repair" (i.e. scrubbing).
    Two additional fields have been appended to the status output to provide more
    information about the type of sync action occurring and the results of those
    actions, specifically: and . These new fields
    will always be populated. This is essentially the device-mapper way of doing
    what MD controls through the 'sync_action' sysfs file and shows through the
    'mismatch_cnt' sysfs file.

    Signed-off-by: Jonathan Brassow
    Signed-off-by: NeilBrown

    Jonathan Brassow
     

06 Mar, 2013

1 commit

  • Pull md updates from NeilBrown:
    "Mostly little bugfixes.

    Only "feature" is a new RAID10 layout which slightly improves the
    number of sets of devices that can concurrently fail, without data
    loss."

    * tag 'md-3.9' of git://neil.brown.name/md:
    md: expedite metadata update when switching read-auto -> active
    md: remove CONFIG_MULTICORE_RAID456
    md/raid1,raid10: fix deadlock with freeze_array()
    md/raid0: improve error message when converting RAID4-with-spares to RAID0
    md: raid0: fix error return from create_stripe_zones.
    md: fix two bugs when attempting to resize RAID0 array.
    DM RAID: Add support for MD's RAID10 "far" and "offset" algorithms
    MD RAID10: Improve redundancy for 'far' and 'offset' algorithms (part 2)
    MD RAID10: Improve redundancy for 'far' and 'offset' algorithms (part 1)
    MD RAID10: Minor non-functional code changes
    md: raid1,10: Handle REQ_WRITE_SAME flag in write bios
    md: protect against crash upon fsync on ro array

    Linus Torvalds
     

02 Mar, 2013

3 commits

  • A simple cache policy that writes back all data to the origin.

    This is used to decommission a dm cache by emptying it.

    Signed-off-by: Heinz Mauelshagen
    Signed-off-by: Joe Thornber
    Signed-off-by: Alasdair G Kergon

    Heinz Mauelshagen
     
  • A cache policy that uses a multiqueue ordered by recent hit
    count to select which blocks should be promoted and demoted.
    This is meant to be a general purpose policy. It prioritises
    reads over writes.

    Signed-off-by: Joe Thornber
    Signed-off-by: Alasdair G Kergon

    Joe Thornber
     
  • Add a target that allows a fast device such as an SSD to be used as a
    cache for a slower device such as a disk.

    A plug-in architecture was chosen so that the decisions about which data
    to migrate and when are delegated to interchangeable tunable policy
    modules. The first general purpose module we have developed, called
    "mq" (multiqueue), follows in the next patch. Other modules are
    under development.

    Signed-off-by: Joe Thornber
    Signed-off-by: Heinz Mauelshagen
    Signed-off-by: Mike Snitzer
    Signed-off-by: Alasdair G Kergon

    Joe Thornber
     

26 Feb, 2013

1 commit

  • DM RAID: Add support for MD's RAID10 "far" and "offset" algorithms

    Until now, dm-raid.c only supported the "near" algorthm of MD's RAID10
    implementation. This patch adds support for the "far" and "offset"
    algorithms, but only with the improved redundancy that is brought with
    the introduction of the 'use_far_sets' bit, which shifts copied stripes
    according to smaller sets vs the entire array. That is, the 17th bit
    of the 'layout' variable that defines the RAID10 implementation will
    always be set. (More information on how the 'layout' variable selects
    the RAID10 algorithm can be found in the opening comments of
    drivers/md/raid10.c.)

    Signed-off-by: Jonathan Brassow
    Signed-off-by: NeilBrown

    Jonathan Brassow
     

24 Jan, 2013

1 commit

  • Before attempting to activate a RAID array, it is checked for sufficient
    redundancy. That is, we make sure that there are not too many failed
    devices - or devices specified for rebuild - to undermine our ability to
    activate the array. The current code performs this check twice - once to
    ensure there were not too many devices specified for rebuild by the user
    ('validate_rebuild_devices') and again after possibly experiencing a failure
    to read the superblock ('analyse_superblocks'). Neither of these checks are
    sufficient. The first check is done properly but with insufficient
    information about the possible failure state of the devices to make a good
    determination if the array can be activated. The second check is simply
    done wrong in the case of RAID10 because it doesn't account for the
    independence of the stripes (i.e. mirror sets). The solution is to use the
    properly written check ('validate_rebuild_devices'), but perform the check
    after the superblocks have been read and we know which devices have failed.
    This gives us one check instead of two and performs it in a location where
    it can be done right.

    Only RAID10 was affected and it was affected in the following ways:
    - the code did not properly catch the condition where a user specified
    a device for rebuild that already had a failed device in the same mirror
    set. (This condition would, however, be caught at a deeper level in MD.)
    - the code triggers a false positive and denies activation when devices in
    independent mirror sets have failed - counting the failures as though they
    were all in the same set.

    The most likely place this error was introduced (or this patch should have
    been included) is in commit 4ec1e369 - first introduced in v3.7-rc1.
    Consequently this fix should also go in v3.7.y, however there is a
    small conflict on the .version in raid_target, so I'll submit a
    separate patch to -stable.

    Cc: stable@vger.kernel.org
    Signed-off-by: Jonathan Brassow
    Signed-off-by: NeilBrown

    Jonathan Brassow
     

11 Oct, 2012

1 commit

  • DM RAID: Add code to validate replacement slots for RAID10 arrays

    RAID10 can handle 'copies - 1' failures for each mirror group. This code
    ensures the user has provided a valid array - one whose devices specified for
    rebuild do not exceed the amount of redundancy available.

    Signed-off-by: Jonathan Brassow
    Signed-off-by: NeilBrown

    Jonathan Brassow
     

02 Aug, 2012

1 commit

  • Pull md updates from NeilBrown.

    * 'for-next' of git://neil.brown.name/md:
    DM RAID: Add support for MD RAID10
    md/RAID1: Add missing case for attempting to repair known bad blocks.
    md/raid5: For odirect-write performance, do not set STRIPE_PREREAD_ACTIVE.
    md/raid1: don't abort a resync on the first badblock.
    md: remove duplicated test on ->openers when calling do_md_stop()
    raid5: Add R5_ReadNoMerge flag which prevent bio from merging at block layer
    md/raid1: prevent merging too large request
    md/raid1: read balance chooses idlest disk for SSD
    md/raid1: make sequential read detection per disk based
    MD RAID10: Export md_raid10_congested
    MD: Move macros from raid1*.h to raid1*.c
    MD RAID1: rename mirror_info structure
    MD RAID10: rename mirror_info structure
    MD RAID10: Fix compiler warning.
    raid5: add a per-stripe lock
    raid5: remove unnecessary bitmap write optimization
    raid5: lockless access raid5 overrided bi_phys_segments
    raid5: reduce chance release_stripe() taking device_lock

    Linus Torvalds
     

01 Aug, 2012

1 commit


27 Jul, 2012

3 commits

  • Add read-only and fail-io modes to thin provisioning.

    If a transaction commit fails the pool's metadata device will transition
    to "read-only" mode. If a commit fails once already in read-only mode
    the transition to "fail-io" mode occurs.

    Once in fail-io mode the pool and all associated thin devices will
    report a status of "Fail".

    Signed-off-by: Joe Thornber
    Signed-off-by: Mike Snitzer
    Signed-off-by: Alasdair G Kergon

    Joe Thornber
     
  • Support non-power-of-2 chunk sizes with dm striping for proper alignment
    of stripe IO on storage that has non-power-of-2 optimal IO sizes (e.g.
    RAID6 10+2).

    Signed-off-by: Mike Snitzer
    Signed-off-by: Mikulas Patocka
    Signed-off-by: Alasdair G Kergon

    Mike Snitzer
     
  • dm-stripe is supposed to ensure that all the space allocated to the
    stripes is fully used and that all stripes are the same size. This
    patch fixes the test. It checks that device length is divisible by the
    chunk size and checks that the resulting quotient is divisible by the
    number of stripes (which is equivalent to testing if device length is
    divisible by chunk_size * stripes).

    Previously, the code only tested that the number of sectors in the target
    was divisible by each of the chunk size and the number of stripes
    separately, which could leave entire stripes unused.

    (A setup that genuinely needs some stripes to be shorter than others
    can be created by concatenating striped targets.)

    Signed-off-by: Mikulas Patocka
    Signed-off-by: Alasdair G Kergon

    Mikulas Patocka
     

03 Jul, 2012

1 commit

  • Veritysetup is now part of cryptsetup package.
    Remove on-disk header description (which is not parsed in kernel)
    and point users to cryptsetup where it the format is documented.
    Mention units for block size paramaters.
    Fix target line specification and dmsetup parameters.

    Signed-off-by: Milan Broz
    Cc: stable@kernel.org
    Signed-off-by: Alasdair G Kergon

    Milan Broz
     

03 Jun, 2012

1 commit

  • This patch implements two new messages that can be sent to the thin
    pool target allowing it to take a snapshot of the _metadata_. This,
    read-only snapshot can be accessed by userland, concurrently with the
    live target.

    Only one metadata snapshot can be held at a time. The pool's status
    line will give the block location for the current msnap.

    Since version 0.1.5 of the userland thin provisioning tools, the
    thin_dump program displays the msnap as follows:

    thin_dump -m

    Available here: https://github.com/jthornber/thin-provisioning-tools

    Now that userland can access the metadata we can do various things
    that have traditionally been kernel side tasks:

    i) Incremental backups.

    By using metadata snapshots we can work out what blocks have
    changed over time. Combined with data snapshots we can ensure
    the data doesn't change while we back it up.

    A short proof of concept script can be found here:

    https://github.com/jthornber/thinp-test-suite/blob/master/incremental_backup_example.rb

    ii) Migration of thin devices from one pool to another.

    iii) Merging snapshots back into an external origin.

    iv) Asyncronous replication.

    Signed-off-by: Joe Thornber
    Signed-off-by: Alasdair G Kergon

    Joe Thornber