1/*
2 * Block driver for the COW 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 "qemu-common.h"
25#include "block_int.h"
26#include "module.h"
27
28/**************************************************************/
29/* COW block driver using file system holes */
30
31/* user mode linux compatible COW file */
32#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
33#define COW_VERSION 2
34
35struct cow_header_v2 {
36    uint32_t magic;
37    uint32_t version;
38    char backing_file[1024];
39    int32_t mtime;
40    uint64_t size;
41    uint32_t sectorsize;
42};
43
44typedef struct BDRVCowState {
45    int64_t cow_sectors_offset;
46} BDRVCowState;
47
48static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
49{
50    const struct cow_header_v2 *cow_header = (const void *)buf;
51
52    if (buf_size >= sizeof(struct cow_header_v2) &&
53        be32_to_cpu(cow_header->magic) == COW_MAGIC &&
54        be32_to_cpu(cow_header->version) == COW_VERSION)
55        return 100;
56    else
57        return 0;
58}
59
60static int cow_open(BlockDriverState *bs, int flags)
61{
62    BDRVCowState *s = bs->opaque;
63    struct cow_header_v2 cow_header;
64    int bitmap_size;
65    int64_t size;
66
67    /* see if it is a cow image */
68    if (bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header)) !=
69            sizeof(cow_header)) {
70        goto fail;
71    }
72
73    if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
74        be32_to_cpu(cow_header.version) != COW_VERSION) {
75        goto fail;
76    }
77
78    /* cow image found */
79    size = be64_to_cpu(cow_header.size);
80    bs->total_sectors = size / 512;
81
82    pstrcpy(bs->backing_file, sizeof(bs->backing_file),
83            cow_header.backing_file);
84
85    bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
86    s->cow_sectors_offset = (bitmap_size + 511) & ~511;
87    return 0;
88 fail:
89    return -1;
90}
91
92/*
93 * XXX(hch): right now these functions are extremly ineffcient.
94 * We should just read the whole bitmap we'll need in one go instead.
95 */
96static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
97{
98    uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
99    uint8_t bitmap;
100    int ret;
101
102    ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
103    if (ret < 0) {
104       return ret;
105    }
106
107    bitmap |= (1 << (bitnum % 8));
108
109    ret = bdrv_pwrite_sync(bs->file, offset, &bitmap, sizeof(bitmap));
110    if (ret < 0) {
111       return ret;
112    }
113    return 0;
114}
115
116static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum)
117{
118    uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
119    uint8_t bitmap;
120    int ret;
121
122    ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
123    if (ret < 0) {
124       return ret;
125    }
126
127    return !!(bitmap & (1 << (bitnum % 8)));
128}
129
130/* Return true if first block has been changed (ie. current version is
131 * in COW file).  Set the number of continuous blocks for which that
132 * is true. */
133static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
134        int nb_sectors, int *num_same)
135{
136    int changed;
137
138    if (nb_sectors == 0) {
139	*num_same = nb_sectors;
140	return 0;
141    }
142
143    changed = is_bit_set(bs, sector_num);
144    if (changed < 0) {
145        return 0; /* XXX: how to return I/O errors? */
146    }
147
148    for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
149	if (is_bit_set(bs, sector_num + *num_same) != changed)
150	    break;
151    }
152
153    return changed;
154}
155
156static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,
157        int nb_sectors)
158{
159    int error = 0;
160    int i;
161
162    for (i = 0; i < nb_sectors; i++) {
163        error = cow_set_bit(bs, sector_num + i);
164        if (error) {
165            break;
166        }
167    }
168
169    return error;
170}
171
172static int cow_read(BlockDriverState *bs, int64_t sector_num,
173                    uint8_t *buf, int nb_sectors)
174{
175    BDRVCowState *s = bs->opaque;
176    int ret, n;
177
178    while (nb_sectors > 0) {
179        if (cow_is_allocated(bs, sector_num, nb_sectors, &n)) {
180            ret = bdrv_pread(bs->file,
181                        s->cow_sectors_offset + sector_num * 512,
182                        buf, n * 512);
183            if (ret != n * 512)
184                return -1;
185        } else {
186            if (bs->backing_hd) {
187                /* read from the base image */
188                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
189                if (ret < 0)
190                    return -1;
191            } else {
192            memset(buf, 0, n * 512);
193        }
194        }
195        nb_sectors -= n;
196        sector_num += n;
197        buf += n * 512;
198    }
199    return 0;
200}
201
202static int cow_write(BlockDriverState *bs, int64_t sector_num,
203                     const uint8_t *buf, int nb_sectors)
204{
205    BDRVCowState *s = bs->opaque;
206    int ret;
207
208    ret = bdrv_pwrite(bs->file, s->cow_sectors_offset + sector_num * 512,
209                      buf, nb_sectors * 512);
210    if (ret != nb_sectors * 512)
211        return -1;
212
213    return cow_update_bitmap(bs, sector_num, nb_sectors);
214}
215
216static void cow_close(BlockDriverState *bs)
217{
218}
219
220static int cow_create(const char *filename, QEMUOptionParameter *options)
221{
222    int fd, cow_fd;
223    struct cow_header_v2 cow_header;
224    struct stat st;
225    int64_t image_sectors = 0;
226    const char *image_filename = NULL;
227    int ret;
228
229    /* Read out options */
230    while (options && options->name) {
231        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
232            image_sectors = options->value.n / 512;
233        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
234            image_filename = options->value.s;
235        }
236        options++;
237    }
238
239    cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
240              0644);
241    if (cow_fd < 0)
242        return -errno;
243    memset(&cow_header, 0, sizeof(cow_header));
244    cow_header.magic = cpu_to_be32(COW_MAGIC);
245    cow_header.version = cpu_to_be32(COW_VERSION);
246    if (image_filename) {
247        /* Note: if no file, we put a dummy mtime */
248        cow_header.mtime = cpu_to_be32(0);
249
250        fd = open(image_filename, O_RDONLY | O_BINARY);
251        if (fd < 0) {
252            close(cow_fd);
253            goto mtime_fail;
254        }
255        if (fstat(fd, &st) != 0) {
256            close(fd);
257            goto mtime_fail;
258        }
259        close(fd);
260        cow_header.mtime = cpu_to_be32(st.st_mtime);
261    mtime_fail:
262        pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file),
263                image_filename);
264    }
265    cow_header.sectorsize = cpu_to_be32(512);
266    cow_header.size = cpu_to_be64(image_sectors * 512);
267    ret = qemu_write_full(cow_fd, &cow_header, sizeof(cow_header));
268    if (ret != sizeof(cow_header)) {
269        ret = -errno;
270        goto exit;
271    }
272
273    /* resize to include at least all the bitmap */
274    ret = ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
275    if (ret) {
276        ret = -errno;
277        goto exit;
278    }
279
280exit:
281    close(cow_fd);
282    return ret;
283}
284
285static void cow_flush(BlockDriverState *bs)
286{
287    bdrv_flush(bs->file);
288}
289
290static QEMUOptionParameter cow_create_options[] = {
291    {
292        .name = BLOCK_OPT_SIZE,
293        .type = OPT_SIZE,
294        .help = "Virtual disk size"
295    },
296    {
297        .name = BLOCK_OPT_BACKING_FILE,
298        .type = OPT_STRING,
299        .help = "File name of a base image"
300    },
301    { NULL }
302};
303
304static BlockDriver bdrv_cow = {
305    .format_name	= "cow",
306    .instance_size	= sizeof(BDRVCowState),
307    .bdrv_probe		= cow_probe,
308    .bdrv_open		= cow_open,
309    .bdrv_read		= cow_read,
310    .bdrv_write		= cow_write,
311    .bdrv_close		= cow_close,
312    .bdrv_create	= cow_create,
313    .bdrv_flush		= cow_flush,
314    .bdrv_is_allocated	= cow_is_allocated,
315
316    .create_options = cow_create_options,
317};
318
319static void bdrv_cow_init(void)
320{
321    bdrv_register(&bdrv_cow);
322}
323
324block_init(bdrv_cow_init);
325