1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-20 05:44:20 +03:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Bryn M. Reeves
261b1e54e4 dmfilemapd: do not wait if file has been truncated 2017-06-07 19:41:54 +01:00
Bryn M. Reeves
08658195b9 dmfilemapd: update file block count at daemon start
The file block count stored in the filemap_monitor was lazily
initialised at the time of the first check. This causes problems
in the case that the file has been truncated between this time and
the time the daemon started: the initial block count and current
block count match and the daemon fails to detect a change.

Separate the setting of the block count from the check and make a
call to update the value at the start of _dmfilemapd().
2017-06-07 19:41:54 +01:00
Bryn M. Reeves
3d85c9ae57 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.
2017-06-07 19:41:50 +01:00
3 changed files with 39 additions and 30 deletions

View File

@@ -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

View File

@@ -357,30 +357,33 @@ static int _parse_args(int argc, char **argv, struct filemap_monitor *fm)
return 1;
}
static int _filemap_fd_check_changed(struct filemap_monitor *fm)
static int _filemap_fd_update_blocks(struct filemap_monitor *fm)
{
int64_t blocks, old_blocks;
struct stat buf;
if (fm->fd < 0) {
log_error("Filemap fd is not open.");
return -1;
return 0;
}
if (fstat(fm->fd, &buf)) {
log_error("Failed to fstat filemap file descriptor.");
return -1;
return 0;
}
blocks = buf.st_blocks;
fm->blocks = buf.st_blocks;
/* first check? */
if (fm->blocks < 0)
old_blocks = buf.st_blocks;
else
old_blocks = fm->blocks;
return 1;
}
fm->blocks = blocks;
static int _filemap_fd_check_changed(struct filemap_monitor *fm)
{
int64_t old_blocks;
old_blocks = fm->blocks;
if (!_filemap_fd_update_blocks(fm))
return -1;
return (fm->blocks != old_blocks);
}
@@ -683,7 +686,10 @@ static int _update_regions(struct dm_stats *dms, struct filemap_monitor *fm)
for (region = regions; *region != DM_STATS_REGIONS_ALL; region++)
nr_regions++;
if (regions[0] != fm->group_id) {
if (!nr_regions)
log_warn("File contains no extents: exiting.");
if (nr_regions && (regions[0] != fm->group_id)) {
log_warn("group_id changed from " FMTu64 " to " FMTu64,
fm->group_id, regions[0]);
fm->group_id = regions[0];
@@ -714,6 +720,9 @@ static int _dmfilemapd(struct filemap_monitor *fm)
if (!_filemap_monitor_set_notify(fm))
goto bad;
if (!_filemap_fd_update_blocks(fm))
goto bad;
if (!dm_stats_list(dms, DM_STATS_ALL_PROGRAMS)) {
log_error("Failed to list stats handle.");
goto bad;
@@ -747,17 +756,16 @@ static int _dmfilemapd(struct filemap_monitor *fm)
if ((check = _filemap_fd_check_changed(fm)) < 0)
goto bad;
if (!check)
goto wait;
if (!_update_regions(dms, fm))
if (check && !_update_regions(dms, fm))
goto bad;
running = !!fm->nr_regions;
if (!running)
continue;
wait:
_filemap_monitor_wait(FILEMAPD_WAIT_USECS);
running = !!fm->nr_regions;
/* mode=inode termination condions */
if (fm->mode == DM_FILEMAPD_FOLLOW_INODE) {
if (!_filemap_monitor_check_file_unlinked(fm))

View File

@@ -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;