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

2012-01-08 Thread Dong Xu Wang
Okay, I will consider your suggestion in version 7.
Thank you Marcelo and Stefan, :).


On Fri, Jan 6, 2012 at 16:22, Stefan Hajnoczi
wrote:

> On Thu, Jan 05, 2012 at 01:46:08PM -0200, Marcelo Tosatti wrote:
> > On Thu, Dec 29, 2011 at 05:36:59PM +0800, Dong Xu Wang wrote:
> > > From: Dong Xu Wang 
> > >
> > > Introduce a new file format: add-cow. The usage can be found in
> add-cow.txt of
> > > this patch.
> > >
> > > CC: Kevin Wolf 
> > > CC: Stefan Hajnoczi 
> > > Signed-off-by: Dong Xu Wang 
> > > ---
> > > After applying this patch, qemu might can not compile, need apply this
> patch first:
> > > http://lists.gnu.org/archive/html/qemu-devel/2011-12/msg02527.html
> > >
> > >  Makefile.objs  |1 +
> > >  block.c|2 +-
> > >  block.h|1 +
> > >  block/add-cow.c|  429
> 
> > >  block_int.h|1 +
> > >  docs/specs/add-cow.txt |   72 
> > >  6 files changed, 505 insertions(+), 1 deletions(-)
> > >  create mode 100644 block/add-cow.c
> > >  create mode 100644 docs/specs/add-cow.txt
> > >
> >
> >
> > > +s->bitmap_size = ((bs->total_sectors + 7) >> 3);
> > > +s->bitmap = qemu_blockalign(bs, s->bitmap_size);
> > > +
> > > +ret = bdrv_pread(bs->file, sizeof(header), s->bitmap,
> > > +s->bitmap_size);
> > > +if (ret != s->bitmap_size) {
> > > +goto fail;
> > > +}
> >
> > As noted previously, it is not acceptable to read the entire bitmap in
> > memory since it might be very large. A cache, which limits the in-memory
> > size of the bitmap, must be created. In the qcow2-cache.c file you can
> > find an example (thats for qcow2 metadata cache). You can divide the
> > bitmap in chunks of say, 4k, and have:
> >
> > int is_bit_set(int64_t bitnum, BlockDriverState *bs)
> > {
> > int64_t bitmap_entry = bitnum >> bits_per_entry;
> >
> > if (!is_in_bitmap_cache(bs, bitmap_entry))
> > read_from_disk(bs, bitmap_entry);
> >
> > return lookup_bitmap_cache(bs, bitnum);
> > }
> >
> > And then limit the cache to a few megabytes.
> >
> > Also when setting a bit you must update cache and write
> > to disk.
>
> I suspect it's also better to increase the bitmap granularity.  The
> bitmap should track allocation at a larger "cluster" size like 64 KB.
> That way we reduce the number of I/O operations required to update
> metadata - it reduces the amount of metadata by a factor of 65536 / 512
> = 128.
>
> If you imagine a random write workload with 4 KB block size there is an
> advantage to a 64 KB cluster size since later I/Os may require no bitmap
> updates where we already allocated a cluster in an earlier operation.
>
> The downside of a larger bitmap granularity is that writes are increased
> to 64 KB, but if you run a benchmark I guess there is a threshold around
> 32 or 64 KB where the reduction in I/O operations makes up for the
> larger I/O size.  It depends on your disks.
>
> Stefan
>
>
>


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

