mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Handle orphan PVs too, so hints remain valid after vgreduce.
This commit is contained in:
parent
18d5a38594
commit
839f595181
@ -344,7 +344,7 @@ struct disk_list *read_disk(struct device *dev, struct pool *mem,
|
||||
int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter,
|
||||
struct pool *mem, struct list *head)
|
||||
{
|
||||
struct dev_iter *iter = dev_iter_create(filter);
|
||||
struct dev_iter *iter;
|
||||
struct device *dev;
|
||||
struct disk_list *data = NULL;
|
||||
|
||||
@ -364,12 +364,16 @@ int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter,
|
||||
list_size(head) == data->vgd.pv_cur))
|
||||
return 1;
|
||||
|
||||
/* Something changed. */
|
||||
/* Something changed. Remove the hints. */
|
||||
list_init(head);
|
||||
/* FIXME Do at a lower level? */
|
||||
vgcache_del(vg_name);
|
||||
}
|
||||
|
||||
if (!(iter = dev_iter_create(filter))) {
|
||||
log_error("read_pvs_in_vg: dev_iter_create failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise do a complete scan */
|
||||
for (dev = dev_iter_get(iter); dev; dev = dev_iter_get(iter)) {
|
||||
if ((data = read_disk(dev, mem, vg_name))) {
|
||||
@ -498,6 +502,7 @@ static int __write_all_pvd(struct disk_list *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
vgcache_add(data->pvd.vg_name, data->dev);
|
||||
/*
|
||||
* Stop here for orphan pv's.
|
||||
*/
|
||||
|
@ -12,19 +12,22 @@
|
||||
#include "log.h"
|
||||
|
||||
static struct hash_table *_vghash;
|
||||
static struct hash_table *_pvhash;
|
||||
|
||||
/* NULL is a special case that returns all devices */
|
||||
const char *null_const = "\0";
|
||||
const char *all_devices = "\0";
|
||||
|
||||
int vgcache_init()
|
||||
{
|
||||
if (!(_vghash = hash_create(128))) {
|
||||
if (!(_vghash = hash_create(128)))
|
||||
return 0;
|
||||
|
||||
if (!(_pvhash = hash_create(128)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* A vg_name of NULL returns all_devices */
|
||||
struct list *vgcache_find(const char *vg_name)
|
||||
{
|
||||
struct vgname_entry *vgn;
|
||||
@ -33,7 +36,7 @@ struct list *vgcache_find(const char *vg_name)
|
||||
return NULL;
|
||||
|
||||
if (!vg_name)
|
||||
vg_name = null_const;
|
||||
vg_name = all_devices;
|
||||
|
||||
if (!(vgn = hash_lookup(_vghash, vg_name)))
|
||||
return NULL;
|
||||
@ -41,9 +44,20 @@ struct list *vgcache_find(const char *vg_name)
|
||||
return &vgn->pvdevs;
|
||||
}
|
||||
|
||||
void vgcache_del_orphan(struct device *dev)
|
||||
{
|
||||
struct pvdev_list *pvdev;
|
||||
|
||||
if (_pvhash && ((pvdev = hash_lookup(_pvhash, dev_name(dev))))) {
|
||||
list_del(&pvdev->list);
|
||||
hash_remove(_pvhash, dev_name(pvdev->dev));
|
||||
dbg_free(pvdev);
|
||||
}
|
||||
}
|
||||
|
||||
int vgcache_add_entry(const char *vg_name, struct device *dev)
|
||||
{
|
||||
|
||||
const char *pv_name;
|
||||
struct vgname_entry *vgn;
|
||||
struct pvdev_list *pvdev;
|
||||
struct list *pvdh, *pvdevs;
|
||||
@ -63,7 +77,7 @@ int vgcache_add_entry(const char *vg_name, struct device *dev)
|
||||
}
|
||||
|
||||
if (!hash_insert(_vghash, vg_name, vgn)) {
|
||||
log_error("vgcache_add: hash insertion failed");
|
||||
log_error("vgcache_add: VG hash insertion failed");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -74,7 +88,16 @@ int vgcache_add_entry(const char *vg_name, struct device *dev)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(pvdev = dbg_malloc(sizeof(struct pvdev_list)))) {
|
||||
/* Remove PV from any existing VG unless an all_devices request */
|
||||
pvdev = NULL;
|
||||
pv_name = dev_name(dev);
|
||||
if (*vg_name && _pvhash && ((pvdev = hash_lookup(_pvhash, pv_name)))) {
|
||||
list_del(&pvdev->list);
|
||||
hash_remove(_pvhash, dev_name(pvdev->dev));
|
||||
}
|
||||
|
||||
/* Allocate new pvdev_list if there isn't an existing one to reuse */
|
||||
if (!pvdev && !(pvdev = dbg_malloc(sizeof(struct pvdev_list)))) {
|
||||
log_error("struct pvdev_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@ -82,18 +105,31 @@ int vgcache_add_entry(const char *vg_name, struct device *dev)
|
||||
pvdev->dev = dev;
|
||||
list_add(pvdevs, &pvdev->list);
|
||||
|
||||
if (*vg_name && _pvhash && !hash_insert(_pvhash, pv_name, pvdev)) {
|
||||
log_error("vgcache_add: PV hash insertion for %s "
|
||||
"failed", pv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* vg_name of "\0" is an orphan PV; NULL means only add to all_devices */
|
||||
int vgcache_add(const char *vg_name, struct device *dev)
|
||||
{
|
||||
if (!_vghash && !vgcache_init())
|
||||
return 0;
|
||||
|
||||
if (vg_name && !vgcache_add_entry(vg_name, dev))
|
||||
/* If orphan PV remove it */
|
||||
if (vg_name && !*vg_name)
|
||||
vgcache_del_orphan(dev);
|
||||
|
||||
/* Add PV if vg_name supplied */
|
||||
if (vg_name && *vg_name && !vgcache_add_entry(vg_name, dev))
|
||||
return 0;
|
||||
|
||||
return vgcache_add_entry(null_const, dev);
|
||||
/* Always add to all_devices */
|
||||
return vgcache_add_entry(all_devices, dev);
|
||||
}
|
||||
|
||||
void vgcache_destroy_entry(struct vgname_entry *vgn)
|
||||
@ -121,7 +157,7 @@ void vgcache_del(const char *vg_name)
|
||||
return;
|
||||
|
||||
if (!vg_name)
|
||||
vg_name = null_const;
|
||||
vg_name = all_devices;
|
||||
|
||||
if (!(vgn = hash_lookup(_vghash, vg_name)))
|
||||
return;
|
||||
@ -135,5 +171,11 @@ void vgcache_destroy()
|
||||
if (_vghash) {
|
||||
hash_iterate(_vghash, (iterate_fn)vgcache_destroy_entry);
|
||||
hash_destroy(_vghash);
|
||||
_vghash = NULL;
|
||||
}
|
||||
|
||||
if (_pvhash) {
|
||||
hash_destroy(_pvhash);
|
||||
_pvhash = NULL;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user