Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Marcelo Tosatti
On Tue, Nov 15, 2011 at 01:28:51PM +0800, Dong Xu Wang wrote:
 From: Dong Xu Wang wdon...@linux.vnet.ibm.com
 
 Provide a new file format: add-cow. The usage can be found in add-cow.txt of
 this patch.
 
 Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com
 ---
  Makefile.objs  |1 +
  block.c|2 +-
  block.h|1 +
  block/add-cow.c|  417 
 
  block_int.h|1 +
  docs/specs/add-cow.txt |   57 +++
  6 files changed, 478 insertions(+), 1 deletions(-)
  create mode 100644 block/add-cow.c
  create mode 100644 docs/specs/add-cow.txt
 
 diff --git a/Makefile.objs b/Makefile.objs
 index d7a6539..ad99243 100644
 --- a/Makefile.objs
 +++ b/Makefile.objs
 @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
  
  block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o 
 vpc.o vvfat.o
  block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o 
 qcow2-cache.o
 +block-nested-y += add-cow.o
  block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
  block-nested-y += qed-check.o
  block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
 diff --git a/block.c b/block.c
 index 86910b0..a2be27b 100644
 --- a/block.c
 +++ b/block.c
 @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename)
  #endif
  
  /* check if the path starts with protocol: */
 -static int path_has_protocol(const char *path)
 +int path_has_protocol(const char *path)
  {
  #ifdef _WIN32
  if (is_windows_drive(path) ||
 diff --git a/block.h b/block.h
 index 051a25d..836284f 100644
 --- a/block.h
 +++ b/block.h
 @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, 
 QEMUSnapshotInfo *sn);
  
  char *get_human_readable_size(char *buf, int buf_size, int64_t size);
  int path_is_absolute(const char *path);
 +int path_has_protocol(const char *path);
  void path_combine(char *dest, int dest_size,
const char *base_path,
const char *filename);
 diff --git a/block/add-cow.c b/block/add-cow.c
 new file mode 100644
 index 000..54d30a9
 --- /dev/null
 +++ b/block/add-cow.c
 @@ -0,0 +1,417 @@
 +#include qemu-common.h
 +#include block_int.h
 +#include module.h
 +
 +#define ADD_COW_MAGIC   (((uint64_t)'A'  56) | ((uint64_t)'D'  48) | 
 \
 +((uint64_t)'D'  40) | ((uint64_t)'_'  32) | \
 +((uint64_t)'C'  24) | ((uint64_t)'O'  16) | \
 +((uint64_t)'W'  8) | 0xFF)
 +#define ADD_COW_VERSION 1
 +#define ADD_COW_FILE_LEN1024
 +
 +typedef struct AddCowHeader {
 +uint64_tmagic;
 +uint32_tversion;
 +charbacking_file[ADD_COW_FILE_LEN];
 +charimage_file[ADD_COW_FILE_LEN];
 +uint64_tsize;
 +} QEMU_PACKED AddCowHeader;
 +
 +typedef struct BDRVAddCowState {
 +charimage_file[ADD_COW_FILE_LEN];
 +BlockDriverState*image_hd;
 +uint8_t *bitmap;
 +uint64_tbitmap_size;
 +CoMutex lock;
 +} BDRVAddCowState;
 +
 +static int add_cow_probe(const uint8_t *buf, int buf_size, const char 
 *filename)
 +{
 +const AddCowHeader *header = (const void *)buf;
 +
 +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC 
 +be32_to_cpu(header-version) == ADD_COW_VERSION) {
 +return 100;
 +} else {
 +return 0;
 +}
 +}
 +
 +static int add_cow_open(BlockDriverState *bs, int flags)
 +{
 +AddCowHeaderheader;
 +int64_t size;
 +charimage_filename[ADD_COW_FILE_LEN];
 +int image_flags;
 +BlockDriver *image_drv = NULL;
 +int ret;
 +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque);
 +
 +ret = bdrv_pread(bs-file, 0, header, sizeof(header));
 +if (ret != sizeof(header)) {
 +goto fail;
 +}
 +
 +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC ||
 +be32_to_cpu(header.version) != ADD_COW_VERSION) {
 +ret = -EINVAL;
 +goto fail;
 +}
 +
 +size = be64_to_cpu(header.size);
 +bs-total_sectors = size / BDRV_SECTOR_SIZE;
 +
 +QEMU_BUILD_BUG_ON(sizeof(state-image_file) != 
 sizeof(header.image_file));
 +pstrcpy(bs-backing_file, sizeof(bs-backing_file),
 +header.backing_file);
 +pstrcpy(state-image_file, sizeof(state-image_file),
 +header.image_file);
 +
 +state-bitmap_size = ((bs-total_sectors + 7)  3);
 +state-bitmap = g_malloc0(state-bitmap_size);
 +
 +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
 +state-bitmap_size);
 +if (ret != state-bitmap_size) {
 +goto fail;
 +}