2012-01-06 Thread Stefan Hajnoczi
On Thu, Jan 05, 2012 at 01:46:08PM -0200, Marcelo Tosatti wrote:
> On Thu, Dec 29, 2011 at 05:36:59PM +0800, Dong Xu Wang wrote:
> > From: Dong Xu Wang 
> > 
> > Introduce a new file format: add-cow. The usage can be found in add-cow.txt 
> > of
> > this patch.
> > 
> > CC: Kevin Wolf 
> > CC: Stefan Hajnoczi 
> > Signed-off-by: Dong Xu Wang 
> > ---
> > After applying this patch, qemu might can not compile, need apply this 
> > patch first:
> > http://lists.gnu.org/archive/html/qemu-devel/2011-12/msg02527.html
> > 
> >  Makefile.objs  |1 +
> >  block.c|2 +-
> >  block.h|1 +
> >  block/add-cow.c|  429 
> > 
> >  block_int.h|1 +
> >  docs/specs/add-cow.txt |   72 
> >  6 files changed, 505 insertions(+), 1 deletions(-)
> >  create mode 100644 block/add-cow.c
> >  create mode 100644 docs/specs/add-cow.txt
> > 
> 
> 
> > +s->bitmap_size = ((bs->total_sectors + 7) >> 3);
> > +s->bitmap = qemu_blockalign(bs, s->bitmap_size);
> > +
> > +ret = bdrv_pread(bs->file, sizeof(header), s->bitmap,
> > +s->bitmap_size);
> > +if (ret != s->bitmap_size) {
> > +goto fail;
> > +}
> 
> As noted previously, it is not acceptable to read the entire bitmap in
> memory since it might be very large. A cache, which limits the in-memory
> size of the bitmap, must be created. In the qcow2-cache.c file you can 
> find an example (thats for qcow2 metadata cache). You can divide the
> bitmap in chunks of say, 4k, and have:
> 
> int is_bit_set(int64_t bitnum, BlockDriverState *bs)
> {
> int64_t bitmap_entry = bitnum >> bits_per_entry;
> 
> if (!is_in_bitmap_cache(bs, bitmap_entry))
> read_from_disk(bs, bitmap_entry);
> 
> return lookup_bitmap_cache(bs, bitnum);
> }
> 
> And then limit the cache to a few megabytes.
> 
> Also when setting a bit you must update cache and write
> to disk.

I suspect it's also better to increase the bitmap granularity.  The
bitmap should track allocation at a larger "cluster" size like 64 KB.
That way we reduce the number of I/O operations required to update
metadata - it reduces the amount of metadata by a factor of 65536 / 512
= 128.

If you imagine a random write workload with 4 KB block size there is an
advantage to a 64 KB cluster size since later I/Os may require no bitmap
updates where we already allocated a cluster in an earlier operation.

The downside of a larger bitmap granularity is that writes are increased
to 64 KB, but if you run a benchmark I guess there is a threshold around
32 or 64 KB where the reduction in I/O operations makes up for the
larger I/O size.  It depends on your disks.

Stefan




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

2012-01-05 Thread Marcelo Tosatti
On Thu, Dec 29, 2011 at 05:36:59PM +0800, Dong Xu Wang wrote:
> From: Dong Xu Wang 
> 
> Introduce a new file format: add-cow. The usage can be found in add-cow.txt of
> this patch.
> 
> CC: Kevin Wolf 
> CC: Stefan Hajnoczi 
> Signed-off-by: Dong Xu Wang 
> ---
> After applying this patch, qemu might can not compile, need apply this patch 
> first:
> http://lists.gnu.org/archive/html/qemu-devel/2011-12/msg02527.html
> 
>  Makefile.objs  |1 +
>  block.c|2 +-
>  block.h|1 +
>  block/add-cow.c|  429 
> 
>  block_int.h|1 +
>  docs/specs/add-cow.txt |   72 
>  6 files changed, 505 insertions(+), 1 deletions(-)
>  create mode 100644 block/add-cow.c
>  create mode 100644 docs/specs/add-cow.txt
> 


> +s->bitmap_size = ((bs->total_sectors + 7) >> 3);
> +s->bitmap = qemu_blockalign(bs, s->bitmap_size);
> +
> +ret = bdrv_pread(bs->file, sizeof(header), s->bitmap,
> +s->bitmap_size);
> +if (ret != s->bitmap_size) {
> +goto fail;
> +}

As noted previously, it is not acceptable to read the entire bitmap in
memory since it might be very large. A cache, which limits the in-memory
size of the bitmap, must be created. In the qcow2-cache.c file you can 
find an example (thats for qcow2 metadata cache). You can divide the
bitmap in chunks of say, 4k, and have:

int is_bit_set(int64_t bitnum, BlockDriverState *bs)
{
int64_t bitmap_entry = bitnum >> bits_per_entry;

if (!is_in_bitmap_cache(bs, bitmap_entry))
read_from_disk(bs, bitmap_entry);

return lookup_bitmap_cache(bs, bitnum);
}

And then limit the cache to a few megabytes.

Also when setting a bit you must update cache and write
to disk.

