aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2015-04-13 04:45:25 -0400
committerMike Snitzer <snitzer@redhat.com>2015-06-11 17:13:04 -0400
commit6550f075f5087459f64c1af71298fc50b102af11 (patch)
tree4822242b4a3499f0700905f725f3b5a44d254722
parenta5d895a90bf57e5fe87edf48dd1852e7292d570d (diff)
dm thin metadata: add dm_thin_remove_range()
Removes a range of blocks from the btree. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/dm-thin-metadata.c54
-rw-r--r--drivers/md/dm-thin-metadata.h2
2 files changed, 56 insertions, 0 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
index 94cf0db8a22e..8b521e3e1e1b 100644
--- a/drivers/md/dm-thin-metadata.c
+++ b/drivers/md/dm-thin-metadata.c
@@ -1526,6 +1526,47 @@ static int __remove(struct dm_thin_device *td, dm_block_t block)
1526 return 0; 1526 return 0;
1527} 1527}
1528 1528
1529static int __remove_range(struct dm_thin_device *td, dm_block_t begin, dm_block_t end)
1530{
1531 int r;
1532 unsigned count;
1533 struct dm_pool_metadata *pmd = td->pmd;
1534 dm_block_t keys[1] = { td->id };
1535 __le64 value;
1536 dm_block_t mapping_root;
1537
1538 /*
1539 * Find the mapping tree
1540 */
1541 r = dm_btree_lookup(&pmd->tl_info, pmd->root, keys, &value);
1542 if (r)
1543 return r;
1544
1545 /*
1546 * Remove from the mapping tree, taking care to inc the
1547 * ref count so it doesn't get deleted.
1548 */
1549 mapping_root = le64_to_cpu(value);
1550 dm_tm_inc(pmd->tm, mapping_root);
1551 r = dm_btree_remove(&pmd->tl_info, pmd->root, keys, &pmd->root);
1552 if (r)
1553 return r;
1554
1555 r = dm_btree_remove_leaves(&pmd->bl_info, mapping_root, &begin, end, &mapping_root, &count);
1556 if (r)
1557 return r;
1558
1559 td->mapped_blocks -= count;
1560 td->changed = 1;
1561
1562 /*
1563 * Reinsert the mapping tree.
1564 */
1565 value = cpu_to_le64(mapping_root);
1566 __dm_bless_for_disk(&value);
1567 return dm_btree_insert(&pmd->tl_info, pmd->root, keys, &value, &pmd->root);
1568}
1569
1529int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block) 1570int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block)
1530{ 1571{
1531 int r = -EINVAL; 1572 int r = -EINVAL;
@@ -1538,6 +1579,19 @@ int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block)
1538 return r; 1579 return r;
1539} 1580}
1540 1581
1582int dm_thin_remove_range(struct dm_thin_device *td,
1583 dm_block_t begin, dm_block_t end)
1584{
1585 int r = -EINVAL;
1586
1587 down_write(&td->pmd->root_lock);
1588 if (!td->pmd->fail_io)
1589 r = __remove_range(td, begin, end);
1590 up_write(&td->pmd->root_lock);
1591
1592 return r;
1593}
1594
1541int dm_pool_block_is_used(struct dm_pool_metadata *pmd, dm_block_t b, bool *result) 1595int dm_pool_block_is_used(struct dm_pool_metadata *pmd, dm_block_t b, bool *result)
1542{ 1596{
1543 int r; 1597 int r;
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h
index f11f14095b93..a938babe4258 100644
--- a/drivers/md/dm-thin-metadata.h
+++ b/drivers/md/dm-thin-metadata.h
@@ -167,6 +167,8 @@ int dm_thin_insert_block(struct dm_thin_device *td, dm_block_t block,
167 dm_block_t data_block); 167 dm_block_t data_block);
168 168
169int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block); 169int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block);
170int dm_thin_remove_range(struct dm_thin_device *td,
171 dm_block_t begin, dm_block_t end);
170 172
171/* 173/*
172 * Queries. 174 * Queries.