Reading the entire bitmap in memory is not acceptable, it may be huge.
Better mmap it and use msync(MS_SYNC) when writing it back. This way the
host can free memory easily upon pressure.

 +   /* If 

Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Kevin Wolf
Am 06.12.2011 13:48, schrieb Marcelo Tosatti:
 On Tue, Nov 15, 2011 at 01:28:51PM +0800, Dong Xu Wang wrote:
 From: Dong Xu Wang wdon...@linux.vnet.ibm.com

 Provide a new file format: add-cow. The usage can be found in add-cow.txt of
 this patch.

 Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com
 ---
  Makefile.objs  |1 +
  block.c|2 +-
  block.h|1 +
  block/add-cow.c|  417 
 
  block_int.h|1 +
  docs/specs/add-cow.txt |   57 +++
  6 files changed, 478 insertions(+), 1 deletions(-)
  create mode 100644 block/add-cow.c
  create mode 100644 docs/specs/add-cow.txt

 diff --git a/Makefile.objs b/Makefile.objs
 index d7a6539..ad99243 100644
 --- a/Makefile.objs
 +++ b/Makefile.objs
 @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
  
  block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o 
 vpc.o vvfat.o
  block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o 
 qcow2-cache.o
 +block-nested-y += add-cow.o
  block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
  block-nested-y += qed-check.o
  block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
 diff --git a/block.c b/block.c
 index 86910b0..a2be27b 100644
 --- a/block.c
 +++ b/block.c
 @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename)
  #endif
  
  /* check if the path starts with protocol: */
 -static int path_has_protocol(const char *path)
 +int path_has_protocol(const char *path)
  {
  #ifdef _WIN32
  if (is_windows_drive(path) ||
 diff --git a/block.h b/block.h
 index 051a25d..836284f 100644
 --- a/block.h
 +++ b/block.h
 @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, 
 QEMUSnapshotInfo *sn);
  
  char *get_human_readable_size(char *buf, int buf_size, int64_t size);
  int path_is_absolute(const char *path);
 +int path_has_protocol(const char *path);
  void path_combine(char *dest, int dest_size,
const char *base_path,
const char *filename);
 diff --git a/block/add-cow.c b/block/add-cow.c
 new file mode 100644
 index 000..54d30a9
 --- /dev/null
 +++ b/block/add-cow.c
 @@ -0,0 +1,417 @@
 +#include qemu-common.h
 +#include block_int.h
 +#include module.h
 +
 +#define ADD_COW_MAGIC   (((uint64_t)'A'  56) | ((uint64_t)'D'  48) 
 | \
 +((uint64_t)'D'  40) | ((uint64_t)'_'  32) | 
 \
 +((uint64_t)'C'  24) | ((uint64_t)'O'  16) | 
 \
 +((uint64_t)'W'  8) | 0xFF)
 +#define ADD_COW_VERSION 1
 +#define ADD_COW_FILE_LEN1024
 +
 +typedef struct AddCowHeader {
 +uint64_tmagic;
 +uint32_tversion;
 +charbacking_file[ADD_COW_FILE_LEN];
 +charimage_file[ADD_COW_FILE_LEN];
 +uint64_tsize;
 +} QEMU_PACKED AddCowHeader;
 +
 +typedef struct BDRVAddCowState {
 +charimage_file[ADD_COW_FILE_LEN];
 +BlockDriverState*image_hd;
 +uint8_t *bitmap;
 +uint64_tbitmap_size;
 +CoMutex lock;
 +} BDRVAddCowState;
 +
 +static int add_cow_probe(const uint8_t *buf, int buf_size, const char 
 *filename)
 +{
 +const AddCowHeader *header = (const void *)buf;
 +
 +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC 
 +be32_to_cpu(header-version) == ADD_COW_VERSION) {
 +return 100;
 +} else {
 +return 0;
 +}
 +}
 +
 +static int add_cow_open(BlockDriverState *bs, int flags)
 +{
 +AddCowHeaderheader;
 +int64_t size;
 +charimage_filename[ADD_COW_FILE_LEN];
 +int image_flags;
 +BlockDriver *image_drv = NULL;
 +int ret;
 +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque);
 +
 +ret = bdrv_pread(bs-file, 0, header, sizeof(header));
 +if (ret != sizeof(header)) {
 +goto fail;
 +}
 +
 +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC ||
 +be32_to_cpu(header.version) != ADD_COW_VERSION) {
 +ret = -EINVAL;
 +goto fail;
 +}
 +
 +size = be64_to_cpu(header.size);
 +bs-total_sectors = size / BDRV_SECTOR_SIZE;
 +
 +QEMU_BUILD_BUG_ON(sizeof(state-image_file) != 
 sizeof(header.image_file));
 +pstrcpy(bs-backing_file, sizeof(bs-backing_file),
 +header.backing_file);
 +pstrcpy(state-image_file, sizeof(state-image_file),
 +header.image_file);
 +
 +state-bitmap_size = ((bs-total_sectors + 7)  3);
 +state-bitmap = g_malloc0(state-bitmap_size);
 +
 +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
 +state-bitmap_size);
 +if (ret != state-bitmap_size) {
 +goto fail;
 +}
 
 Reading the entire bitmap in memory is not acceptable, it may be huge.
 Better mmap it and use msync(MS_SYNC) when writing it back. This way the
 host 

Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Kevin Wolf
Am 15.11.2011 06:28, schrieb Dong Xu Wang:
 From: Dong Xu Wang wdon...@linux.vnet.ibm.com
 
 Provide a new file format: add-cow. The usage can be found in add-cow.txt of
 this patch.
 
 Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com
 ---
  Makefile.objs  |1 +
  block.c|2 +-
  block.h|1 +
  block/add-cow.c|  417 
 
  block_int.h|1 +
  docs/specs/add-cow.txt |   57 +++
  6 files changed, 478 insertions(+), 1 deletions(-)
  create mode 100644 block/add-cow.c
  create mode 100644 docs/specs/add-cow.txt
 
 diff --git a/Makefile.objs b/Makefile.objs
 index d7a6539..ad99243 100644
 --- a/Makefile.objs
 +++ b/Makefile.objs
 @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
  
  block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o 
 vpc.o vvfat.o
  block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o 
 qcow2-cache.o
 +block-nested-y += add-cow.o
  block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
  block-nested-y += qed-check.o
  block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
 diff --git a/block.c b/block.c
 index 86910b0..a2be27b 100644
 --- a/block.c
 +++ b/block.c
 @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename)
  #endif
  
  /* check if the path starts with protocol: */
 -static int path_has_protocol(const char *path)
 +int path_has_protocol(const char *path)
  {
  #ifdef _WIN32
  if (is_windows_drive(path) ||
 diff --git a/block.h b/block.h
 index 051a25d..836284f 100644
 --- a/block.h
 +++ b/block.h
 @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, 
 QEMUSnapshotInfo *sn);
  
  char *get_human_readable_size(char *buf, int buf_size, int64_t size);
  int path_is_absolute(const char *path);
 +int path_has_protocol(const char *path);
  void path_combine(char *dest, int dest_size,
const char *base_path,
const char *filename);
 diff --git a/block/add-cow.c b/block/add-cow.c
 new file mode 100644
 index 000..54d30a9
 --- /dev/null
 +++ b/block/add-cow.c
 @@ -0,0 +1,417 @@
 +#include qemu-common.h
 +#include block_int.h
 +#include module.h
 +
 +#define ADD_COW_MAGIC   (((uint64_t)'A'  56) | ((uint64_t)'D'  48) | 
 \
 +((uint64_t)'D'  40) | ((uint64_t)'_'  32) | \
 +((uint64_t)'C'  24) | ((uint64_t)'O'  16) | \
 +((uint64_t)'W'  8) | 0xFF)
 +#define ADD_COW_VERSION 1
 +#define ADD_COW_FILE_LEN1024
 +
 +typedef struct AddCowHeader {
 +uint64_tmagic;
 +uint32_tversion;
 +charbacking_file[ADD_COW_FILE_LEN];
 +charimage_file[ADD_COW_FILE_LEN];
 +uint64_tsize;
 +} QEMU_PACKED AddCowHeader;
 +
 +typedef struct BDRVAddCowState {
 +charimage_file[ADD_COW_FILE_LEN];
 +BlockDriverState*image_hd;
 +uint8_t *bitmap;
 +uint64_tbitmap_size;
 +CoMutex lock;
 +} BDRVAddCowState;
 +
 +static int add_cow_probe(const uint8_t *buf, int buf_size, const char 
 *filename)
 +{
 +const AddCowHeader *header = (const void *)buf;
 +
 +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC 
 +be32_to_cpu(header-version) == ADD_COW_VERSION) {
 +return 100;
 +} else {
 +return 0;
 +}
 +}
 +
 +static int add_cow_open(BlockDriverState *bs, int flags)
 +{
 +AddCowHeaderheader;
 +int64_t size;
 +charimage_filename[ADD_COW_FILE_LEN];
 +int image_flags;
 +BlockDriver *image_drv = NULL;
 +int ret;
 +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque);
 +
 +ret = bdrv_pread(bs-file, 0, header, sizeof(header));
 +if (ret != sizeof(header)) {
 +goto fail;
 +}
 +
 +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC ||
 +be32_to_cpu(header.version) != ADD_COW_VERSION) {
 +ret = -EINVAL;
 +goto fail;
 +}