> +
> +if (s->image_file[0] == '\0') {
> +ret = -ENOENT;
> +goto fail;
> +}
> +
> +ret = bdrv_file_open(&backing_bs, bs->backing_file, 0);
> +if (ret < 0) {
> +return ret;
> +}
> +bdrv_delete(backing_bs);
> +
> +s->image_hd = bdrv_new("");
> +
> +if (path_has_protocol(s->image_file)) {
> +pstrcpy(image_filename, sizeof(image_filename),
> +s->image_file);
> +} else {
> +path_combine(image_filename, sizeof(image_filename),
> + bs->filename, s->image_file);
> +}
> +
> +image_drv = bdrv_find_format("raw");
> +ret = bdrv_open(s->image_hd, image_filename, flags, image_drv);
> +if (ret < 0) {
> +bdrv_delete(s->image_hd);
> +s->image_hd = NULL;
> +goto fail;
> +}

Please make sure it is possible to create a snapshot with the
snapshot_blkdev command, of a raw image. It is necessary for live block
copy, as described here:

http://patchwork.ozlabs.org/patch/134257/

Also please update that document, later, with raw examples.

Thanks




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

2012-01-01 Thread Stefan Hajnoczi
On Sat, Dec 31, 2011 at 9:17 AM, Dong Xu Wang
 wrote:
> On Fri, Dec 30, 2011 at 22:09, Stefan Hajnoczi  wrote:
>> On Thu, Dec 29, 2011 at 05:36:59PM +0800, Dong Xu Wang wrote:
>> > +    ret = bdrv_file_open(&backing_bs, bs->backing_file, 0);
>> > +    if (ret < 0) {
>> > +        return ret;
>> > +    }
>> > +    bdrv_delete(backing_bs);
>>
>> What does this do?  (It leaks s->bitmap when it fails.)
>
>
> I wanna make sure backing_file exists while opening.

block.c:bdrv_open() opens the backing file after .bdrv_open() has
returned.  It fails if the backing file does not exist.  There's no
need to duplicate this.

>> > +    s->image_hd = bdrv_new("");
>> > +
>> > +    if (path_has_protocol(s->image_file)) {
>> > +        pstrcpy(image_filename, sizeof(image_filename),
>> > +                s->image_file);
>> > +    } else {
>> > +        path_combine(image_filename, sizeof(image_filename),
>> > +                     bs->filename, s->image_file);
>> > +    }
>> > +
>> > +    image_drv = bdrv_find_format("raw");
>> > +    ret = bdrv_open(s->image_hd, image_filename, flags, image_drv);
>> > +    if (ret < 0) {
>> > +        bdrv_delete(s->image_hd);
>> > +        s->image_hd = NULL;
>> > +        goto fail;
>> > +    }
>>
>> TODO

If you were wondering why I put "TODO" here it's because I had some
thoughts when reviewing but didn't fully investigate it yet.  When I
send the rest of my feedback I'll include my comment here.  (I should
have removed this before replying :))

>> > +         1036 - 2059:   image_file
>> > +                        image_file is a raw file, While using
>> > image_file, must
>> > +                        together with image_file. All unused bytes are
>> > padded
>>
>> "While using image_file, must together with image_file"
>>
>> What does this mean?
>
>
> I mean while using add-cow, must together with image_file and backing_file.
> Both of them can not be missing.
> Errors with sentences like that, I will correct them in v7.

That sounds like qemu-img create behavior which should not be part of
the file format specification.

The only impact on the file format speficiation is that backing_file
can be an empty string but image_file must always be a valid filename.



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

2011-12-31 Thread Dong Xu Wang
On Fri, Dec 30, 2011 at 22:09, Stefan Hajnoczi  wrote:

