master - raid: fix raid1 to mirror conversion
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0c8369099bc610...
Commit: 0c8369099bc6105f39982b3e36dd9a53c347b07a
Parent: 31564834db7610b37f52040fbba89f4c71de4c34
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Dec 10 20:01:05 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Dec 11 23:17:22 2016 +0100
raid: fix raid1 to mirror conversion
Fix order of operation when converting raid1 into old mirror.
Before any later metadata modification are initiated prepare
mirror_log device with all clearing.
Then directly convert raid1 into mirror with mirror_log.
This convertion now properly see as precommitted metadata
new 'mirror' and committed old 'raid' and is able to
preload all LVs.
---
WHATS_NEW | 1 +
lib/metadata/raid_manip.c | 13 +++++++------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 274430f..74627ba 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Fix lvconvert raid1 to mirror table reload order.
Add internal function for separate mirror log preparation.
Fix segfault in lvmetad from missing NULL in daemon_reply_simple.
Simplify internal _info_run() and use _setup_task_run() for mknod.
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 7c4ce61..5cbd819 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -2207,6 +2207,7 @@ static int _convert_raid1_to_mirror(struct logical_volume *lv,
int update_and_reload,
struct dm_list *removal_lvs)
{
+ struct logical_volume *log_lv;
struct lv_segment *seg = first_seg(lv);
if (!seg_is_raid1(seg)) {
@@ -2227,7 +2228,10 @@ static int _convert_raid1_to_mirror(struct logical_volume *lv,
return 0;
}
- init_mirror_in_sync(new_image_count > seg->area_count ? 0 : 1);
+ if (!(log_lv = prepare_mirror_log(lv, (new_image_count <= seg->area_count) /* in sync */,
+ new_region_size,
+ allocate_pvs, lv->vg->alloc)))
+ return_0; /* TODO remove log_lv on error path */
/* Change image pair count to requested # of images */
if (new_image_count != seg->area_count) {
@@ -2255,11 +2259,8 @@ static int _convert_raid1_to_mirror(struct logical_volume *lv,
seg->status &= ~RAID;
lv->status |= (MIRROR | MIRRORED);
- /* Add mirror_log LV (should happen in wih image allocation */
- if (!add_mirror_log(lv->vg->cmd, lv, 1, seg->region_size, allocate_pvs, lv->vg->alloc)) {
- log_error("Unable to add mirror log to %s.", display_lvname(lv));
- return 0;
- }
+ if (!attach_mirror_log(first_seg(lv), log_lv))
+ return_0;
return update_and_reload ? _lv_update_reload_fns_reset_eliminate_lvs(lv, removal_lvs) : 1;
}
6 years, 3 months
master - mirror: add prepare_mirror_log
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=31564834db7610...
Commit: 31564834db7610b37f52040fbba89f4c71de4c34
Parent: b9f9ce52ecb0de3b33b1d0e2294a1b13c744e655
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Dec 10 19:54:09 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Dec 11 23:16:16 2016 +0100
mirror: add prepare_mirror_log
Function prepares new mirror log LV in-sync optionaly.
This is useful to have such device ready when converting
raid1 to mirror.
---
WHATS_NEW | 1 +
lib/metadata/metadata-exported.h | 4 +++
lib/metadata/mirror.c | 43 ++++++++++++++++++++++++++++++++++++++
3 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 37a0dc7..274430f 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Add internal function for separate mirror log preparation.
Fix segfault in lvmetad from missing NULL in daemon_reply_simple.
Simplify internal _info_run() and use _setup_task_run() for mknod.
Better API for internal function _setup_task_run.
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index cdd4984..4bf466b 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1157,6 +1157,10 @@ struct logical_volume *detach_mirror_log(struct lv_segment *seg);
int attach_mirror_log(struct lv_segment *seg, struct logical_volume *lv);
int remove_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
struct dm_list *removable_pvs, int force);
+struct logical_volume *prepare_mirror_log(struct logical_volume *lv,
+ int in_sync, uint32_t region_size,
+ struct dm_list *allocatable_pvs,
+ alloc_policy_t alloc);
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t log_count, uint32_t region_size,
struct dm_list *allocatable_pvs, alloc_policy_t alloc);
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index e84916e..73b1110 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -1912,6 +1912,49 @@ int attach_mirror_log(struct lv_segment *seg, struct logical_volume *log_lv)
return add_seg_to_segs_using_this_lv(log_lv, seg);
}
+/* Prepare disk mirror log for raid1->mirror conversion */
+struct logical_volume *prepare_mirror_log(struct logical_volume *lv,
+ int in_sync, uint32_t region_size,
+ struct dm_list *allocatable_pvs,
+ alloc_policy_t alloc)
+{
+ struct cmd_context *cmd = lv->vg->cmd;
+ const struct segment_type *segtype;
+ struct dm_list *parallel_areas;
+ struct alloc_handle *ah;
+ struct logical_volume *log_lv;
+
+ if (!(parallel_areas = build_parallel_areas_from_lv(lv, 0, 0)))
+ return_NULL;
+
+ if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_MIRROR)))
+ return_NULL;
+
+ /* Allocate destination extents */
+ if (!(ah = allocate_extents(lv->vg, NULL, segtype,
+ 0, 0, 1, region_size,
+ lv->le_count, allocatable_pvs,
+ alloc, 0, parallel_areas))) {
+ log_error("Unable to allocate extents for mirror log.");
+ return NULL;
+ }
+
+ if (!(log_lv = _create_mirror_log(lv, ah, alloc, lv->name, "_mlog"))) {
+ log_error("Failed to create mirror log.");
+ goto out;
+ }
+
+ if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
+ log_error("Failed to initialise mirror log.");
+ log_lv = NULL;
+ goto out;
+ }
+out:
+ alloc_destroy(ah);
+
+ return log_lv;
+}
+
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t log_count, uint32_t region_size,
struct dm_list *allocatable_pvs, alloc_policy_t alloc)
6 years, 3 months
master - test: add results/ to .gitignore
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b9f9ce52ecb0de...
Commit: b9f9ce52ecb0de3b33b1d0e2294a1b13c744e655
Parent: 14c20ae217ecb42e77f1775ae9185a08e74ea2d3
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Sat Dec 10 18:00:25 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sat Dec 10 18:00:25 2016 +0000
test: add results/ to .gitignore
---
test/.gitignore | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/test/.gitignore b/test/.gitignore
index 2450c66..5b377c7 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -1,3 +1,4 @@
.bin-dir-stamp
bin
init.sh
+results/
6 years, 3 months
master - lvmdbusd: add path.py to .gitignore
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=14c20ae217ecb4...
Commit: 14c20ae217ecb42e77f1775ae9185a08e74ea2d3
Parent: f9c9772a80737e8f00f2c96dc2b033aaf85487c3
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Sat Dec 10 17:59:07 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sat Dec 10 17:59:07 2016 +0000
lvmdbusd: add path.py to .gitignore
---
daemons/lvmdbusd/.gitignore | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/daemons/lvmdbusd/.gitignore b/daemons/lvmdbusd/.gitignore
new file mode 100644
index 0000000..09375e7
--- /dev/null
+++ b/daemons/lvmdbusd/.gitignore
@@ -0,0 +1 @@
+path.py
6 years, 3 months
master - scripts: add systemd unit files to .gitignore
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f9c9772a80737e...
Commit: f9c9772a80737e8f00f2c96dc2b033aaf85487c3
Parent: 383683ffd390e1936474c3bced850ea887223478
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Sat Dec 10 17:58:10 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sat Dec 10 17:58:10 2016 +0000
scripts: add systemd unit files to .gitignore
com.redhat.lvmdbus1.service
lvm2_lvmdbusd_systemd_red_hat.service
.gitignore
---
scripts/.gitignore | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/scripts/.gitignore b/scripts/.gitignore
index ed0d945..0368f23 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -3,6 +3,7 @@ blk_availability_systemd_red_hat.service
blkdeactivate.sh
clvmd_init_red_hat
cmirrord_init_red_hat
+com.redhat.lvmdbus1.service
dm_event_systemd_red_hat.service
dm_event_systemd_red_hat.socket
lvm2_activation_generator_systemd_red_hat
@@ -10,6 +11,7 @@ lvm2_cluster_activation_red_hat.sh
lvm2_cluster_activation_systemd_red_hat.service
lvm2_clvmd_systemd_red_hat.service
lvm2_cmirrord_systemd_red_hat.service
+lvm2_lvmdbusd_systemd_red_hat.service
lvm2_lvmetad_init_red_hat
lvm2_lvmetad_systemd_red_hat.service
lvm2_lvmetad_systemd_red_hat.socket
6 years, 3 months
master - scripts: add lvmdump.sh to .gitignore
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=383683ffd390e1...
Commit: 383683ffd390e1936474c3bced850ea887223478
Parent: b311122a5666489f5dbeae09952dfbcd533f5a36
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Sat Dec 10 17:56:56 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sat Dec 10 17:56:56 2016 +0000
scripts: add lvmdump.sh to .gitignore
---
scripts/.gitignore | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 3a668ae..ed0d945 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -22,3 +22,4 @@ lvm2_monitoring_init_red_hat
lvm2_monitoring_systemd_red_hat.service
lvm2_pvscan_systemd_red_hat@.service
lvm2_tmpfiles_red_hat.conf
+lvmdump.sh
6 years, 3 months
master - libdm: fix filemap cleanup loop condition
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b311122a566648...
Commit: b311122a5666489f5dbeae09952dfbcd533f5a36
Parent: d8ba8ee9aea0b23a4ff03d19f7ddbe6511cdcbbd
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Sat Dec 10 13:28:21 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sat Dec 10 13:31:12 2016 +0000
libdm: fix filemap cleanup loop condition
---
libdm/libdm-stats.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index 78b66ab..850aa49 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -4323,7 +4323,7 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
struct dm_histogram *bounds,
int precise, uint64_t *count)
{
- uint64_t *regions = NULL, i, max_region;
+ uint64_t *regions = NULL, i, fail_region;
struct dm_pool *extent_mem = NULL;
struct _extent *extents = NULL;
char *hist_arg = NULL;
@@ -4411,8 +4411,8 @@ out_remove:
*/
dm_stats_list(dms, NULL);
- max_region = i;
- for (i = max_region - 1; i < max_region; i++)
+ fail_region = i;
+ for (i = 0; i < fail_region; i++)
if (!_stats_delete_region(dms, regions[i]))
log_error("Could not delete region " FMTu64 ".", i);
6 years, 3 months
master - libdm: use a private pool for filemap extent table
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d8ba8ee9aea0b2...
Commit: d8ba8ee9aea0b23a4ff03d19f7ddbe6511cdcbbd
Parent: 1de3e106c96f6df7b32e072b6a1a3f924fa041bc
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Sat Dec 10 13:07:03 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sat Dec 10 13:31:12 2016 +0000
libdm: use a private pool for filemap extent table
When mapping regions to a file descriptor, a temporary table of
extent descriptors is built using the dm_pool object building
interface.
Previously this use borrowed the dms->mem region and counter
table pool (since nothing can interleave with the allocation
while the caller is still in dm_stats_create_regions_from_fd()).
This turns out to be problematic for error recovery. When a
region creation operation fails partway through file mapping,
we need to roll back the set of already created regions and
this requires a listed handle: the dm_stats_list() will then
allocate from the same pool as the extents; we either have
to throw away valid list data, or leak the extent table, to
return the handle in a valid state.
Avoid this problem by creating a new, temporary mem pool in
_stats_create_file_regions() to hold the extent data, and
discarding it on exit from the function.
---
WHATS_NEW_DM | 1 +
libdm/libdm-stats.c | 19 ++++++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 4113876..73707b6 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.138 -
=====================================
+ Separate filemap extent allocation from region table.
Fix segmentation fault when filemap region creation fails
Fix performance of region cleanup for failed filemap creation.
Fix very slow region deletion with many regions.
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index 34870e3..78b66ab 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -4324,6 +4324,7 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
int precise, uint64_t *count)
{
uint64_t *regions = NULL, i, max_region;
+ struct dm_pool *extent_mem = NULL;
struct _extent *extents = NULL;
char *hist_arg = NULL;
struct statfs fsbuf;
@@ -4357,9 +4358,19 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
return 0;
}
- if (!(extents = _stats_get_extents_for_file(dms->mem, fd, count)))
+ /* Use a temporary, private pool for the extent table. This avoids
+ * hijacking the dms->mem (region table) pool which would lead to
+ * interleaving temporary allocations with dm_stats_list() data,
+ * causing complications in the error path.
+ */
+ if (!(extent_mem = dm_pool_create("extents", sizeof(*extents))))
return_0;
+ if (!(extents = _stats_get_extents_for_file(extent_mem, fd, count))) {
+ dm_pool_destroy(extent_mem);
+ return_0;
+ }
+
if (bounds) {
/* _build_histogram_arg enables precise if vals < 1ms. */
if (!(hist_arg = _build_histogram_arg(bounds, &precise)))
@@ -4386,7 +4397,8 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
if (bounds)
dm_free(hist_arg);
- dm_pool_free(dms->mem, extents);
+ dm_pool_free(extent_mem, extents);
+ dm_pool_destroy(extent_mem);
return regions;
out_remove:
@@ -4407,7 +4419,8 @@ out_remove:
*count = 0;
out:
- dm_pool_free(dms->mem, extents);
+ dm_pool_free(extent_mem, extents);
+ dm_pool_destroy(extent_mem);
dm_free(hist_arg);
dm_free(regions);
return NULL;
6 years, 3 months
master - doc: add filemap creation fixes to WHATS_NEW_DM
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1de3e106c96f6d...
Commit: 1de3e106c96f6df7b32e072b6a1a3f924fa041bc
Parent: 2d1dbb9eddd9dbc3aedf4572926178e532899995
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Sat Dec 10 12:02:30 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sat Dec 10 12:02:30 2016 +0000
doc: add filemap creation fixes to WHATS_NEW_DM
---
WHATS_NEW_DM | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index c6a4902..4113876 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,8 @@
Version 1.02.138 -
=====================================
+ Fix segmentation fault when filemap region creation fails
+ Fix performance of region cleanup for failed filemap creation.
+ Fix very slow region deletion with many regions.
Version 1.02.137 - 30th November 2016
=====================================
6 years, 3 months
master - libdm: fix performance of failed filemap cleanup
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2d1dbb9eddd9db...
Commit: 2d1dbb9eddd9dbc3aedf4572926178e532899995
Parent: 97c4490cc53157adde6da84933524f22149f449f
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Fri Dec 9 23:59:51 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sat Dec 10 11:59:16 2016 +0000
libdm: fix performance of failed filemap cleanup
While cleaning up the table of already created regions during a
failed dm_stats_create_regions_from_fd(), list the handle once,
and call _stats_delete_region() directly. This avoids sending a
@stats_list message for each region deleted, reducing runtime
from 6s to 0.7s when cleaning up ~250 out of ~10000 regions:
# time dmstats create --filemap b.img
device-mapper: message ioctl on (253:0) failed: Cannot allocate memory
Failed to create region 246 of 309 at 9388032.
Could not create regions from file /root/b.img
<< pauses here >>
Command failed
real 0m6.267s
user 0m3.770s
sys 0m2.487s
# time dmstats create --filemap b.img
device-mapper: message ioctl on (253:0) failed: Cannot allocate memory
Failed to create region 246 of 309 at 9388032.
Could not create regions from file /root/b.img
Command failed
real 0m0.716s
user 0m0.034s
sys 0m0.581s
Testing the error path requires region creation to start to
fail part way through the operation (in order to have regions
to clean up): the simplest way is to ensure the system is
close to the kernel limit of 1/4 RAM or 1/2 vmalloc space
consumed by dmstats data.
---
libdm/libdevmapper.h | 21 +++++++++++++--------
libdm/libdm-stats.c | 20 +++++++++++++++-----
2 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 09e3fcc..fe2e410 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1297,24 +1297,29 @@ int dm_stats_get_group_descriptor(const struct dm_stats *dms,
* filesystem and optionally place them into a group.
*
* File descriptor fd must reference a regular file, open for reading,
- * in a local file system that supports the FIEMAP ioctl and that
+ * in a local file system that supports the FIEMAP ioctl, and that
* returns data describing the physical location of extents.
*
* The file descriptor can be closed by the caller following the call
* to dm_stats_create_regions_from_fd().
*
- * The function returns a pointer to an array of uint64_t containing
- * the IDs of the newly created regions. The array is terminated by the
- * value DM_STATS_REGIONS_ALL and should be freed using dm_free() when
- * no longer required.
- *
* Unless nogroup is non-zero the regions will be placed into a group
- * and the group alias is set to the value supplied.
+ * and the group alias set to the value supplied (if alias is NULL no
+ * group alias will be assigned).
+ *
+ * On success the function returns a pointer to an array of uint64_t
+ * containing the IDs of the newly created regions. The region_id
+ * array is terminated by the value DM_STATS_REGION_NOT_PRESENT and
+ * should be freed using dm_free() when no longer required. On error
+ * NULL is returned.
+ *
+ * Following a call to dm_stats_create_regions_from_fd() the handle
+ * is guaranteed to be in a listed state, and to contain any region
+ * and group identifiers created by the operation.
*
* The group_id for the new group is equal to the region_id value in
* the first array element.
*
- * File mapped histograms will be supported in a future version.
*/
uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
int group, int precise,
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index 1cabd9a..34870e3 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -4323,8 +4323,8 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
struct dm_histogram *bounds,
int precise, uint64_t *count)
{
+ uint64_t *regions = NULL, i, max_region;
struct _extent *extents = NULL;
- uint64_t *regions = NULL, i;
char *hist_arg = NULL;
struct statfs fsbuf;
struct stat buf;
@@ -4390,11 +4390,22 @@ static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
return regions;
out_remove:
- /* clean up regions after create failure */
- for (--i; i != DM_STATS_REGION_NOT_PRESENT; i--)
- if (!dm_stats_delete_region(dms, regions[i]))
+ /* New region creation may begin to fail part-way through creating
+ * a set of file mapped regions: in this case we need to roll back
+ * the regions that were already created and return the handle to
+ * a consistent state. A listed handle is required for this: use a
+ * single list operation and call _stats_delete_region() directly
+ * to avoid a @stats_list ioctl and list parsing for each region.
+ */
+ dm_stats_list(dms, NULL);
+
+ max_region = i;
+ for (i = max_region - 1; i < max_region; i++)
+ if (!_stats_delete_region(dms, regions[i]))
log_error("Could not delete region " FMTu64 ".", i);
+ *count = 0;
+
out:
dm_pool_free(dms->mem, extents);
dm_free(hist_arg);
@@ -4402,7 +4413,6 @@ out:
return NULL;
}
-
uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
int group, int precise,
struct dm_histogram *bounds,
6 years, 3 months