Please have a look at qcow2 for better handling of newer version
numbers. We should try to give a good error message for this case.

 +
 +size = be64_to_cpu(header.size);
 +bs-total_sectors = size / BDRV_SECTOR_SIZE;
 +
 +QEMU_BUILD_BUG_ON(sizeof(state-image_file) != 
 sizeof(header.image_file));
 +pstrcpy(bs-backing_file, sizeof(bs-backing_file),
 +header.backing_file);
 +pstrcpy(state-image_file, sizeof(state-image_file),
 +header.image_file);

You need the same QEMU_BUILD_BUG_ON for the backing file, or you can't
assume that header.image_file is large enough that it doesn't matter
that it isn't necessarily correctly terminated.

 +
 +state-bitmap_size = ((bs-total_sectors + 7)  3);
 +state-bitmap = g_malloc0(state-bitmap_size);

qemu_blockalign is better if you're using it as a buffer for 

Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Marcelo Tosatti
On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote:
  +
  +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
  +state-bitmap_size);
  +if (ret != state-bitmap_size) {
  +goto fail;
  +}
  
  Reading the entire bitmap in memory is not acceptable, it may be huge.
  Better mmap it and use msync(MS_SYNC) when writing it back. This way the
  host can free memory easily upon pressure.
 
 You can't use mmap in block drivers. It would only work with raw-posix
 backends, if at all.
 
 Kevin