> On Thu, Dec 29, 2011 at 05:36:59PM +0800, Dong Xu Wang wrote:
>
> Some comments on everything but the I/O path, which I haven't reviewed
> yet:
>
> > diff --git a/block/add-cow.c b/block/add-cow.c
> > new file mode 100644
> > index 000..95af5b7
> > --- /dev/null
> > +++ b/block/add-cow.c
> > @@ -0,0 +1,429 @@
>
> Missing GPL or LGPL license header.
>
> > +#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;
> > +charreserved[492];
> > +} QEMU_PACKED AddCowHeader;
> > +
> > +typedef struct BDRVAddCowState {
> > +charimage_file[ADD_COW_FILE_LEN];
>
> Why is this field needed?
>
> Yes, not needed.

>
> > +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];
> > +BlockDriver *image_drv = NULL;
> > +int ret;
> > +BDRVAddCowState *s = bs->opaque;
> > +BlockDriverState*backing_bs = NULL;
> > +
> > +ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
> > +if (ret != sizeof(header)) {
> > +goto fail;
> > +}
> > +
> > +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC) {
> > +ret = -EINVAL;
> > +goto fail;
> > +}
> > +if (be32_to_cpu(header.version) != ADD_COW_VERSION) {
> > +char version[64];
> > +snprintf(version, sizeof(version), "ADD-COW version %d",
> header.version);
> > +qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
> > +bs->device_name, "add-cow", version);
> > +ret = -ENOTSUP;
> > +goto fail;
> > +}
> > +
> > +size = be64_to_cpu(header.size);
> > +bs->total_sectors = size / BDRV_SECTOR_SIZE;
> > +
> > +QEMU_BUILD_BUG_ON(sizeof(bs->backing_file) !=
> sizeof(header.backing_file));
> > +QEMU_BUILD_BUG_ON(sizeof(s->image_file) !=
> sizeof(header.image_file));
> > +pstrcpy(bs->backing_file, sizeof(bs->backing_file),
> > +header.backing_file);
> > +pstrcpy(s->image_file, sizeof(s->image_file),
> > +header.image_file);
>
> This assumes that header.backing_file and header.image_file is
> NUL-terminated.  If the file happened to have the magic number and
> version but does not include '\0' bytes in the header.backing_file then
> we may crash here when trying to read beyond the end of the header
> struct.
>
> Image format code should be robust.  Please use strncpy(3) carefully
> instead of pstrcpy().
>
> Also please update the file format specification to either make these
> fields NUL-terminated or NUL-terminated unless the length is 1024
> characters (in which case there is no NUL but the string still ends).
>
Okay.

>
> > +
> > +s->bitmap_size = ((bs->total_sectors + 7) >> 3);
> > +s->bitmap = qemu_blockalign(bs, s->bitmap_size);
> > +
> > +ret = bdrv_pread(bs->file, sizeof(header), s->bitmap,
> > +s->bitmap_size);
> > +if (ret != s->bitmap_size) {
> > +goto fail;
> > +}
> > +
> > +if (s->image_file[0] == '\0') {
> > +ret = -ENOENT;
> > +goto fail;
> > +}
> > +
> > +ret = bdrv_file_open(&backing_bs, bs->backing_file, 0);
> > +if (ret < 0) {
> > +return ret;
> > +}
> > +bdrv_delete(backing_bs);
>
> What does this do?  (It leaks s->bitmap when it fails.)
>

I wanna make sure backing_file exists while opening.

>
> > +
> > +s->image_hd = bdrv_new("");
> > +
> > +if (path_has_protocol(s->image_file)) {
> > +pstrcpy(image_filename, sizeof(image_filename),
> > +s->image_file);
> > +} else {
> > +path_combine(image_filename, sizeof(image_filename)

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

2011-12-30 Thread Stefan Hajnoczi
On Thu, Dec 29, 2011 at 05:36:59PM +0800, Dong Xu Wang wrote:

Some comments on everything but the I/O path, which I haven't reviewed
yet:

> diff --git a/block/add-cow.c b/block/add-cow.c
> new file mode 100644
> index 000..95af5b7
> --- /dev/null
> +++ b/block/add-cow.c
> @@ -0,0 +1,429 @@

Missing GPL or LGPL license header.

> +#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;
> +charreserved[492];
> +} QEMU_PACKED AddCowHeader;
> +
> +typedef struct BDRVAddCowState {
> +charimage_file[ADD_COW_FILE_LEN];

Why is this field needed?

> +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];
> +BlockDriver *image_drv = NULL;
> +int ret;
> +BDRVAddCowState *s = bs->opaque;
> +BlockDriverState*backing_bs = NULL;
> +
> +ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
> +if (ret != sizeof(header)) {
> +goto fail;
> +}
> +
> +if (be64_to_cpu(header.magic) != ADD_COW_MAGIC) {
> +ret = -EINVAL;
> +goto fail;
> +}
> +if (be32_to_cpu(header.version) != ADD_COW_VERSION) {
> +char version[64];
> +snprintf(version, sizeof(version), "ADD-COW version %d", 
> header.version);
> +qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
> +bs->device_name, "add-cow", version);
> +ret = -ENOTSUP;
> +goto fail;
> +}
> +
> +size = be64_to_cpu(header.size);
> +bs->total_sectors = size / BDRV_SECTOR_SIZE;
> +
> +QEMU_BUILD_BUG_ON(sizeof(bs->backing_file) != 
> sizeof(header.backing_file));
> +QEMU_BUILD_BUG_ON(sizeof(s->image_file) != sizeof(header.image_file));
> +pstrcpy(bs->backing_file, sizeof(bs->backing_file),
> +header.backing_file);
> +pstrcpy(s->image_file, sizeof(s->image_file),
> +header.image_file);

