#include <sys/ioctl.h>
#include <sys/mount.h>
+/*
+ * FIXME: all this opening and closing devices is
+ * killing performance.
+ */
+
int dev_get_size(struct device *dev, uint64_t *size)
{
int fd;
close(fd);
return r;
}
+
+int dev_zero(struct device *dev, uint64_t offset, int64_t len)
+{
+ int64_t r, s;
+ char buffer[4096];
+ const char *name = dev_name(dev);
+ int fd = open(name, O_WRONLY);
+
+ if (fd < 0) {
+ log_sys_error("open", name);
+ return 0;
+ }
+
+ if (lseek(fd, offset, SEEK_SET) < 0) {
+ log_sys_error("lseek", name);
+ return 0;
+ }
+
+ memset(buffer, 0, sizeof(buffer));
+ while (1) {
+ s = len > sizeof(buffer) ? sizeof(buffer) : len;
+ r = _write(fd, buffer, s);
+
+ if (r <= 0)
+ break;
+
+ len -= r;
+ if (!len) {
+ r = 1;
+ break;
+ }
+ }
+
+ close(fd);
+ return r;
+}
uint64_t offset, int64_t len, void *buffer);
int64_t dev_write(struct device *dev,
uint64_t offset, int64_t len, void *buffer);
+int dev_zero(struct device *dev, uint64_t offset, int64_t len);
static inline const char *dev_name(struct device *dev) {
return list_item(dev->aliases.n, struct str_list)->str;
return 1;
}
-static int _check_lvd(struct lv_disk *lvd)
+static inline int _check_lvd(struct lv_disk *lvd)
{
- /* FIXME: add more checks */
- if (lvd->lv_name[0] == '\0') {
- log_debug("lv has no name");
- return 0;
- }
-
- return 1;
+ return !(lvd->lv_name[0] == '\0');
}
static int _read_lvs(struct disk_list *data)
{
- int i;
+ int i, read = 0;
unsigned long pos;
struct lvd_list *ll;
+ struct vg_disk *vgd = &data->vgd;
- /* FIXME May be gaps - use lv_max */
- for(i = 0; i < data->vgd.lv_cur; i++) {
+ for(i = 0; (i < vgd->lv_max) && (read < vgd->lv_cur); i++) {
pos = data->pvd.lv_on_disk.base + (i * sizeof(struct lv_disk));
ll = pool_alloc(data->mem, sizeof(*ll));
fail;
if (!_check_lvd(&ll->lvd))
- fail;
+ continue;
+ read++;
list_add(&data->lvds, &ll->list);
}
unsigned long pos;
pos = data->pvd.lv_on_disk.base;
+
+ if (!dev_zero(data->dev, pos, data->pvd.lv_on_disk.size)) {
+ log_err("couldn't zero lv area on device '%s'",
+ dev_name(data->dev));
+ return 0;
+ }
+
list_iterate(lvh, &data->lvds) {
struct lvd_list *ll = list_item(lvh, struct lvd_list);
struct list *lvh;
struct lv_list *ll;
struct lvd_list *lvdl;
- int lv_num = 1, len;
+ int lv_num = 0, len;
/*
* setup the pv's extents array
export_lv(&lvdl->lvd, vg, &ll->lv, prefix);
lvdl->lvd.lv_number = lv_num;
- if (!export_extents(dl, lv_num++, &ll->lv, pv)) {
+ if (!export_extents(dl, lv_num + 1, &ll->lv, pv)) {
stack;
return 0;
}
list_add(&dl->lvds, &lvdl->list);
dl->pvd.lv_cur++;
+ lv_num++;
}
return 1;
}
}
list_init(&pvm->areas);
-
list_add(maps, &pvm->list);
}