mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
cache: check for cache fail during flush
Just WARN if the cache can't be flushed because it's failed.
This commit is contained in:
parent
569ba79abf
commit
5c415afd85
@ -1,5 +1,6 @@
|
||||
Version 2.02.146 -
|
||||
=================================
|
||||
Use new cache status info and skip flushing for failed cache.
|
||||
Support --uncache with missing PVs.
|
||||
Tidy report field names, headings and widths.
|
||||
Add vgscan --notifydbus to send a dbus notification.
|
||||
|
@ -1334,12 +1334,18 @@ int dev_manager_cache_status(struct dev_manager *dm,
|
||||
|
||||
c = (*status)->cache;
|
||||
(*status)->mem = dm->mem; /* User has to destroy this mem pool later */
|
||||
(*status)->data_usage = dm_make_percent(c->used_blocks,
|
||||
c->total_blocks);
|
||||
(*status)->metadata_usage = dm_make_percent(c->metadata_used_blocks,
|
||||
c->metadata_total_blocks);
|
||||
(*status)->dirty_usage = dm_make_percent(c->dirty_blocks,
|
||||
c->used_blocks);
|
||||
if (c->fail || c->error) {
|
||||
(*status)->data_usage =
|
||||
(*status)->metadata_usage =
|
||||
(*status)->dirty_usage = DM_PERCENT_INVALID;
|
||||
} else {
|
||||
(*status)->data_usage = dm_make_percent(c->used_blocks,
|
||||
c->total_blocks);
|
||||
(*status)->metadata_usage = dm_make_percent(c->metadata_used_blocks,
|
||||
c->metadata_total_blocks);
|
||||
(*status)->dirty_usage = dm_make_percent(c->dirty_blocks,
|
||||
c->used_blocks);
|
||||
}
|
||||
r = 1;
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
@ -359,10 +359,16 @@ int lv_cache_remove(struct logical_volume *cache_lv)
|
||||
*/
|
||||
if (!lv_cache_status(cache_lv, &status))
|
||||
return_0;
|
||||
dirty_blocks = status->cache->dirty_blocks;
|
||||
if (!(status->cache->feature_flags & DM_CACHE_FEATURE_WRITETHROUGH))
|
||||
dirty_blocks++; /* Not writethrough - always dirty */
|
||||
is_cleaner = !strcmp(status->cache->policy_name, "cleaner");
|
||||
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) {
|
||||
@ -378,6 +384,10 @@ int lv_cache_remove(struct logical_volume *cache_lv)
|
||||
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) {
|
||||
|
@ -1137,10 +1137,12 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
|
||||
}
|
||||
}
|
||||
|
||||
/* 'c' when thin-pool active with needs_check flag
|
||||
/* 'c' when cache/thin-pool is active with needs_check flag
|
||||
* 'C' for suspend */
|
||||
if (lv_is_thin_pool(lv) &&
|
||||
lvdm->seg_status.thin_pool->needs_check)
|
||||
if ((lv_is_thin_pool(lv) &&
|
||||
lvdm->seg_status.thin_pool->needs_check) ||
|
||||
(lv_is_cache(lv) &&
|
||||
lvdm->seg_status.cache->needs_check))
|
||||
repstr[4] = lvdm->info.suspended ? 'C' : 'c';
|
||||
|
||||
/*
|
||||
@ -1194,6 +1196,14 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
|
||||
repstr[8] = 'm'; /* RAID has 'm'ismatches */
|
||||
} else if (lv->status & LV_WRITEMOSTLY)
|
||||
repstr[8] = 'w'; /* sub-LV has 'w'ritemostly */
|
||||
} else if (lv_is_cache(lv) &&
|
||||
(lvdm->seg_status.type != SEG_STATUS_NONE)) {
|
||||
if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)
|
||||
repstr[8] = 'X'; /* Unknown */
|
||||
else if (lvdm->seg_status.cache->fail)
|
||||
repstr[8] = 'F';
|
||||
else if (lvdm->seg_status.cache->read_only)
|
||||
repstr[8] = 'M';
|
||||
} else if (lv_is_thin_pool(lv) &&
|
||||
(lvdm->seg_status.type != SEG_STATUS_NONE)) {
|
||||
if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)
|
||||
|
@ -3487,6 +3487,14 @@ static int _lvhealthstatus_disp(struct dm_report *rh, struct dm_pool *mem,
|
||||
health = "mismatches exist";
|
||||
} else if (lv->status & LV_WRITEMOSTLY)
|
||||
health = "writemostly";
|
||||
} else if (lv_is_cache(lv) && (lvdm->seg_status.type != SEG_STATUS_NONE)) {
|
||||
if (lvdm->seg_status.type != SEG_STATUS_CACHE)
|
||||
return _field_set_value(field, GET_FIRST_RESERVED_NAME(health_undef),
|
||||
GET_FIELD_RESERVED_VALUE(health_undef));
|
||||
else if (lvdm->seg_status.cache->fail)
|
||||
health = "failed";
|
||||
else if (lvdm->seg_status.cache->read_only)
|
||||
health = "metadata_read_only";
|
||||
} else if (lv_is_thin_pool(lv) && (lvdm->seg_status.type != SEG_STATUS_NONE)) {
|
||||
if (lvdm->seg_status.type != SEG_STATUS_THIN_POOL)
|
||||
return _field_set_value(field, GET_FIRST_RESERVED_NAME(health_undef),
|
||||
@ -3512,6 +3520,10 @@ static int _lvcheckneeded_disp(struct dm_report *rh, struct dm_pool *mem,
|
||||
return _binary_disp(rh, mem, field, lvdm->seg_status.thin_pool->needs_check,
|
||||
GET_FIRST_RESERVED_NAME(lv_check_needed_y), private);
|
||||
|
||||
if (lv_is_cache(lvdm->lv) && lvdm->seg_status.type == SEG_STATUS_CACHE)
|
||||
return _binary_disp(rh, mem, field, lvdm->seg_status.cache->needs_check,
|
||||
GET_FIRST_RESERVED_NAME(lv_check_needed_y), private);
|
||||
|
||||
return _binary_undef_disp(rh, mem, field, private);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user