[Sheepdog] [PATCH] sheepdog: add data preallocation support
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Sat May 21 14:35:19 CEST 2011
This introduces a qemu-img create option for sheepdog which allows the
data to be preallocated (note that sheepdog always preallocates
metadata). This is necessary to use Sheepdog volumes as a backend
storage for iSCSI target. More information is available at
https://sourceforge.net/apps/trac/sheepdog/wiki/General%20Protocol%20Support
The option is disabled by default and you need to enable it like the
following:
qemu-img create sheepdog:test -o preallocation=data 1G
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
---
block/sheepdog.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 72 insertions(+), 1 deletions(-)
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 0392ca8..38ca9aa 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1292,6 +1292,57 @@ static int do_sd_create(char *filename, int64_t vdi_size,
return 0;
}
+static int sd_prealloc(uint32_t vid, int64_t vdi_size)
+{
+ int fd, ret;
+ SheepdogInode *inode;
+ char *buf;
+ unsigned long idx, max_idx;
+
+ fd = connect_to_sdog(NULL, NULL);
+ if (fd < 0) {
+ return -EIO;
+ }
+
+ inode = qemu_malloc(sizeof(*inode));
+ buf = qemu_malloc(SD_DATA_OBJ_SIZE);
+
+ ret = read_object(fd, (char *)inode, vid_to_vdi_oid(vid),
+ 0, sizeof(*inode), 0);
+
+ max_idx = (vdi_size + SD_DATA_OBJ_SIZE - 1) / SD_DATA_OBJ_SIZE;
+
+ for (idx = 0; idx < max_idx; idx++) {
+ uint64_t oid;
+ oid = vid_to_data_oid(vid, idx);
+
+ if (inode->data_vdi_id[idx]) {
+ ret = read_object(fd, buf, vid_to_vdi_oid(inode->data_vdi_id[idx]),
+ 1, SD_DATA_OBJ_SIZE, 0);
+ if (ret)
+ goto out;
+ } else {
+ memset(buf, 0, SD_DATA_OBJ_SIZE);
+ }
+
+ ret = write_object(fd, buf, oid, 1, SD_DATA_OBJ_SIZE, 0, 1);
+ if (ret)
+ goto out;
+
+ inode->data_vdi_id[idx] = vid;
+ ret = write_object(fd, (char *)inode, vid_to_vdi_oid(vid),
+ 1, sizeof(*inode), 0, 0);
+ if (ret)
+ goto out;
+ }
+out:
+ free(inode);
+ free(buf);
+ closesocket(fd);
+
+ return ret;
+}
+
static int sd_create(const char *filename, QEMUOptionParameter *options)
{
int ret;
@@ -1301,6 +1352,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
BDRVSheepdogState s;
char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
uint32_t snapid;
+ int prealloc = 0;
strstart(filename, "sheepdog:", (const char **)&filename);
@@ -1317,6 +1369,16 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
vdi_size = options->value.n;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
backing_file = options->value.s;
+ } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
+ if (!options->value.s || !strcmp(options->value.s, "off")) {
+ prealloc = 0;
+ } else if (!strcmp(options->value.s, "data")) {
+ prealloc = 1;
+ } else {
+ error_report("Invalid preallocation mode: '%s'\n",
+ options->value.s);
+ return -EINVAL;
+ }
}
options++;
}
@@ -1354,7 +1416,11 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
bdrv_delete(bs);
}
- return do_sd_create((char *)vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port);
+ ret = do_sd_create((char *)vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port);
+ if (!prealloc || ret)
+ return ret;
+
+ return sd_prealloc(vid, vdi_size);
}
static void sd_close(BlockDriverState *bs)
@@ -1990,6 +2056,11 @@ static QEMUOptionParameter sd_create_options[] = {
.type = OPT_STRING,
.help = "File name of a base image"
},
+ {
+ .name = BLOCK_OPT_PREALLOC,
+ .type = OPT_STRING,
+ .help = "Preallocation mode (allowed values: off, data)"
+ },
{ NULL }
};
--
1.5.6.5
More information about the sheepdog
mailing list