source: trunk/packages/xen-common/xen-common/tools/ioemu/block-qcow.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 22.6 KB
Line 
1/*
2 * Block driver for the QCOW format
3 *
4 * Copyright (c) 2004 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include "vl.h"
25#include "block_int.h"
26#include <zlib.h>
27#include "aes.h"
28
29/**************************************************************/
30/* QEMU COW block driver with compression and encryption support */
31
32#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
33#define QCOW_VERSION 1
34
35#define QCOW_CRYPT_NONE 0
36#define QCOW_CRYPT_AES  1
37
38#define QCOW_OFLAG_COMPRESSED (1LL << 63)
39
40typedef struct QCowHeader {
41    uint32_t magic;
42    uint32_t version;
43    uint64_t backing_file_offset;
44    uint32_t backing_file_size;
45    uint32_t mtime;
46    uint64_t size; /* in bytes */
47    uint8_t cluster_bits;
48    uint8_t l2_bits;
49    uint32_t crypt_method;
50    uint64_t l1_table_offset;
51} QCowHeader;
52
53#define L2_CACHE_SIZE 16
54
55typedef struct BDRVQcowState {
56    int fd;
57    int cluster_bits;
58    int cluster_size;
59    int cluster_sectors;
60    int l2_bits;
61    int l2_size;
62    int l1_size;
63    uint64_t cluster_offset_mask;
64    uint64_t l1_table_offset;
65    uint64_t *l1_table;
66    uint64_t *l2_cache;
67    uint64_t l2_cache_offsets[L2_CACHE_SIZE];
68    uint32_t l2_cache_counts[L2_CACHE_SIZE];
69    uint8_t *cluster_cache;
70    uint8_t *cluster_data;
71    uint64_t cluster_cache_offset;
72    uint32_t crypt_method; /* current crypt method, 0 if no key yet */
73    uint32_t crypt_method_header;
74    AES_KEY aes_encrypt_key;
75    AES_KEY aes_decrypt_key;
76} BDRVQcowState;
77
78static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
79
80static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
81{
82    const QCowHeader *cow_header = (const void *)buf;
83   
84    if (buf_size >= sizeof(QCowHeader) &&
85        be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
86        be32_to_cpu(cow_header->version) == QCOW_VERSION) 
87        return 100;
88    else
89        return 0;
90}
91
92static int qcow_open(BlockDriverState *bs, const char *filename)
93{
94    BDRVQcowState *s = bs->opaque;
95    int fd, len, i, shift;
96    QCowHeader header;
97   
98    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
99    if (fd < 0) {
100        fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
101        if (fd < 0)
102            return -1;
103    }
104    s->fd = fd;
105    if (read(fd, &header, sizeof(header)) != sizeof(header))
106        goto fail;
107    be32_to_cpus(&header.magic);
108    be32_to_cpus(&header.version);
109    be64_to_cpus(&header.backing_file_offset);
110    be32_to_cpus(&header.backing_file_size);
111    be32_to_cpus(&header.mtime);
112    be64_to_cpus(&header.size);
113    be32_to_cpus(&header.crypt_method);
114    be64_to_cpus(&header.l1_table_offset);
115   
116    if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
117        goto fail;
118    if (header.size <= 1 || header.cluster_bits < 9)
119        goto fail;
120    if (header.crypt_method > QCOW_CRYPT_AES)
121        goto fail;
122    s->crypt_method_header = header.crypt_method;
123    if (s->crypt_method_header)
124        bs->encrypted = 1;
125    s->cluster_bits = header.cluster_bits;
126    s->cluster_size = 1 << s->cluster_bits;
127    s->cluster_sectors = 1 << (s->cluster_bits - 9);
128    s->l2_bits = header.l2_bits;
129    s->l2_size = 1 << s->l2_bits;
130    bs->total_sectors = header.size / 512;
131    s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
132
133    /* read the level 1 table */
134    shift = s->cluster_bits + s->l2_bits;
135    s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
136
137    s->l1_table_offset = header.l1_table_offset;
138    s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
139    if (!s->l1_table)
140        goto fail;
141    lseek(fd, s->l1_table_offset, SEEK_SET);
142    if (read(fd, s->l1_table, s->l1_size * sizeof(uint64_t)) != 
143        s->l1_size * sizeof(uint64_t))
144        goto fail;
145    for(i = 0;i < s->l1_size; i++) {
146        be64_to_cpus(&s->l1_table[i]);
147    }
148    /* alloc L2 cache */
149    s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
150    if (!s->l2_cache)
151        goto fail;
152    s->cluster_cache = qemu_malloc(s->cluster_size);
153    if (!s->cluster_cache)
154        goto fail;
155    s->cluster_data = qemu_malloc(s->cluster_size);
156    if (!s->cluster_data)
157        goto fail;
158    s->cluster_cache_offset = -1;
159   
160    /* read the backing file name */
161    if (header.backing_file_offset != 0) {
162        len = header.backing_file_size;
163        if (len > 1023)
164            len = 1023;
165        lseek(fd, header.backing_file_offset, SEEK_SET);
166        if (read(fd, bs->backing_file, len) != len)
167            goto fail;
168        bs->backing_file[len] = '\0';
169    }
170    return 0;
171
172 fail:
173    qemu_free(s->l1_table);
174    qemu_free(s->l2_cache);
175    qemu_free(s->cluster_cache);
176    qemu_free(s->cluster_data);
177    close(fd);
178    return -1;
179}
180
181static int qcow_set_key(BlockDriverState *bs, const char *key)
182{
183    BDRVQcowState *s = bs->opaque;
184    uint8_t keybuf[16];
185    int len, i;
186   
187    memset(keybuf, 0, 16);
188    len = strlen(key);
189    if (len > 16)
190        len = 16;
191    /* XXX: we could compress the chars to 7 bits to increase
192       entropy */
193    for(i = 0;i < len;i++) {
194        keybuf[i] = key[i];
195    }
196    s->crypt_method = s->crypt_method_header;
197
198    if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
199        return -1;
200    if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
201        return -1;
202#if 0
203    /* test */
204    {
205        uint8_t in[16];
206        uint8_t out[16];
207        uint8_t tmp[16];
208        for(i=0;i<16;i++)
209            in[i] = i;
210        AES_encrypt(in, tmp, &s->aes_encrypt_key);
211        AES_decrypt(tmp, out, &s->aes_decrypt_key);
212        for(i = 0; i < 16; i++)
213            printf(" %02x", tmp[i]);
214        printf("\n");
215        for(i = 0; i < 16; i++)
216            printf(" %02x", out[i]);
217        printf("\n");
218    }
219#endif
220    return 0;
221}
222
223/* The crypt function is compatible with the linux cryptoloop
224   algorithm for < 4 GB images. NOTE: out_buf == in_buf is
225   supported */
226static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
227                            uint8_t *out_buf, const uint8_t *in_buf,
228                            int nb_sectors, int enc,
229                            const AES_KEY *key)
230{
231    union {
232        uint64_t ll[2];
233        uint8_t b[16];
234    } ivec;
235    int i;
236
237    for(i = 0; i < nb_sectors; i++) {
238        ivec.ll[0] = cpu_to_le64(sector_num);
239        ivec.ll[1] = 0;
240        AES_cbc_encrypt(in_buf, out_buf, 512, key, 
241                        ivec.b, enc);
242        sector_num++;
243        in_buf += 512;
244        out_buf += 512;
245    }
246}
247
248/* 'allocate' is:
249 *
250 * 0 to not allocate.
251 *
252 * 1 to allocate a normal cluster (for sector indexes 'n_start' to
253 * 'n_end')
254 *
255 * 2 to allocate a compressed cluster of size
256 * 'compressed_size'. 'compressed_size' must be > 0 and <
257 * cluster_size
258 *
259 * return 0 if not allocated.
260 */
261static uint64_t get_cluster_offset(BlockDriverState *bs,
262                                   uint64_t offset, int allocate,
263                                   int compressed_size,
264                                   int n_start, int n_end)
265{
266    BDRVQcowState *s = bs->opaque;
267    int min_index, i, j, l1_index, l2_index;
268    uint64_t l2_offset, *l2_table, cluster_offset, tmp;
269    uint32_t min_count;
270    int new_l2_table;
271   
272    l1_index = offset >> (s->l2_bits + s->cluster_bits);
273    l2_offset = s->l1_table[l1_index];
274    new_l2_table = 0;
275    if (!l2_offset) {
276        if (!allocate)
277            return 0;
278        /* allocate a new l2 entry */
279        l2_offset = lseek(s->fd, 0, SEEK_END);
280        /* round to cluster size */
281        l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
282        /* update the L1 entry */
283        s->l1_table[l1_index] = l2_offset;
284        tmp = cpu_to_be64(l2_offset);
285        lseek(s->fd, s->l1_table_offset + l1_index * sizeof(tmp), SEEK_SET);
286        if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
287            return 0;
288        new_l2_table = 1;
289    }
290    for(i = 0; i < L2_CACHE_SIZE; i++) {
291        if (l2_offset == s->l2_cache_offsets[i]) {
292            /* increment the hit count */
293            if (++s->l2_cache_counts[i] == 0xffffffff) {
294                for(j = 0; j < L2_CACHE_SIZE; j++) {
295                    s->l2_cache_counts[j] >>= 1;
296                }
297            }
298            l2_table = s->l2_cache + (i << s->l2_bits);
299            goto found;
300        }
301    }
302    /* not found: load a new entry in the least used one */
303    min_index = 0;
304    min_count = 0xffffffff;
305    for(i = 0; i < L2_CACHE_SIZE; i++) {
306        if (s->l2_cache_counts[i] < min_count) {
307            min_count = s->l2_cache_counts[i];
308            min_index = i;
309        }
310    }
311    l2_table = s->l2_cache + (min_index << s->l2_bits);
312    lseek(s->fd, l2_offset, SEEK_SET);
313    if (new_l2_table) {
314        memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
315        if (write(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
316            s->l2_size * sizeof(uint64_t))
317            return 0;
318    } else {
319        if (read(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) != 
320            s->l2_size * sizeof(uint64_t))
321            return 0;
322    }
323    s->l2_cache_offsets[min_index] = l2_offset;
324    s->l2_cache_counts[min_index] = 1;
325 found:
326    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
327    cluster_offset = be64_to_cpu(l2_table[l2_index]);
328    if (!cluster_offset || 
329        ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
330        if (!allocate)
331            return 0;
332        /* allocate a new cluster */
333        if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
334            (n_end - n_start) < s->cluster_sectors) {
335            /* if the cluster is already compressed, we must
336               decompress it in the case it is not completely
337               overwritten */
338            if (decompress_cluster(s, cluster_offset) < 0)
339                return 0;
340            cluster_offset = lseek(s->fd, 0, SEEK_END);
341            cluster_offset = (cluster_offset + s->cluster_size - 1) & 
342                ~(s->cluster_size - 1);
343            /* write the cluster content */
344            lseek(s->fd, cluster_offset, SEEK_SET);
345            if (write(s->fd, s->cluster_cache, s->cluster_size) != 
346                s->cluster_size)
347                return -1;
348        } else {
349            cluster_offset = lseek(s->fd, 0, SEEK_END);
350            if (allocate == 1) {
351                /* round to cluster size */
352                cluster_offset = (cluster_offset + s->cluster_size - 1) & 
353                    ~(s->cluster_size - 1);
354                ftruncate(s->fd, cluster_offset + s->cluster_size);
355                /* if encrypted, we must initialize the cluster
356                   content which won't be written */
357                if (s->crypt_method && 
358                    (n_end - n_start) < s->cluster_sectors) {
359                    uint64_t start_sect;
360                    start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
361                    memset(s->cluster_data + 512, 0xaa, 512);
362                    for(i = 0; i < s->cluster_sectors; i++) {
363                        if (i < n_start || i >= n_end) {
364                            encrypt_sectors(s, start_sect + i, 
365                                            s->cluster_data, 
366                                            s->cluster_data + 512, 1, 1,
367                                            &s->aes_encrypt_key);
368                            lseek(s->fd, cluster_offset + i * 512, SEEK_SET);
369                            if (write(s->fd, s->cluster_data, 512) != 512)
370                                return -1;
371                        }
372                    }
373                }
374            } else {
375                cluster_offset |= QCOW_OFLAG_COMPRESSED | 
376                    (uint64_t)compressed_size << (63 - s->cluster_bits);
377            }
378        }
379        /* update L2 table */
380        tmp = cpu_to_be64(cluster_offset);
381        l2_table[l2_index] = tmp;
382        lseek(s->fd, l2_offset + l2_index * sizeof(tmp), SEEK_SET);
383        if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
384            return 0;
385    }
386    return cluster_offset;
387}
388
389static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num, 
390                             int nb_sectors, int *pnum)
391{
392    BDRVQcowState *s = bs->opaque;
393    int index_in_cluster, n;
394    uint64_t cluster_offset;
395
396    cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
397    index_in_cluster = sector_num & (s->cluster_sectors - 1);
398    n = s->cluster_sectors - index_in_cluster;
399    if (n > nb_sectors)
400        n = nb_sectors;
401    *pnum = n;
402    return (cluster_offset != 0);
403}
404
405static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
406                             const uint8_t *buf, int buf_size)
407{
408    z_stream strm1, *strm = &strm1;
409    int ret, out_len;
410
411    memset(strm, 0, sizeof(*strm));
412
413    strm->next_in = (uint8_t *)buf;
414    strm->avail_in = buf_size;
415    strm->next_out = out_buf;
416    strm->avail_out = out_buf_size;
417
418    ret = inflateInit2(strm, -12);
419    if (ret != Z_OK)
420        return -1;
421    ret = inflate(strm, Z_FINISH);
422    out_len = strm->next_out - out_buf;
423    if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
424        out_len != out_buf_size) {
425        inflateEnd(strm);
426        return -1;
427    }
428    inflateEnd(strm);
429    return 0;
430}
431                             
432static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
433{
434    int ret, csize;
435    uint64_t coffset;
436
437    coffset = cluster_offset & s->cluster_offset_mask;
438    if (s->cluster_cache_offset != coffset) {
439        csize = cluster_offset >> (63 - s->cluster_bits);
440        csize &= (s->cluster_size - 1);
441        lseek(s->fd, coffset, SEEK_SET);
442        ret = read(s->fd, s->cluster_data, csize);
443        if (ret != csize) 
444            return -1;
445        if (decompress_buffer(s->cluster_cache, s->cluster_size,
446                              s->cluster_data, csize) < 0) {
447            return -1;
448        }
449        s->cluster_cache_offset = coffset;
450    }
451    return 0;
452}
453
454static int qcow_read(BlockDriverState *bs, int64_t sector_num, 
455                     uint8_t *buf, int nb_sectors)
456{
457    BDRVQcowState *s = bs->opaque;
458    int ret, index_in_cluster, n;
459    uint64_t cluster_offset;
460   
461    while (nb_sectors > 0) {
462        cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
463        index_in_cluster = sector_num & (s->cluster_sectors - 1);
464        n = s->cluster_sectors - index_in_cluster;
465        if (n > nb_sectors)
466            n = nb_sectors;
467        if (!cluster_offset) {
468            memset(buf, 0, 512 * n);
469        } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
470            if (decompress_cluster(s, cluster_offset) < 0)
471                return -1;
472            memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
473        } else {
474            lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
475            ret = read(s->fd, buf, n * 512);
476            if (ret != n * 512) 
477                return -1;
478            if (s->crypt_method) {
479                encrypt_sectors(s, sector_num, buf, buf, n, 0, 
480                                &s->aes_decrypt_key);
481            }
482        }
483        nb_sectors -= n;
484        sector_num += n;
485        buf += n * 512;
486    }
487    return 0;
488}
489
490static int qcow_write(BlockDriverState *bs, int64_t sector_num, 
491                     const uint8_t *buf, int nb_sectors)
492{
493    BDRVQcowState *s = bs->opaque;
494    int ret, index_in_cluster, n;
495    uint64_t cluster_offset;
496   
497    while (nb_sectors > 0) {
498        index_in_cluster = sector_num & (s->cluster_sectors - 1);
499        n = s->cluster_sectors - index_in_cluster;
500        if (n > nb_sectors)
501            n = nb_sectors;
502        cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0, 
503                                            index_in_cluster, 
504                                            index_in_cluster + n);
505        if (!cluster_offset)
506            return -1;
507        lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
508        if (s->crypt_method) {
509            encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
510                            &s->aes_encrypt_key);
511            ret = write(s->fd, s->cluster_data, n * 512);
512        } else {
513            ret = write(s->fd, buf, n * 512);
514        }
515        if (ret != n * 512) 
516            return -1;
517        nb_sectors -= n;
518        sector_num += n;
519        buf += n * 512;
520    }
521    s->cluster_cache_offset = -1; /* disable compressed cache */
522    return 0;
523}
524
525static void qcow_close(BlockDriverState *bs)
526{
527    BDRVQcowState *s = bs->opaque;
528    qemu_free(s->l1_table);
529    qemu_free(s->l2_cache);
530    qemu_free(s->cluster_cache);
531    qemu_free(s->cluster_data);
532    close(s->fd);
533}
534
535static int qcow_create(const char *filename, int64_t total_size,
536                      const char *backing_file, int flags)
537{
538    int fd, header_size, backing_filename_len, l1_size, i, shift;
539    QCowHeader header;
540    char backing_filename[1024];
541    uint64_t tmp;
542    struct stat st;
543
544    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 
545              0644);
546    if (fd < 0)
547        return -1;
548    memset(&header, 0, sizeof(header));
549    header.magic = cpu_to_be32(QCOW_MAGIC);
550    header.version = cpu_to_be32(QCOW_VERSION);
551    header.size = cpu_to_be64(total_size * 512);
552    header_size = sizeof(header);
553    backing_filename_len = 0;
554    if (backing_file) {
555        if (strcmp(backing_file, "fat:")) {
556            const char *p;
557            /* XXX: this is a hack: we do not attempt to check for URL
558               like syntax */
559            p = strchr(backing_file, ':');
560            if (p && (p - backing_file) >= 2) {
561                /* URL like but exclude "c:" like filenames */
562                pstrcpy(backing_filename, sizeof(backing_filename),
563                        backing_file);
564            } else {
565                realpath(backing_file, backing_filename);
566                if (stat(backing_filename, &st) != 0) {
567                    return -1;
568                }
569            }
570            header.backing_file_offset = cpu_to_be64(header_size);
571            backing_filename_len = strlen(backing_filename);
572            header.backing_file_size = cpu_to_be32(backing_filename_len);
573            header_size += backing_filename_len;
574        } else
575            backing_file = NULL;
576        header.mtime = cpu_to_be32(st.st_mtime);
577        header.cluster_bits = 9; /* 512 byte cluster to avoid copying
578                                    unmodifyed sectors */
579        header.l2_bits = 12; /* 32 KB L2 tables */
580    } else {
581        header.cluster_bits = 12; /* 4 KB clusters */
582        header.l2_bits = 9; /* 4 KB L2 tables */
583    }
584    header_size = (header_size + 7) & ~7;
585    shift = header.cluster_bits + header.l2_bits;
586    l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
587
588    header.l1_table_offset = cpu_to_be64(header_size);
589    if (flags) {
590        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
591    } else {
592        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
593    }
594   
595    /* write all the data */
596    write(fd, &header, sizeof(header));
597    if (backing_file) {
598        write(fd, backing_filename, backing_filename_len);
599    }
600    lseek(fd, header_size, SEEK_SET);
601    tmp = 0;
602    for(i = 0;i < l1_size; i++) {
603        write(fd, &tmp, sizeof(tmp));
604    }
605    close(fd);
606    return 0;
607}
608
609int qcow_make_empty(BlockDriverState *bs)
610{
611    BDRVQcowState *s = bs->opaque;
612    uint32_t l1_length = s->l1_size * sizeof(uint64_t);
613
614    memset(s->l1_table, 0, l1_length);
615    lseek(s->fd, s->l1_table_offset, SEEK_SET);
616    if (write(s->fd, s->l1_table, l1_length) < 0)
617        return -1;
618    ftruncate(s->fd, s->l1_table_offset + l1_length);
619
620    memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
621    memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
622    memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t));
623
624    return 0;
625}
626
627int qcow_get_cluster_size(BlockDriverState *bs)
628{
629    BDRVQcowState *s = bs->opaque;
630    if (bs->drv != &bdrv_qcow)
631        return -1;
632    return s->cluster_size;
633}
634
635/* XXX: put compressed sectors first, then all the cluster aligned
636   tables to avoid losing bytes in alignment */
637int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num, 
638                          const uint8_t *buf)
639{
640    BDRVQcowState *s = bs->opaque;
641    z_stream strm;
642    int ret, out_len;
643    uint8_t *out_buf;
644    uint64_t cluster_offset;
645
646    if (bs->drv != &bdrv_qcow)
647        return -1;
648
649    out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
650    if (!out_buf)
651        return -1;
652
653    /* best compression, small window, no zlib header */
654    memset(&strm, 0, sizeof(strm));
655    ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
656                       Z_DEFLATED, -12, 
657                       9, Z_DEFAULT_STRATEGY);
658    if (ret != 0) {
659        qemu_free(out_buf);
660        return -1;
661    }
662
663    strm.avail_in = s->cluster_size;
664    strm.next_in = (uint8_t *)buf;
665    strm.avail_out = s->cluster_size;
666    strm.next_out = out_buf;
667
668    ret = deflate(&strm, Z_FINISH);
669    if (ret != Z_STREAM_END && ret != Z_OK) {
670        qemu_free(out_buf);
671        deflateEnd(&strm);
672        return -1;
673    }
674    out_len = strm.next_out - out_buf;
675
676    deflateEnd(&strm);
677
678    if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
679        /* could not compress: write normal cluster */
680        qcow_write(bs, sector_num, buf, s->cluster_sectors);
681    } else {
682        cluster_offset = get_cluster_offset(bs, sector_num << 9, 2, 
683                                            out_len, 0, 0);
684        cluster_offset &= s->cluster_offset_mask;
685        lseek(s->fd, cluster_offset, SEEK_SET);
686        if (write(s->fd, out_buf, out_len) != out_len) {
687            qemu_free(out_buf);
688            return -1;
689        }
690    }
691   
692    qemu_free(out_buf);
693    return 0;
694}
695
696static void qcow_flush(BlockDriverState *bs)
697{
698    BDRVQcowState *s = bs->opaque;
699    fsync(s->fd);
700}
701
702BlockDriver bdrv_qcow = {
703    "qcow",
704    sizeof(BDRVQcowState),
705    qcow_probe,
706    qcow_open,
707    qcow_read,
708    qcow_write,
709    qcow_close,
710    qcow_create,
711    qcow_flush,
712    qcow_is_allocated,
713    qcow_set_key,
714    qcow_make_empty
715};
716
717
Note: See TracBrowser for help on using the repository browser.