--- Documentation/device-mapper/thin-provisioning.txt | 25 ++++++++--------- drivers/md/dm-thin.c | 31 +++++++++------------- 2 files changed, 26 insertions(+), 30 deletions(-) Index: linux/Documentation/device-mapper/thin-provisioning.txt =================================================================== --- linux.orig/Documentation/device-mapper/thin-provisioning.txt +++ linux/Documentation/device-mapper/thin-provisioning.txt @@ -88,16 +88,15 @@ Using an existing pool device $data_block_size $low_water_mark" $data_block_size gives the smallest unit of disk space that can be -allocated at a time. As with all sizes passed to device-mapper, this -is expressed in units of 512-byte sectors. People primarily -interested in thin provisioning may want to use a value such as 1024. -People doing lots of snapshotting may want a smaller value such as -128. $data_block_size must be the same for the lifetime of the +allocated at a time expressed in units of 512-byte sectors. People +primarily interested in thin provisioning may want to use a value such +as 1024. People doing lots of snapshotting may want a smaller value +such as 128. $data_block_size must be the same for the lifetime of the metadata device. -$low_water_mark is expressed in 512-byte sectors. If free space on -the data device drops below this level then a dm event will be -triggered which a userspace daemon should catch allowing it to +$low_water_mark is expressed in blocks of size $data_block_size. If +free space on the data device drops below this level then a dm event +will be triggered which a userspace daemon should catch allowing it to extend the pool device. Only one such event will be sent. FIXME - Do we get a second event after a table reload when you're @@ -177,7 +176,7 @@ Reference i) Constructor thin-pool \ - [ []*] + [ []*] Optional feature arguments: - 'skip_block_zeroing': skips the zeroing of newly-provisioned blocks. @@ -187,16 +186,16 @@ i) Constructor ii) Status - / - / + / + / transaction id: A 64-bit number used by userspace to help synchronise with metadata from volume managers. - used data sectors / total data sectors - If the number of free sectors drops below the pool's low water mark a + used data blocks / total data blocks + If the number of free blocks drops below the pool's low water mark a dm event will be sent to userspace. This event is edge-triggered and it will occur only once after each resume so volume manager writers should register for the event and then check the target's status. Index: linux/drivers/md/dm-thin.c =================================================================== --- linux.orig/drivers/md/dm-thin.c +++ linux/drivers/md/dm-thin.c @@ -474,7 +474,7 @@ struct pool { uint32_t sectors_per_block; unsigned block_shift; dm_block_t offset_mask; - dm_block_t low_water_mark; + dm_block_t low_water_blocks; unsigned zero_new_blocks:1; unsigned low_water_triggered:1; /* A dm event has been sent */ @@ -512,7 +512,7 @@ struct pool_c { struct dm_dev *metadata_dev; struct dm_target_callbacks callbacks; - sector_t low_water_mark; + dm_block_t low_water_blocks; unsigned zero_new_blocks:1; }; @@ -986,7 +986,7 @@ static int alloc_data_block(struct thin_ if (r) return r; - if (free_blocks <= pool->low_water_mark && !pool->low_water_triggered) { + if (free_blocks <= pool->low_water_blocks && !pool->low_water_triggered) { DMWARN("%s: reached low water mark, sending event.", dm_device_name(pool->pool_md)); spin_lock_irqsave(&pool->lock, flags); @@ -1384,8 +1384,7 @@ static int bind_control_target(struct po struct pool_c *pt = ti->private; pool->ti = ti; - pool->low_water_mark = dm_sector_div_up(pt->low_water_mark, - pool->sectors_per_block); + pool->low_water_blocks = pt->low_water_blocks; pool->zero_new_blocks = pt->zero_new_blocks; dm_pool_rebind_metadata_device(pool->pmd, pt->metadata_dev->bdev); @@ -1447,7 +1446,7 @@ static struct pool *pool_create(struct m pool->sectors_per_block = block_size; pool->block_shift = ffs(block_size) - 1; pool->offset_mask = block_size - 1; - pool->low_water_mark = 0; + pool->low_water_blocks = 0; pool->zero_new_blocks = 1; pool->prison = prison_create(PRISON_CELLS); if (!pool->prison) { @@ -1641,7 +1640,7 @@ static int pool_ctr(struct dm_target *ti struct dm_arg_set as; struct dm_dev *data_dev; unsigned long block_size; - sector_t low_water; + dm_block_t low_water_blocks; struct dm_dev *metadata_dev; sector_t metadata_dev_size; @@ -1683,7 +1682,7 @@ static int pool_ctr(struct dm_target *ti goto out; } - if (kstrtoull(argv[3], 10, (unsigned long long *)&low_water)) { + if (kstrtoull(argv[3], 10, (unsigned long long *)&low_water_blocks)) { ti->error = "Invalid low water mark"; r = -EINVAL; goto out; @@ -1717,7 +1716,7 @@ static int pool_ctr(struct dm_target *ti pt->ti = ti; pt->metadata_dev = metadata_dev; pt->data_dev = data_dev; - pt->low_water_mark = low_water; + pt->low_water_blocks = low_water_blocks; pt->zero_new_blocks = pf.zero_new_blocks; ti->num_flush_requests = 1; ti->num_discard_requests = 0; @@ -2091,13 +2090,11 @@ static int pool_status(struct dm_target if (r) return r; - DMEMIT("%llu %llu/%llu %llu/%llu", (unsigned long long)transaction_id, - (unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata) * - pool->sectors_per_block, - (unsigned long long)nr_blocks_metadata * pool->sectors_per_block, - (unsigned long long)(nr_blocks_data - nr_free_blocks_data) * - pool->sectors_per_block, - (unsigned long long)nr_blocks_data * pool->sectors_per_block); + DMEMIT("%llu %llu/%llu %llu/%llu ", (unsigned long long)transaction_id, + (unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata), + (unsigned long long)nr_blocks_metadata, + (unsigned long long)(nr_blocks_data - nr_free_blocks_data), + (unsigned long long)nr_blocks_data); if (held_root) DMEMIT("%llu", held_root); @@ -2111,7 +2108,7 @@ static int pool_status(struct dm_target format_dev_t(buf, pt->metadata_dev->bdev->bd_dev), format_dev_t(buf2, pt->data_dev->bdev->bd_dev), (unsigned long)pool->sectors_per_block, - (unsigned long long)pt->low_water_mark); + (unsigned long long)pt->low_water_blocks); DMEMIT("%u ", !pool->zero_new_blocks);