1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

vgchange: invalidate bcache for stacked LVs when deactivating

An LV with a stacked PV will be open in bcache and needs to be
invalidated to close the fd before attempting to deactivate.
This commit is contained in:
David Teigland 2018-02-16 14:18:55 -06:00
parent 34fd818caf
commit 0da296003d
4 changed files with 33 additions and 15 deletions

View File

@ -20,6 +20,7 @@
#include "lvmcache.h" #include "lvmcache.h"
#include "bcache.h" #include "bcache.h"
#include "toolcontext.h" #include "toolcontext.h"
#include "activate.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
@ -725,6 +726,24 @@ void label_scan_invalidate(struct device *dev)
} }
} }
/*
* If a PV is stacked on an LV, then the LV is kept open
* in bcache, and needs to be closed so the open fd doesn't
* interfere with processing the LV.
*/
void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv)
{
struct lvinfo lvinfo;
struct device *dev;
dev_t devt;
lv_info(cmd, lv, 0, &lvinfo, 0, 0);
devt = MKDEV(lvinfo.major, lvinfo.minor);
if ((dev = dev_cache_get_by_devt(devt, cmd->filter)))
label_scan_invalidate(dev);
}
/* /*
* Undo label_scan() * Undo label_scan()
* *

View File

@ -106,6 +106,7 @@ int label_scan(struct cmd_context *cmd);
int label_scan_devs(struct cmd_context *cmd, struct dm_list *devs); int label_scan_devs(struct cmd_context *cmd, struct dm_list *devs);
int label_scan_devs_excl(struct dm_list *devs); int label_scan_devs_excl(struct dm_list *devs);
void label_scan_invalidate(struct device *dev); void label_scan_invalidate(struct device *dev);
void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv);
void label_scan_destroy(struct cmd_context *cmd); void label_scan_destroy(struct cmd_context *cmd);
int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector); int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector);
int label_read_sector(struct device *dev, struct label **labelp, uint64_t scan_sector); int label_read_sector(struct device *dev, struct label **labelp, uint64_t scan_sector);

View File

@ -3009,7 +3009,6 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
log_report_t saved_log_report_state = log_get_report_state(); log_report_t saved_log_report_state = log_get_report_state();
char lv_uuid[64] __attribute__((aligned(8))); char lv_uuid[64] __attribute__((aligned(8)));
char vg_uuid[64] __attribute__((aligned(8))); char vg_uuid[64] __attribute__((aligned(8)));
struct lvinfo lvinfo;
int ret_max = ECMD_PROCESSED; int ret_max = ECMD_PROCESSED;
int ret = 0; int ret = 0;
int whole_selected = 0; int whole_selected = 0;
@ -3026,8 +3025,6 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
struct lv_list *final_lvl; struct lv_list *final_lvl;
struct dm_list found_arg_lvnames; struct dm_list found_arg_lvnames;
struct glv_list *glvl, *tglvl; struct glv_list *glvl, *tglvl;
struct device *dev;
dev_t devt;
int do_report_ret_code = 1; int do_report_ret_code = 1;
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LV); log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LV);
@ -3170,12 +3167,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
* in bcache, and needs to be closed so the open fd doesn't * in bcache, and needs to be closed so the open fd doesn't
* interfere with processing the LV. * interfere with processing the LV.
*/ */
dm_list_iterate_items(lvl, &final_lvs) { dm_list_iterate_items(lvl, &final_lvs)
lv_info(cmd, lvl->lv, 0, &lvinfo, 0, 0); label_scan_invalidate_lv(cmd, lvl->lv);
devt = MKDEV(lvinfo.major, lvinfo.minor);
if ((dev = dev_cache_get_by_devt(devt, cmd->filter)))
label_scan_invalidate(dev);
}
dm_list_iterate_items(lvl, &final_lvs) { dm_list_iterate_items(lvl, &final_lvs) {
lv_uuid[0] = '\0'; lv_uuid[0] = '\0';

View File

@ -209,15 +209,20 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
cmd->handles_missing_pvs = 1; cmd->handles_missing_pvs = 1;
/* FIXME: Force argument to deactivate them? */ /* FIXME: Force argument to deactivate them? */
if (!do_activate && (lv_open = lvs_in_vg_opened(vg))) { if (!do_activate) {
dm_list_iterate_items(lvl, &vg->lvs) dm_list_iterate_items(lvl, &vg->lvs)
if (lv_is_visible(lvl->lv) && label_scan_invalidate_lv(cmd, lvl->lv);
!lv_check_not_in_use(lvl->lv, 1)) {
log_error("Can't deactivate volume group \"%s\" with %d open " if ((lv_open = lvs_in_vg_opened(vg))) {
"logical volume(s)", vg->name, lv_open); dm_list_iterate_items(lvl, &vg->lvs) {
if (lv_is_visible(lvl->lv) && !lv_check_not_in_use(lvl->lv, 1)) {
log_error("Can't deactivate volume group \"%s\" with %d open logical volume(s)",
vg->name, lv_open);
return 0; return 0;
} }
} }
}
}
/* FIXME Move into library where clvmd can use it */ /* FIXME Move into library where clvmd can use it */
if (do_activate) if (do_activate)