mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
dev-cache: enhance usability of dm cache
With existing code, the cache was working only to the 2nd. locking. So i.e. when 'lvs' scans system with more then one VG, the caching was effectively not working. Update the code, so the label invalidate code is able to update DM cache - so whenever we take a new lock - we will refresh the cache. TODO: the refresh ATM does a very simple compare of old a new list of cached DM device, and with the first spotted difference, it just fallback to the full rebuild of DM cache - with large amount of active devices this might not the most efficient way....
This commit is contained in:
parent
96cea466a5
commit
7156b4930d
@ -1281,11 +1281,13 @@ void dm_devs_cache_destroy(void)
|
|||||||
_cache.use_dm_devs_cache = 0;
|
_cache.use_dm_devs_cache = 0;
|
||||||
|
|
||||||
if (_cache.dm_devnos) {
|
if (_cache.dm_devnos) {
|
||||||
|
log_debug_cache("Destroying DM devno cache.");
|
||||||
radix_tree_destroy(_cache.dm_devnos);
|
radix_tree_destroy(_cache.dm_devnos);
|
||||||
_cache.dm_devnos = NULL;
|
_cache.dm_devnos = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cache.dm_uuids) {
|
if (_cache.dm_uuids) {
|
||||||
|
log_debug_cache("Destroying DM uuid cache.");
|
||||||
radix_tree_destroy(_cache.dm_uuids);
|
radix_tree_destroy(_cache.dm_uuids);
|
||||||
_cache.dm_uuids = NULL;
|
_cache.dm_uuids = NULL;
|
||||||
}
|
}
|
||||||
@ -1293,23 +1295,64 @@ void dm_devs_cache_destroy(void)
|
|||||||
dm_device_list_destroy(&_cache.dm_devs);
|
dm_device_list_destroy(&_cache.dm_devs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Updates cached trees with active DM devices.
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* For large amount of active devices it might be useful
|
||||||
|
* to update existing trees - especially when there is high
|
||||||
|
* chance the set of active devices is nearly the same).
|
||||||
|
* However its not so trivial, so just make it a TODO.
|
||||||
|
* And do only an easy 1:1 match or full rebuild.
|
||||||
|
*/
|
||||||
int dm_devs_cache_update(void)
|
int dm_devs_cache_update(void)
|
||||||
{
|
{
|
||||||
struct dm_active_device *dm_dev;
|
struct dm_active_device *dm_dev, *dm_dev_new;
|
||||||
unsigned devs_features;
|
unsigned devs_features;
|
||||||
uint32_t d;
|
uint32_t d;
|
||||||
|
struct dm_list *dm_devs_new, *l;
|
||||||
|
int cache_changed = 0;
|
||||||
|
|
||||||
dm_devs_cache_destroy();
|
if (!get_dm_active_devices(NULL, &dm_devs_new, &devs_features))
|
||||||
|
|
||||||
if (!get_dm_active_devices(NULL, &_cache.dm_devs, &devs_features))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!(devs_features & DM_DEVICE_LIST_HAS_UUID)) {
|
if (!(devs_features & DM_DEVICE_LIST_HAS_UUID)) {
|
||||||
/* Cache unusable with older kernels without UUIDs in LIST */
|
/* Cache unusable with older kernels without UUIDs in LIST */
|
||||||
dm_device_list_destroy(&_cache.dm_devs);
|
dm_device_list_destroy(&dm_devs_new);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_cache.dm_devs) {
|
||||||
|
/* Compare existing cached list with a new one.
|
||||||
|
* When there is any mismatch, just rebuild whole cache */
|
||||||
|
l = dm_list_first(dm_devs_new);
|
||||||
|
dm_list_iterate_items(dm_dev, _cache.dm_devs) {
|
||||||
|
dm_dev_new = dm_list_item(l, struct dm_active_device);
|
||||||
|
if ((dm_dev->devno != dm_dev_new->devno) ||
|
||||||
|
strcmp(dm_dev->uuid, dm_dev_new->uuid)) {
|
||||||
|
log_debug_cache("Mismatching UUID or devno found %s %lu %s %lu",
|
||||||
|
dm_dev->uuid, dm_dev->devno,
|
||||||
|
dm_dev_new->uuid, dm_dev_new->devno);
|
||||||
|
cache_changed = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!(l = dm_list_next(dm_devs_new, l))) {
|
||||||
|
if (dm_list_next(_cache.dm_devs, &dm_dev->list))
|
||||||
|
cache_changed = 1; /* old cached list still with entries */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!cache_changed) {
|
||||||
|
log_debug_cache("Preserving DM cache.");
|
||||||
|
dm_device_list_destroy(&dm_devs_new);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dm_devs_cache_destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
_cache.dm_devs = dm_devs_new;
|
||||||
|
|
||||||
/* _cache.dm_devs entries are referenced by radix trees */
|
/* _cache.dm_devs entries are referenced by radix trees */
|
||||||
|
|
||||||
/* TODO: if _cache.dm_devs list is small, then skip the
|
/* TODO: if _cache.dm_devs list is small, then skip the
|
||||||
@ -1320,6 +1363,7 @@ int dm_devs_cache_update(void)
|
|||||||
return_0; // FIXME
|
return_0; // FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_debug_cache("Creating DM cache for devno and uuid.");
|
||||||
/* Insert every active DM device into radix trees */
|
/* Insert every active DM device into radix trees */
|
||||||
dm_list_iterate_items(dm_dev, _cache.dm_devs) {
|
dm_list_iterate_items(dm_dev, _cache.dm_devs) {
|
||||||
d = _shuffle_devno(dm_dev->devno);
|
d = _shuffle_devno(dm_dev->devno);
|
||||||
@ -1344,6 +1388,8 @@ void dm_devs_cache_label_invalidate(struct cmd_context *cmd)
|
|||||||
struct dm_active_device *dm_dev;
|
struct dm_active_device *dm_dev;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
|
||||||
|
dm_devs_cache_update();
|
||||||
|
|
||||||
dm_list_iterate_items(dm_dev, _cache.dm_devs) {
|
dm_list_iterate_items(dm_dev, _cache.dm_devs) {
|
||||||
if (dm_dev->uuid &&
|
if (dm_dev->uuid &&
|
||||||
strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) {
|
strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) {
|
||||||
|
@ -330,7 +330,6 @@ int vg_write_lock_held(void)
|
|||||||
|
|
||||||
int sync_local_dev_names(struct cmd_context* cmd)
|
int sync_local_dev_names(struct cmd_context* cmd)
|
||||||
{
|
{
|
||||||
dm_devs_cache_destroy();
|
|
||||||
memlock_unlock(cmd);
|
memlock_unlock(cmd);
|
||||||
fs_unlock();
|
fs_unlock();
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user