This is just the bitmap, a plain file. Why would you want to use
anything other than a plain file to use as storage for the bitmap?




Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Marcelo Tosatti
On Tue, Dec 06, 2011 at 12:53:16PM -0200, Marcelo Tosatti wrote:
 On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote:
   +
   +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
   +state-bitmap_size);
   +if (ret != state-bitmap_size) {
   +goto fail;
   +}
   
   Reading the entire bitmap in memory is not acceptable, it may be huge.
   Better mmap it and use msync(MS_SYNC) when writing it back. This way the
   host can free memory easily upon pressure.
  
  You can't use mmap in block drivers. It would only work with raw-posix
  backends, if at all.
  
  Kevin
 
 This is just the bitmap, a plain file. Why would you want to use
 anything other than a plain file to use as storage for the bitmap?

Well, mmap'ing would make life much simpler, but it has limitations such 
as portability.

Then what is necessary is a cache similar to qcow2's metadata cache.




Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Kevin Wolf
Am 06.12.2011 15:53, schrieb Marcelo Tosatti:
 On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote:
 +
 +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
 +state-bitmap_size);
 +if (ret != state-bitmap_size) {
 +goto fail;
 +}

 Reading the entire bitmap in memory is not acceptable, it may be huge.
 Better mmap it and use msync(MS_SYNC) when writing it back. This way the
 host can free memory easily upon pressure.

 You can't use mmap in block drivers. It would only work with raw-posix
 backends, if at all.
 
 This is just the bitmap, a plain file. Why would you want to use
 anything other than a plain file to use as storage for the bitmap?

