diff options
author | Bryn M. Reeves <bmr@redhat.com> | 2017-06-07 19:21:10 +0100 |
---|---|---|
committer | Bryn M. Reeves <bmr@redhat.com> | 2017-06-07 19:41:50 +0100 |
commit | 3d85c9ae574a9733a16b81871377a07ccc8866f3 (patch) | |
tree | ca48e243cba49589e93d3bb56251902001ac3af8 | |
parent | 39703cb48514415633bc027e49e99e1ee7c4bbb4 (diff) | |
download | lvm2-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_DM | 1 | ||||
-rw-r--r-- | libdm/libdm-stats.c | 24 |
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; |