1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +03:00

writecache: fix uncache for two step detach

Fix the two-step writecache detach in commit c32d7fed4f.
In the case of uncache, the cachevol is removed after
detaching the writecache.  When the detach is finished
in the second step, the remove must wait until then.
This commit is contained in:
David Teigland 2020-12-10 15:37:23 -06:00
parent 9fe7aba251
commit 5dbe2fdd9d
3 changed files with 106 additions and 2 deletions

View File

@ -149,5 +149,34 @@ lvchange -an $vg/$lv2
lvremove $vg/$lv1
lvremove $vg/$lv2
# Repeat similar using uncache
lvcreate -n $lv1 -L 560M -an $vg "$dev1"
lvcreate -n $lv2 -L 500M -an $vg "$dev2"
lvchange -ay $vg/$lv1
lvconvert --yes --type writecache --cachevol $lv2 $vg/$lv1
_add_new_data_to_mnt
_add_more_data_to_mnt
dd if=/dev/zero of=$mnt/big1 bs=1M count=100 oflag=sync
umount $mnt
lvchange -an $vg/$lv1
lvconvert --uncache $vg/$lv1
check lv_field $vg/$lv1 segtype linear
not lvs $vg/$lv2
lvchange -ay $vg/$lv1
mount "$DM_DEV_DIR/$vg/$lv1" $mnt
_verify_data_on_mnt
_verify_more_data_on_mnt
umount $mnt
lvchange -an $vg/$lv1
vgremove -ff $vg

View File

@ -171,5 +171,51 @@ lvconvert -y --type writecache --cachevol $lv2 $vg/$lv1
fail vgsplit $vg $vg1 "$dev2"
fail vgsplit $vg $vg1 "$dev3"
lvremove $vg/$lv1
vgremove $vg
#
# uncache
#
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3" "$dev4"
# while inactive
lvcreate -n $lv1 -l 16 -an $vg "$dev1" "$dev4"
lvcreate -n $lv2 -l 4 -an $vg "$dev2"
lvconvert -y --type writecache --cachevol $lv2 $vg/$lv1
lvchange -ay $vg/$lv1
mkfs_mount_umount $lv1
lvchange -an $vg/$lv1
lvconvert --uncache $vg/$lv1
lvs -o segtype $vg/$lv1 | grep linear
not lvs $vg/$lv2
lvchange -ay $vg/$lv1
mount_umount $lv1
lvchange -an $vg/$lv1
lvremove -y $vg/$lv1
# while active
lvcreate -n $lv1 -l 16 -an $vg "$dev1" "$dev4"
lvcreate -n $lv2 -l 4 -an $vg "$dev2"
lvconvert -y --type writecache --cachevol $lv2 $vg/$lv1
lvchange -ay $vg/$lv1
mkfs_mount_umount $lv1
lvconvert --uncache $vg/$lv1
lvs -o segtype $vg/$lv1 | grep linear
not lvs $vg/$lv2
lvchange -an $vg/$lv1
lvchange -ay $vg/$lv1
mount_umount $lv1
lvchange -an $vg/$lv1
lvremove -y $vg/$lv1
vgremove -ff $vg

View File

@ -3662,6 +3662,7 @@ struct lvconvert_result {
unsigned need_polling:1;
unsigned wait_cleaner_writecache:1;
unsigned active_begin:1;
unsigned remove_cache:1;
struct dm_list poll_idls;
};
@ -4966,8 +4967,18 @@ static int _lvconvert_split_cache_single(struct cmd_context *cmd,
return ECMD_FAILED;
if (cmd->command->command_enum == lvconvert_split_and_remove_cache_CMD) {
if (lvremove_single(cmd, lv_fast, NULL) != ECMD_PROCESSED)
return ECMD_FAILED;
struct lvconvert_result *lr = (struct lvconvert_result *) handle->custom_handle;
/*
* If detach is ongoing, then the remove needs to wait
* until _lvconvert_detach_writecache_when_clean(),
* after the detach has finished. When lr->remove_cache
* has been set, when_clean() knows it should remove
* lv_fast at the end.
*/
if (!lr->wait_cleaner_writecache) {
if (lvremove_single(cmd, lv_fast, NULL) != ECMD_PROCESSED)
return ECMD_FAILED;
}
}
ret = 1;
} else if (lv_is_cache(lv_main) && lv_is_cache_vol(lv_fast)) {
@ -5637,6 +5648,10 @@ static int _lvconvert_detach_writecache(struct cmd_context *cmd,
lr->wait_cleaner_writecache = 1;
lr->active_begin = active_begin;
/* The command wants to remove the cache after detaching. */
if (cmd->command->command_enum == lvconvert_split_and_remove_cache_CMD)
lr->remove_cache = 1;
dm_list_add(&lr->poll_idls, &idl->list);
return 1;
}
@ -5679,6 +5694,7 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
struct poll_operation_id *id;
struct volume_group *vg;
struct logical_volume *lv;
struct logical_volume *lv_fast;
uint32_t lockd_state, error_flags;
uint64_t dirty;
int ret;
@ -5759,6 +5775,8 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
log_print("Detaching writecache completed cleaning.");
lv_fast = first_seg(lv)->writecache;
/*
* When the cleaner has finished, we can detach with noflush since
* the cleaner has done the flushing.
@ -5770,6 +5788,17 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
goto out_release;
}
/*
* The detach was started by an uncache command that wants to remove
* the cachevol after detaching.
*/
if (lr->remove_cache) {
if (lvremove_single(cmd, lv_fast, NULL) != ECMD_PROCESSED) {
log_error("Removing the writecache cachevol failed.");
ret = 0;
}
}
ret = 1;
backup(vg);