The obvious case is raw-win32. There are probably not so obvious, but
still valid use cases that involve things like NBD, iSCSI, blkdebug or
whatever.

Kevin



Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Kevin Wolf
Am 06.12.2011 16:06, schrieb Marcelo Tosatti:
 On Tue, Dec 06, 2011 at 12:53:16PM -0200, Marcelo Tosatti wrote:
 On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote:
 +
 +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
 +state-bitmap_size);
 +if (ret != state-bitmap_size) {
 +goto fail;
 +}

 Reading the entire bitmap in memory is not acceptable, it may be huge.
 Better mmap it and use msync(MS_SYNC) when writing it back. This way the
 host can free memory easily upon pressure.

 You can't use mmap in block drivers. It would only work with raw-posix
 backends, if at all.

 Kevin

 This is just the bitmap, a plain file. Why would you want to use
 anything other than a plain file to use as storage for the bitmap?
 
 Well, mmap'ing would make life much simpler, but it has limitations such 
 as portability.
 
 Then what is necessary is a cache similar to qcow2's metadata cache.

Right, we can probably generalise the qcow2 code and make it available
for other drivers as well.

Kevin



Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Marcelo Tosatti
On Tue, Dec 06, 2011 at 04:20:55PM +0100, Kevin Wolf wrote:
 Am 06.12.2011 16:06, schrieb Marcelo Tosatti:
  On Tue, Dec 06, 2011 at 12:53:16PM -0200, Marcelo Tosatti wrote:
  On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote:
  +
  +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
  +state-bitmap_size);
  +if (ret != state-bitmap_size) {
  +goto fail;
  +}
 
  Reading the entire bitmap in memory is not acceptable, it may be huge.
  Better mmap it and use msync(MS_SYNC) when writing it back. This way the
  host can free memory easily upon pressure.
 
  You can't use mmap in block drivers. It would only work with raw-posix
  backends, if at all.
 
  Kevin
 
  This is just the bitmap, a plain file. Why would you want to use
  anything other than a plain file to use as storage for the bitmap?
  
  Well, mmap'ing would make life much simpler, but it has limitations such 
  as portability.
  
  Then what is necessary is a cache similar to qcow2's metadata cache.
 
 Right, we can probably generalise the qcow2 code and make it available
 for other drivers as well.

