mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
cache: check for clean cache as separete function
This commit is contained in:
parent
588455d03e
commit
8b5967e1e3
@ -278,6 +278,61 @@ struct logical_volume *lv_cache_create(struct logical_volume *pool_lv,
|
|||||||
return cache_lv;
|
return cache_lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks cache status and loops until there are not dirty blocks
|
||||||
|
* Set 1 to *is_clean when there are no dirty blocks on return.
|
||||||
|
*/
|
||||||
|
int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean)
|
||||||
|
{
|
||||||
|
struct lv_segment *cache_seg = first_seg(cache_lv);
|
||||||
|
struct lv_status_cache *status;
|
||||||
|
int cleaner_policy;
|
||||||
|
uint64_t dirty_blocks;
|
||||||
|
|
||||||
|
*is_clean = 0;
|
||||||
|
|
||||||
|
//FIXME: use polling to do this...
|
||||||
|
for (;;) {
|
||||||
|
if (!lv_cache_status(cache_lv, &status))
|
||||||
|
return_0;
|
||||||
|
if (status->cache->fail) {
|
||||||
|
dm_pool_destroy(status->mem);
|
||||||
|
log_warn("WARNING: Skippping flush for failed cache.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleaner_policy = !strcmp(status->cache->policy_name, "cleaner");
|
||||||
|
dirty_blocks = status->cache->dirty_blocks;
|
||||||
|
|
||||||
|
/* No clear policy and writeback mode means dirty */
|
||||||
|
if (!cleaner_policy &&
|
||||||
|
(status->cache->feature_flags & DM_CACHE_FEATURE_WRITEBACK))
|
||||||
|
dirty_blocks++;
|
||||||
|
dm_pool_destroy(status->mem);
|
||||||
|
|
||||||
|
if (!dirty_blocks)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (cleaner_policy) {
|
||||||
|
log_print_unless_silent(FMTu64 " blocks must still be flushed.",
|
||||||
|
dirty_blocks);
|
||||||
|
sleep(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Switch to cleaner policy to flush the cache */
|
||||||
|
log_print_unless_silent("Flushing cache for %s.",
|
||||||
|
display_lvname(cache_lv));
|
||||||
|
cache_seg->cleaner_policy = 1;
|
||||||
|
/* Reaload kernel with "cleaner" policy */
|
||||||
|
if (!lv_update_and_reload_origin(cache_lv))
|
||||||
|
return_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*is_clean = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* lv_cache_remove
|
* lv_cache_remove
|
||||||
* @cache_lv
|
* @cache_lv
|
||||||
@ -291,12 +346,10 @@ struct logical_volume *lv_cache_create(struct logical_volume *pool_lv,
|
|||||||
*/
|
*/
|
||||||
int lv_cache_remove(struct logical_volume *cache_lv)
|
int lv_cache_remove(struct logical_volume *cache_lv)
|
||||||
{
|
{
|
||||||
int is_cleaner;
|
|
||||||
uint64_t dirty_blocks;
|
|
||||||
struct lv_segment *cache_seg = first_seg(cache_lv);
|
struct lv_segment *cache_seg = first_seg(cache_lv);
|
||||||
struct logical_volume *corigin_lv;
|
struct logical_volume *corigin_lv;
|
||||||
struct logical_volume *cache_pool_lv;
|
struct logical_volume *cache_pool_lv;
|
||||||
struct lv_status_cache *status;
|
int is_clear;
|
||||||
|
|
||||||
if (!lv_is_cache(cache_lv)) {
|
if (!lv_is_cache(cache_lv)) {
|
||||||
log_error(INTERNAL_ERROR "LV %s is not cache volume.",
|
log_error(INTERNAL_ERROR "LV %s is not cache volume.",
|
||||||
@ -356,45 +409,8 @@ int lv_cache_remove(struct logical_volume *cache_lv)
|
|||||||
* remove the cache_pool then without waiting for the flush to
|
* remove the cache_pool then without waiting for the flush to
|
||||||
* complete.
|
* complete.
|
||||||
*/
|
*/
|
||||||
if (!lv_cache_status(cache_lv, &status))
|
if (!lv_cache_wait_for_clean(cache_lv, &is_clear))
|
||||||
return_0;
|
return_0;
|
||||||
if (!status->cache->fail) {
|
|
||||||
is_cleaner = !strcmp(status->cache->policy_name, "cleaner");
|
|
||||||
dirty_blocks = status->cache->dirty_blocks;
|
|
||||||
if (!(status->cache->feature_flags & DM_CACHE_FEATURE_WRITETHROUGH))
|
|
||||||
dirty_blocks++; /* Not writethrough - always dirty */
|
|
||||||
} else {
|
|
||||||
log_warn("WARNING: Skippping flush for failed cache.");
|
|
||||||
is_cleaner = 0;
|
|
||||||
dirty_blocks = 0;
|
|
||||||
}
|
|
||||||
dm_pool_destroy(status->mem);
|
|
||||||
|
|
||||||
if (dirty_blocks && !is_cleaner) {
|
|
||||||
/* Switch to cleaner policy to flush the cache */
|
|
||||||
log_print_unless_silent("Flushing cache for %s.", cache_lv->name);
|
|
||||||
cache_seg->cleaner_policy = 1;
|
|
||||||
/* update the kernel to put the cleaner policy in place */
|
|
||||||
if (!lv_update_and_reload_origin(cache_lv))
|
|
||||||
return_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//FIXME: use polling to do this...
|
|
||||||
while (dirty_blocks) {
|
|
||||||
if (!lv_cache_status(cache_lv, &status))
|
|
||||||
return_0;
|
|
||||||
if (status->cache->fail) {
|
|
||||||
log_warn("WARNING: Flushing of failing cache skipped.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
dirty_blocks = status->cache->dirty_blocks;
|
|
||||||
dm_pool_destroy(status->mem);
|
|
||||||
if (dirty_blocks) {
|
|
||||||
log_print_unless_silent(FMTu64 " blocks must still be flushed.",
|
|
||||||
dirty_blocks);
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_pool_lv = cache_seg->pool_lv;
|
cache_pool_lv = cache_seg->pool_lv;
|
||||||
if (!detach_pool_lv(cache_seg))
|
if (!detach_pool_lv(cache_seg))
|
||||||
|
@ -1226,6 +1226,7 @@ int validate_lv_cache_create_pool(const struct logical_volume *pool_lv);
|
|||||||
int validate_lv_cache_create_origin(const struct logical_volume *origin_lv);
|
int validate_lv_cache_create_origin(const struct logical_volume *origin_lv);
|
||||||
struct logical_volume *lv_cache_create(struct logical_volume *pool,
|
struct logical_volume *lv_cache_create(struct logical_volume *pool,
|
||||||
struct logical_volume *origin);
|
struct logical_volume *origin);
|
||||||
|
int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean);
|
||||||
int lv_cache_remove(struct logical_volume *cache_lv);
|
int lv_cache_remove(struct logical_volume *cache_lv);
|
||||||
int wipe_cache_pool(struct logical_volume *cache_pool_lv);
|
int wipe_cache_pool(struct logical_volume *cache_pool_lv);
|
||||||
/* -- metadata/cache_manip.c */
|
/* -- metadata/cache_manip.c */
|
||||||
|
Loading…
Reference in New Issue
Block a user