summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Thornber <joe@fib011235813.fsnet.co.uk>2001-11-13 18:52:52 +0000
committerJoe Thornber <joe@fib011235813.fsnet.co.uk>2001-11-13 18:52:52 +0000
commitb90fc3a56e588310a6411ed65964bd142c133cfe (patch)
tree79803252dd96e2c87914df9b65221ff87f152430
parent1ef3fdccf5182789bd705ab912795fd278ad03af (diff)
downloadlvm2-b90fc3a56e588310a6411ed65964bd142c133cfe.tar.gz
o Deal with sparse lv arrays (on disk)
o new fn. dev_zero which zero's an area of a device
-rw-r--r--lib/device/dev-io.c41
-rw-r--r--lib/device/device.h1
-rw-r--r--lib/format1/disk-rep.c26
-rw-r--r--lib/format1/import-export.c5
-rw-r--r--lib/metadata/pv_map.c1
5 files changed, 59 insertions, 15 deletions
diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c
index 6ff16e8d4..1ece40263 100644
--- a/lib/device/dev-io.c
+++ b/lib/device/dev-io.c
@@ -15,6 +15,11 @@
#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;
@@ -126,3 +131,39 @@ int64_t dev_write(struct device *dev, uint64_t offset,
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;
+}
diff --git a/lib/device/device.h b/lib/device/device.h
index e690b979c..cdea30318 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -29,6 +29,7 @@ int64_t dev_read(struct device *dev,
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;
diff --git a/lib/format1/disk-rep.c b/lib/format1/disk-rep.c
index 7a590af80..f06ece0be 100644
--- a/lib/format1/disk-rep.c
+++ b/lib/format1/disk-rep.c
@@ -179,25 +179,19 @@ static int _read_uuids(struct disk_list *data)
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));
@@ -208,8 +202,9 @@ static int _read_lvs(struct disk_list *data)
fail;
if (!_check_lvd(&ll->lvd))
- fail;
+ continue;
+ read++;
list_add(&data->lvds, &ll->list);
}
@@ -391,6 +386,13 @@ static int _write_lvs(struct disk_list *data)
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);
diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c
index 84dca77da..cd6922589 100644
--- a/lib/format1/import-export.c
+++ b/lib/format1/import-export.c
@@ -476,7 +476,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
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
@@ -498,13 +498,14 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
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;
}
diff --git a/lib/metadata/pv_map.c b/lib/metadata/pv_map.c
index 5a3a8de00..9666e1b87 100644
--- a/lib/metadata/pv_map.c
+++ b/lib/metadata/pv_map.c
@@ -29,7 +29,6 @@ static int _create_maps(struct pool *mem, struct list *pvs, struct list *maps)
}
list_init(&pvm->areas);
-
list_add(maps, &pvm->list);
}