Hum, generalising sounds overly complicated (and there is a time
constraint to this). IMHO a cache internal to add-cow.c just to avoid
reading the entire bitmap would do the trick.




Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Kevin Wolf
Am 06.12.2011 17:35, schrieb Marcelo Tosatti:
 On Tue, Dec 06, 2011 at 04:20:55PM +0100, Kevin Wolf wrote:
 Am 06.12.2011 16:06, schrieb Marcelo Tosatti:
 On Tue, Dec 06, 2011 at 12:53:16PM -0200, Marcelo Tosatti wrote:
 On Tue, Dec 06, 2011 at 01:59:48PM +0100, Kevin Wolf wrote:
 +
 +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
 +state-bitmap_size);
 +if (ret != state-bitmap_size) {
 +goto fail;
 +}

 Reading the entire bitmap in memory is not acceptable, it may be huge.
 Better mmap it and use msync(MS_SYNC) when writing it back. This way the
 host can free memory easily upon pressure.

 You can't use mmap in block drivers. It would only work with raw-posix
 backends, if at all.

 Kevin

 This is just the bitmap, a plain file. Why would you want to use
 anything other than a plain file to use as storage for the bitmap?

 Well, mmap'ing would make life much simpler, but it has limitations such 
 as portability.

 Then what is necessary is a cache similar to qcow2's metadata cache.

 Right, we can probably generalise the qcow2 code and make it available
 for other drivers as well.
 
 Hum, generalising sounds overly complicated (and there is a time
 constraint to this). IMHO a cache internal to add-cow.c just to avoid
 reading the entire bitmap would do the trick.

The cache is mostly self-contained. But maybe we should get the locking
right (instead of always locking the whole BlockDriverState) before
using it in more drivers. I think this might need some change to it.

Kevin



Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-06 Thread Marcelo Tosatti
On Tue, Dec 06, 2011 at 02:35:03PM -0200, Marcelo Tosatti wrote:
  Right, we can probably generalise the qcow2 code and make it available
  for other drivers as well.
 
 Hum, generalising sounds overly complicated (and there is a time
 constraint to this). IMHO a cache internal to add-cow.c just to avoid
 reading the entire bitmap would do the trick. 

(and writes must go through the cache too, of course).




Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-12-04 Thread Dong Xu Wang
Ping...

