Revision f965509c

b/block-qcow2.c
84 84
    uint32_t len;
85 85
} QCowExtension;
86 86
#define  QCOW_EXT_MAGIC_END 0
87
#define  QCOW_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
87 88

  
88 89

  
89 90
typedef struct __attribute__((packed)) QCowSnapshotHeader {
......
235 236
        switch (ext.magic) {
236 237
        case QCOW_EXT_MAGIC_END:
237 238
            return 0;
239

  
240
        case QCOW_EXT_MAGIC_BACKING_FORMAT:
241
            if (ext.len >= sizeof(bs->backing_format)) {
242
                fprintf(stderr, "ERROR: ext_backing_format: len=%u too large"
243
                        " (>=%lu)\n",
244
                        ext.len, sizeof(bs->backing_format));
245
                return 2;
246
            }
247
            if (bdrv_pread(s->hd, offset , bs->backing_format,
248
                           ext.len) != ext.len)
249
                return 3;
250
            bs->backing_format[ext.len] = '\0';
251
#ifdef DEBUG_EXT
252
            printf("Qcow2: Got format extension %s\n", bs->backing_format);
253
#endif
254
            offset += ((ext.len + 7) & ~7);
255
            break;
256

  
238 257
        default:
239 258
            /* unknown magic -- just skip it */
240 259
            offset += ((ext.len + 7) & ~7);
......
1526 1545
    }
1527 1546
}
1528 1547

  
1529
static int qcow_create(const char *filename, int64_t total_size,
1530
                      const char *backing_file, int flags)
1548
static int qcow_create2(const char *filename, int64_t total_size,
1549
                        const char *backing_file, const char *backing_format,
1550
                        int flags)
1531 1551
{
1552

  
1532 1553
    int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
1554
    int backing_format_len = 0;
1533 1555
    QCowHeader header;
1534 1556
    uint64_t tmp, offset;
1535 1557
    QCowCreateState s1, *s = &s1;
1558
    QCowExtension ext_bf = {0, 0};
1559

  
1536 1560

  
1537 1561
    memset(s, 0, sizeof(*s));
1538 1562

  
......
1546 1570
    header_size = sizeof(header);
1547 1571
    backing_filename_len = 0;
1548 1572
    if (backing_file) {
1573
        if (backing_format) {
1574
            ext_bf.magic = QCOW_EXT_MAGIC_BACKING_FORMAT;
1575
            backing_format_len = strlen(backing_format);
1576
            ext_bf.len = (backing_format_len + 7) & ~7;
1577
            header_size += ((sizeof(ext_bf) + ext_bf.len + 7) & ~7);
1578
        }
1549 1579
        header.backing_file_offset = cpu_to_be64(header_size);
1550 1580
        backing_filename_len = strlen(backing_file);
1551 1581
        header.backing_file_size = cpu_to_be32(backing_filename_len);
......
1590 1620
    /* write all the data */
1591 1621
    write(fd, &header, sizeof(header));
1592 1622
    if (backing_file) {
1623
        if (backing_format_len) {
1624
            char zero[16];
1625
            int d = ext_bf.len - backing_format_len;
1626

  
1627
            memset(zero, 0, sizeof(zero));
1628
            cpu_to_be32s(&ext_bf.magic);
1629
            cpu_to_be32s(&ext_bf.len);
1630
            write(fd, &ext_bf, sizeof(ext_bf));
1631
            write(fd, backing_format, backing_format_len);
1632
            if (d>0) {
1633
                write(fd, zero, d);
1634
            }
1635
        }
1593 1636
        write(fd, backing_file, backing_filename_len);
1594 1637
    }
1595 1638
    lseek(fd, s->l1_table_offset, SEEK_SET);
......
1609 1652
    return 0;
1610 1653
}
1611 1654

  
1655
static int qcow_create(const char *filename, int64_t total_size,
1656
                       const char *backing_file, int flags)
1657
{
1658
    return qcow_create2(filename, total_size, backing_file, NULL, flags);
1659
}
1660

  
1612 1661
static int qcow_make_empty(BlockDriverState *bs)
1613 1662
{
1614 1663
#if 0
......
2685 2734
    .bdrv_snapshot_delete = qcow_snapshot_delete,
2686 2735
    .bdrv_snapshot_list	= qcow_snapshot_list,
2687 2736
    .bdrv_get_info	= qcow_get_info,
2737

  
2738
    .bdrv_create2 = qcow_create2,
2688 2739
};

Also available in: Unified diff