summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryn M. Reeves <bmr@redhat.com>2017-06-07 19:21:10 +0100
committerBryn M. Reeves <bmr@redhat.com>2017-06-07 19:41:50 +0100
commit3d85c9ae574a9733a16b81871377a07ccc8866f3 (patch)
treeca48e243cba49589e93d3bb56251902001ac3af8
parent39703cb48514415633bc027e49e99e1ee7c4bbb4 (diff)
downloadlvm2-3d85c9ae574a9733a16b81871377a07ccc8866f3.tar.gz
libdm: allow truncated files dm_stats_update_regions_from_fd()
It's not an error to attempt to update regions from an fd that has been truncated (or otherwise no longer has any allocated extents): in this case, the call should remove all regions corresponding to the group, and return an empty region table.
-rw-r--r--WHATS_NEW_DM1
-rw-r--r--libdm/libdm-stats.c24
2 files changed, 13 insertions, 12 deletions
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 2894d6292..5718ab7ec 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.141 -
===============================
+ Accept truncated files in calls to dm_stats_update_regions_from_fd().
Restore Warning by 5% increment when thin-pool is over 80% (1.02.138).
Version 1.02.140 - 3rd May 2017
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index 6ce6c5755..b0c9e4bd4 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -4466,6 +4466,7 @@ static struct _extent *_stats_get_extents_for_file(struct dm_pool *mem, int fd,
return extents;
bad:
+ *count = 0;
dm_pool_abandon_object(mem);
dm_free(buf);
return NULL;
@@ -4536,7 +4537,7 @@ static int _stats_unmap_regions(struct dm_stats *dms, uint64_t group_id,
region = &dms->regions[i];
nr_old++;
- if (_find_extent(*count, extents,
+ if (extents && _find_extent(*count, extents,
region->start, region->len)) {
ext.start = region->start;
ext.len = region->len;
@@ -4653,11 +4654,12 @@ static uint64_t *_stats_map_file_regions(struct dm_stats *dms, int fd,
* causing complications in the error path.
*/
if (!(extent_mem = dm_pool_create("extents", sizeof(*extents))))
- return_0;
+ return_NULL;
if (!(extents = _stats_get_extents_for_file(extent_mem, fd, count))) {
- dm_pool_destroy(extent_mem);
- return_0;
+ log_very_verbose("No extents found in fd %d", fd);
+ if (!update)
+ goto out;
}
if (update) {
@@ -4734,7 +4736,10 @@ static uint64_t *_stats_map_file_regions(struct dm_stats *dms, int fd,
if (bounds)
dm_free(hist_arg);
- dm_pool_free(extent_mem, extents);
+ /* the extent table will be empty if the file has been truncated. */
+ if (extents)
+ dm_pool_free(extent_mem, extents);
+
dm_pool_destroy(extent_mem);
return regions;
@@ -4755,12 +4760,6 @@ out_remove:
*count = 0;
out:
- /*
- * The table of file extents in 'extents' is always built, so free
- * it explicitly: this will also free any 'old_extents' table that
- * was later allocated from the 'extent_mem' pool by this function.
- */
- dm_pool_free(extent_mem, extents);
dm_pool_destroy(extent_mem);
dm_free(hist_arg);
dm_free(regions);
@@ -4872,7 +4871,8 @@ uint64_t *dm_stats_update_regions_from_fd(struct dm_stats *dms, int fd,
if (!dm_stats_list(dms, NULL))
goto bad;
- if (regroup)
+ /* regroup if there are regions to group */
+ if (regroup && (*regions != DM_STATS_REGION_NOT_PRESENT))
if (!_stats_group_file_regions(dms, regions, count, alias))
goto bad;