This assumes that header.backing_file and header.image_file is
NUL-terminated.  If the file happened to have the magic number and
version but does not include '\0' bytes in the header.backing_file then
we may crash here when trying to read beyond the end of the header
struct.

Image format code should be robust.  Please use strncpy(3) carefully
instead of pstrcpy().

Also please update the file format specification to either make these
fields NUL-terminated or NUL-terminated unless the length is 1024
characters (in which case there is no NUL but the string still ends).

> +
> +s->bitmap_size = ((bs->total_sectors + 7) >> 3);
> +s->bitmap = qemu_blockalign(bs, s->bitmap_size);
> +
> +ret = bdrv_pread(bs->file, sizeof(header), s->bitmap,
> +s->bitmap_size);
> +if (ret != s->bitmap_size) {
> +goto fail;
> +}
> +
> +if (s->image_file[0] == '\0') {
> +ret = -ENOENT;
> +goto fail;
> +}
> +
> +ret = bdrv_file_open(&backing_bs, bs->backing_file, 0);
> +if (ret < 0) {
> +return ret;
> +}
> +bdrv_delete(backing_bs);

What does this do?  (It leaks s->bitmap when it fails.)

> +
> +s->image_hd = bdrv_new("");
> +
> +if (path_has_protocol(s->image_file)) {
> +pstrcpy(image_filename, sizeof(image_filename),
> +s->image_file);
> +} else {
> +path_combine(image_filename, sizeof(image_filename),
> + bs->filename, s->image_file);
> +}
> +
> +image_drv = bdrv_find_format("raw");
> +ret = bdrv_open(s->image_hd, image_filename, flags, image_drv);
> +if (ret < 0) {
> +bdrv_delete(s->image_hd);
> +s->image_hd = NULL;
> +goto fail;
> +}

TODO

> +
> +qemu_co_mutex_init(&s->lock);
> +return 0;
> + fail:
> +g_free(s->bitmap);
> +   

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

2011-12-29 Thread Dong Xu Wang
From: Dong Xu Wang 

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

CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
---
After applying this patch, qemu might can not compile, need apply this patch 
first:
http://lists.gnu.org/archive/html/qemu-devel/2011-12/msg02527.html

 Makefile.objs  |1 +
 block.c|2 +-
 block.h|1 +
 block/add-cow.c|  429 
 block_int.h|1 +
 docs/specs/add-cow.txt |   72 
 6 files changed, 505 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 f753d83..23fab70 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 aa9d142..0f52a67 100644
--- a/block.c
+++ b/block.c
@@ -187,7 +187,7 @@ static void bdrv_io_limits_intercept(BlockDriverState *bs,
 }
 
 /* check if the path starts with ":" */
-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 0e3ff9f..f5bf078 100644
--- a/block.h
+++ b/block.h
@@ -289,6 +289,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..95af5b7
--- /dev/null
+++ b/block/add-cow.c
@@ -0,0 +1,429 @@
+#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;
+charreserved[492];
+} 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];
+BlockDriver *image_drv = NULL;
+int ret;
+BDRVAddCowState *s = bs->opaque;
+BlockDriverState*backing_bs = NULL;
+
+ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
+if (ret != sizeof(header)) {
+goto fail;
+}
+
+if (be64_to_cpu(header.magic) != ADD_COW_MAGIC) {
+ret = -EINVAL;
+goto fail;
+}
+if (be32_to_cpu(header.version) != ADD_COW_VERSION) {
+char version[64];
+snprintf(version, sizeof(version), "ADD-COW version %d", 
header.version);
+qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
+bs->device_name, "add-cow", version);
+ret = -ENOTSUP;
+goto fail;
+}
+
+size = be64_to_cpu(header.size);
+bs->total_sectors = size / BDRV_SECTOR_SIZE;
+
+QEMU_BUILD_BUG_ON(sizeof(bs->backing_file) != sizeof(header.backing_file));
+QEMU_BUILD_BUG_ON(sizeof(s->image_file) != sizeof(header.image_file));
+pstrcpy(bs->backing_file, sizeof(bs->backing_file),
+header.backing_file);
+pstrcpy(s->image_file, sizeof(s->image_file),
+header.image_file);
+
+s->bitmap_size = ((bs->total_sectors + 7) >> 3);
+s->bitmap = qemu_blockalign(bs, s->bitmap_size);
+