2011/11/28 Dong Xu Wang wdon...@linux.vnet.ibm.com

 Any comment?
 Thanks.


 2011/11/15 Dong Xu Wang wdon...@linux.vnet.ibm.com

 From: Dong Xu Wang wdon...@linux.vnet.ibm.com

 Provide a new file format: add-cow. The usage can be found in add-cow.txt
 of
 this patch.

 Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com
 ---
  Makefile.objs  |1 +
  block.c|2 +-
  block.h|1 +
  block/add-cow.c|  417
 
  block_int.h|1 +
  docs/specs/add-cow.txt |   57 +++
  6 files changed, 478 insertions(+), 1 deletions(-)
  create mode 100644 block/add-cow.c
  create mode 100644 docs/specs/add-cow.txt

 diff --git a/Makefile.objs b/Makefile.objs
 index d7a6539..ad99243 100644
 --- a/Makefile.objs
 +++ b/Makefile.objs
 @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o

  block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o
 vpc.o vvfat.o
  block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o
 qcow2-snapshot.o qcow2-cache.o
 +block-nested-y += add-cow.o
  block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o
 qed-cluster.o
  block-nested-y += qed-check.o
  block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
 diff --git a/block.c b/block.c
 index 86910b0..a2be27b 100644
 --- a/block.c
 +++ b/block.c
 @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename)
  #endif

  /* check if the path starts with protocol: */
 -static int path_has_protocol(const char *path)
 +int path_has_protocol(const char *path)
  {
  #ifdef _WIN32
 if (is_windows_drive(path) ||
 diff --git a/block.h b/block.h
 index 051a25d..836284f 100644
 --- a/block.h
 +++ b/block.h
 @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size,
 QEMUSnapshotInfo *sn);

  char *get_human_readable_size(char *buf, int buf_size, int64_t size);
  int path_is_absolute(const char *path);
 +int path_has_protocol(const char *path);
  void path_combine(char *dest, int dest_size,
   const char *base_path,
   const char *filename);
 diff --git a/block/add-cow.c b/block/add-cow.c
 new file mode 100644
 index 000..54d30a9
 --- /dev/null
 +++ b/block/add-cow.c
 @@ -0,0 +1,417 @@
 +#include qemu-common.h
 +#include block_int.h
 +#include module.h
 +
 +#define ADD_COW_MAGIC   (((uint64_t)'A'  56) | ((uint64_t)'D' 
 48) | \
 +((uint64_t)'D'  40) | ((uint64_t)'_' 
 32) | \
 +((uint64_t)'C'  24) | ((uint64_t)'O' 
 16) | \
 +((uint64_t)'W'  8) | 0xFF)
 +#define ADD_COW_VERSION 1
 +#define ADD_COW_FILE_LEN1024
 +
 +typedef struct AddCowHeader {
 +uint64_tmagic;
 +uint32_tversion;
 +charbacking_file[ADD_COW_FILE_LEN];
 +charimage_file[ADD_COW_FILE_LEN];
 +uint64_tsize;
 +} QEMU_PACKED AddCowHeader;
 +
 +typedef struct BDRVAddCowState {
 +charimage_file[ADD_COW_FILE_LEN];
 +BlockDriverState*image_hd;
 +uint8_t *bitmap;
 +uint64_tbitmap_size;
 +CoMutex lock;
 +} BDRVAddCowState;
 +
 +static int add_cow_probe(const uint8_t *buf, int buf_size, const char
 *filename)
 +{
 +const AddCowHeader *header = (const void *)buf;
 +
 +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC 
 +be32_to_cpu(header-version) == ADD_COW_VERSION) {
 +return 100;
 +} else {
 +return 0;
 +}
 +}
 +
 +static int add_cow_open(BlockDriverState *bs, int flags)
 +{
 +AddCowHeaderheader;
 +int64_t size;
 +charimage_filename[ADD_COW_FILE_LEN];
 +int image_flags;
 +BlockDriver *image_drv = NULL;
 +int ret;
 +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque);
 +
 +ret = bdrv_pread(bs-file, 0, header, sizeof(header));
 +if (ret != sizeof(header)) {
 +goto fail;
 +}
 +
 +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC ||
 +be32_to_cpu(header.version) != ADD_COW_VERSION) {
 +ret = -EINVAL;
 +goto fail;
 +}
 +
 +size = be64_to_cpu(header.size);
 +bs-total_sectors = size / BDRV_SECTOR_SIZE;
 +
 +QEMU_BUILD_BUG_ON(sizeof(state-image_file) !=
 sizeof(header.image_file));
 +pstrcpy(bs-backing_file, sizeof(bs-backing_file),
 +header.backing_file);
 +pstrcpy(state-image_file, sizeof(state-image_file),
 +header.image_file);
 +
 +state-bitmap_size = ((bs-total_sectors + 7)  3);
 +state-bitmap = g_malloc0(state-bitmap_size);
 +
 +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
 +state-bitmap_size);
 +if (ret != state-bitmap_size) {
 +goto fail;
 +}
 +   /* If there is a image_file, must be together with backing_file */
 +if (state-image_file[0] != '\0') {
 +state-image_hd = 

Re: [Qemu-devel] [PATCH v5] block:add-cow file format

2011-11-27 Thread Dong Xu Wang
Any comment?
Thanks.

2011/11/15 Dong Xu Wang wdon...@linux.vnet.ibm.com

 From: Dong Xu Wang wdon...@linux.vnet.ibm.com

 Provide a new file format: add-cow. The usage can be found in add-cow.txt
 of
 this patch.

 Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com
 ---
  Makefile.objs  |1 +
  block.c|2 +-
  block.h|1 +
  block/add-cow.c|  417
 
  block_int.h|1 +
  docs/specs/add-cow.txt |   57 +++
  6 files changed, 478 insertions(+), 1 deletions(-)
  create mode 100644 block/add-cow.c
  create mode 100644 docs/specs/add-cow.txt

 diff --git a/Makefile.objs b/Makefile.objs
 index d7a6539..ad99243 100644
 --- a/Makefile.objs
 +++ b/Makefile.objs
 @@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o

  block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o
 vpc.o vvfat.o
  block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o
 qcow2-snapshot.o qcow2-cache.o
 +block-nested-y += add-cow.o
  block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o
 qed-cluster.o
  block-nested-y += qed-check.o
  block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
 diff --git a/block.c b/block.c
 index 86910b0..a2be27b 100644
 --- a/block.c
 +++ b/block.c
 @@ -106,7 +106,7 @@ int is_windows_drive(const char *filename)
  #endif

  /* check if the path starts with protocol: */
 -static int path_has_protocol(const char *path)
 +int path_has_protocol(const char *path)
  {
  #ifdef _WIN32
 if (is_windows_drive(path) ||
 diff --git a/block.h b/block.h
 index 051a25d..836284f 100644
 --- a/block.h
 +++ b/block.h
 @@ -276,6 +276,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size,
 QEMUSnapshotInfo *sn);

  char *get_human_readable_size(char *buf, int buf_size, int64_t size);
  int path_is_absolute(const char *path);
 +int path_has_protocol(const char *path);
  void path_combine(char *dest, int dest_size,
   const char *base_path,
   const char *filename);
 diff --git a/block/add-cow.c b/block/add-cow.c
 new file mode 100644
 index 000..54d30a9
 --- /dev/null
 +++ b/block/add-cow.c
 @@ -0,0 +1,417 @@
 +#include qemu-common.h
 +#include block_int.h
 +#include module.h
 +
 +#define ADD_COW_MAGIC   (((uint64_t)'A'  56) | ((uint64_t)'D' 
 48) | \
 +((uint64_t)'D'  40) | ((uint64_t)'_'  32)
 | \
 +((uint64_t)'C'  24) | ((uint64_t)'O'  16)
 | \
 +((uint64_t)'W'  8) | 0xFF)
 +#define ADD_COW_VERSION 1
 +#define ADD_COW_FILE_LEN1024
 +
 +typedef struct AddCowHeader {
 +uint64_tmagic;
 +uint32_tversion;
 +charbacking_file[ADD_COW_FILE_LEN];
 +charimage_file[ADD_COW_FILE_LEN];
 +uint64_tsize;
 +} QEMU_PACKED AddCowHeader;
 +
 +typedef struct BDRVAddCowState {
 +charimage_file[ADD_COW_FILE_LEN];
 +BlockDriverState*image_hd;
 +uint8_t *bitmap;
 +uint64_tbitmap_size;
 +CoMutex lock;
 +} BDRVAddCowState;
 +
 +static int add_cow_probe(const uint8_t *buf, int buf_size, const char
 *filename)
 +{
 +const AddCowHeader *header = (const void *)buf;
 +
 +if (be64_to_cpu(header-magic) == ADD_COW_MAGIC 
 +be32_to_cpu(header-version) == ADD_COW_VERSION) {
 +return 100;
 +} else {
 +return 0;
 +}
 +}
 +
 +static int add_cow_open(BlockDriverState *bs, int flags)
 +{
 +AddCowHeaderheader;
 +int64_t size;
 +charimage_filename[ADD_COW_FILE_LEN];
 +int image_flags;
 +BlockDriver *image_drv = NULL;
 +int ret;
 +BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque);
 +
 +ret = bdrv_pread(bs-file, 0, header, sizeof(header));
 +if (ret != sizeof(header)) {
 +goto fail;
 +}
 +
 +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC ||
 +be32_to_cpu(header.version) != ADD_COW_VERSION) {
 +ret = -EINVAL;
 +goto fail;
 +}
 +
 +size = be64_to_cpu(header.size);
 +bs-total_sectors = size / BDRV_SECTOR_SIZE;
 +
 +QEMU_BUILD_BUG_ON(sizeof(state-image_file) !=
 sizeof(header.image_file));
 +pstrcpy(bs-backing_file, sizeof(bs-backing_file),
 +header.backing_file);
 +pstrcpy(state-image_file, sizeof(state-image_file),
 +header.image_file);
 +
 +state-bitmap_size = ((bs-total_sectors + 7)  3);
 +state-bitmap = g_malloc0(state-bitmap_size);
 +
 +ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
 +state-bitmap_size);
 +if (ret != state-bitmap_size) {
 +goto fail;
 +}
 +   /* If there is a image_file, must be together with backing_file */
 +if (state-image_file[0] != '\0') {
 +state-image_hd = bdrv_new();
 +
 +if (path_has_protocol(state-image_file))