Statistics
| Branch: | Revision:

root / block / cow.c @ 205ef796

History | View | Annotate | Download (8.6 kB)

1 ea2384d3 bellard
/*
2 ea2384d3 bellard
 * Block driver for the COW format
3 5fafdf24 ths
 *
4 ea2384d3 bellard
 * Copyright (c) 2004 Fabrice Bellard
5 5fafdf24 ths
 *
6 ea2384d3 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 ea2384d3 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 ea2384d3 bellard
 * in the Software without restriction, including without limitation the rights
9 ea2384d3 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 ea2384d3 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 ea2384d3 bellard
 * furnished to do so, subject to the following conditions:
12 ea2384d3 bellard
 *
13 ea2384d3 bellard
 * The above copyright notice and this permission notice shall be included in
14 ea2384d3 bellard
 * all copies or substantial portions of the Software.
15 ea2384d3 bellard
 *
16 ea2384d3 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 ea2384d3 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 ea2384d3 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 ea2384d3 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 ea2384d3 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 ea2384d3 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 ea2384d3 bellard
 * THE SOFTWARE.
23 ea2384d3 bellard
 */
24 faf07963 pbrook
#include "qemu-common.h"
25 ea2384d3 bellard
#include "block_int.h"
26 5efa9d5a Anthony Liguori
#include "module.h"
27 ea2384d3 bellard
28 ea2384d3 bellard
/**************************************************************/
29 ea2384d3 bellard
/* COW block driver using file system holes */
30 ea2384d3 bellard
31 ea2384d3 bellard
/* user mode linux compatible COW file */
32 ea2384d3 bellard
#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
33 ea2384d3 bellard
#define COW_VERSION 2
34 ea2384d3 bellard
35 ea2384d3 bellard
struct cow_header_v2 {
36 ea2384d3 bellard
    uint32_t magic;
37 ea2384d3 bellard
    uint32_t version;
38 ea2384d3 bellard
    char backing_file[1024];
39 ea2384d3 bellard
    int32_t mtime;
40 ea2384d3 bellard
    uint64_t size;
41 ea2384d3 bellard
    uint32_t sectorsize;
42 ea2384d3 bellard
};
43 ea2384d3 bellard
44 ea2384d3 bellard
typedef struct BDRVCowState {
45 ea2384d3 bellard
    int64_t cow_sectors_offset;
46 ea2384d3 bellard
} BDRVCowState;
47 ea2384d3 bellard
48 ea2384d3 bellard
static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
49 ea2384d3 bellard
{
50 ea2384d3 bellard
    const struct cow_header_v2 *cow_header = (const void *)buf;
51 ea2384d3 bellard
52 712e7874 bellard
    if (buf_size >= sizeof(struct cow_header_v2) &&
53 712e7874 bellard
        be32_to_cpu(cow_header->magic) == COW_MAGIC &&
54 5fafdf24 ths
        be32_to_cpu(cow_header->version) == COW_VERSION)
55 ea2384d3 bellard
        return 100;
56 ea2384d3 bellard
    else
57 ea2384d3 bellard
        return 0;
58 ea2384d3 bellard
}
59 ea2384d3 bellard
60 2063392a Christoph Hellwig
static int cow_open(BlockDriverState *bs, int flags)
61 ea2384d3 bellard
{
62 ea2384d3 bellard
    BDRVCowState *s = bs->opaque;
63 ea2384d3 bellard
    struct cow_header_v2 cow_header;
64 893a9cb4 Christoph Hellwig
    int bitmap_size;
65 ea2384d3 bellard
    int64_t size;
66 ea2384d3 bellard
67 ea2384d3 bellard
    /* see if it is a cow image */
68 2063392a Christoph Hellwig
    if (bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header)) !=
69 2063392a Christoph Hellwig
            sizeof(cow_header)) {
70 ea2384d3 bellard
        goto fail;
71 ea2384d3 bellard
    }
72 ea2384d3 bellard
73 ea2384d3 bellard
    if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
74 ea2384d3 bellard
        be32_to_cpu(cow_header.version) != COW_VERSION) {
75 ea2384d3 bellard
        goto fail;
76 ea2384d3 bellard
    }
77 3b46e624 ths
78 ea2384d3 bellard
    /* cow image found */
79 ea2384d3 bellard
    size = be64_to_cpu(cow_header.size);
80 ea2384d3 bellard
    bs->total_sectors = size / 512;
81 ea2384d3 bellard
82 5fafdf24 ths
    pstrcpy(bs->backing_file, sizeof(bs->backing_file),
83 ea2384d3 bellard
            cow_header.backing_file);
84 3b46e624 ths
85 893a9cb4 Christoph Hellwig
    bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
86 893a9cb4 Christoph Hellwig
    s->cow_sectors_offset = (bitmap_size + 511) & ~511;
87 ea2384d3 bellard
    return 0;
88 ea2384d3 bellard
 fail:
89 ea2384d3 bellard
    return -1;
90 ea2384d3 bellard
}
91 ea2384d3 bellard
92 893a9cb4 Christoph Hellwig
/*
93 893a9cb4 Christoph Hellwig
 * XXX(hch): right now these functions are extremly ineffcient.
94 893a9cb4 Christoph Hellwig
 * We should just read the whole bitmap we'll need in one go instead.
95 893a9cb4 Christoph Hellwig
 */
96 893a9cb4 Christoph Hellwig
static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
97 ea2384d3 bellard
{
98 893a9cb4 Christoph Hellwig
    uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
99 893a9cb4 Christoph Hellwig
    uint8_t bitmap;
100 b0ad5a45 Kevin Wolf
    int ret;
101 893a9cb4 Christoph Hellwig
102 b0ad5a45 Kevin Wolf
    ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
103 b0ad5a45 Kevin Wolf
    if (ret < 0) {
104 b0ad5a45 Kevin Wolf
       return ret;
105 893a9cb4 Christoph Hellwig
    }
106 893a9cb4 Christoph Hellwig
107 893a9cb4 Christoph Hellwig
    bitmap |= (1 << (bitnum % 8));
108 893a9cb4 Christoph Hellwig
109 b0ad5a45 Kevin Wolf
    ret = bdrv_pwrite_sync(bs->file, offset, &bitmap, sizeof(bitmap));
110 b0ad5a45 Kevin Wolf
    if (ret < 0) {
111 b0ad5a45 Kevin Wolf
       return ret;
112 893a9cb4 Christoph Hellwig
    }
113 893a9cb4 Christoph Hellwig
    return 0;
114 ea2384d3 bellard
}
115 ea2384d3 bellard
116 893a9cb4 Christoph Hellwig
static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum)
117 ea2384d3 bellard
{
118 893a9cb4 Christoph Hellwig
    uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
119 893a9cb4 Christoph Hellwig
    uint8_t bitmap;
120 b0ad5a45 Kevin Wolf
    int ret;
121 ea2384d3 bellard
122 b0ad5a45 Kevin Wolf
    ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
123 b0ad5a45 Kevin Wolf
    if (ret < 0) {
124 b0ad5a45 Kevin Wolf
       return ret;
125 893a9cb4 Christoph Hellwig
    }
126 893a9cb4 Christoph Hellwig
127 893a9cb4 Christoph Hellwig
    return !!(bitmap & (1 << (bitnum % 8)));
128 893a9cb4 Christoph Hellwig
}
129 ea2384d3 bellard
130 ea2384d3 bellard
/* Return true if first block has been changed (ie. current version is
131 ea2384d3 bellard
 * in COW file).  Set the number of continuous blocks for which that
132 ea2384d3 bellard
 * is true. */
133 893a9cb4 Christoph Hellwig
static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
134 893a9cb4 Christoph Hellwig
        int nb_sectors, int *num_same)
135 ea2384d3 bellard
{
136 ea2384d3 bellard
    int changed;
137 ea2384d3 bellard
138 893a9cb4 Christoph Hellwig
    if (nb_sectors == 0) {
139 ea2384d3 bellard
        *num_same = nb_sectors;
140 ea2384d3 bellard
        return 0;
141 ea2384d3 bellard
    }
142 ea2384d3 bellard
143 893a9cb4 Christoph Hellwig
    changed = is_bit_set(bs, sector_num);
144 893a9cb4 Christoph Hellwig
    if (changed < 0) {
145 893a9cb4 Christoph Hellwig
        return 0; /* XXX: how to return I/O errors? */
146 893a9cb4 Christoph Hellwig
    }
147 893a9cb4 Christoph Hellwig
148 ea2384d3 bellard
    for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
149 893a9cb4 Christoph Hellwig
        if (is_bit_set(bs, sector_num + *num_same) != changed)
150 ea2384d3 bellard
            break;
151 ea2384d3 bellard
    }
152 ea2384d3 bellard
153 ea2384d3 bellard
    return changed;
154 ea2384d3 bellard
}
155 ea2384d3 bellard
156 893a9cb4 Christoph Hellwig
static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,
157 893a9cb4 Christoph Hellwig
        int nb_sectors)
158 ea2384d3 bellard
{
159 893a9cb4 Christoph Hellwig
    int error = 0;
160 893a9cb4 Christoph Hellwig
    int i;
161 893a9cb4 Christoph Hellwig
162 893a9cb4 Christoph Hellwig
    for (i = 0; i < nb_sectors; i++) {
163 893a9cb4 Christoph Hellwig
        error = cow_set_bit(bs, sector_num + i);
164 893a9cb4 Christoph Hellwig
        if (error) {
165 893a9cb4 Christoph Hellwig
            break;
166 893a9cb4 Christoph Hellwig
        }
167 893a9cb4 Christoph Hellwig
    }
168 893a9cb4 Christoph Hellwig
169 893a9cb4 Christoph Hellwig
    return error;
170 ea2384d3 bellard
}
171 ea2384d3 bellard
172 5fafdf24 ths
static int cow_read(BlockDriverState *bs, int64_t sector_num,
173 ea2384d3 bellard
                    uint8_t *buf, int nb_sectors)
174 ea2384d3 bellard
{
175 ea2384d3 bellard
    BDRVCowState *s = bs->opaque;
176 ea2384d3 bellard
    int ret, n;
177 3b46e624 ths
178 ea2384d3 bellard
    while (nb_sectors > 0) {
179 893a9cb4 Christoph Hellwig
        if (cow_is_allocated(bs, sector_num, nb_sectors, &n)) {
180 2063392a Christoph Hellwig
            ret = bdrv_pread(bs->file,
181 2063392a Christoph Hellwig
                        s->cow_sectors_offset + sector_num * 512,
182 2063392a Christoph Hellwig
                        buf, n * 512);
183 5fafdf24 ths
            if (ret != n * 512)
184 ea2384d3 bellard
                return -1;
185 ea2384d3 bellard
        } else {
186 83f64091 bellard
            if (bs->backing_hd) {
187 83f64091 bellard
                /* read from the base image */
188 83f64091 bellard
                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
189 83f64091 bellard
                if (ret < 0)
190 83f64091 bellard
                    return -1;
191 83f64091 bellard
            } else {
192 ea2384d3 bellard
            memset(buf, 0, n * 512);
193 ea2384d3 bellard
        }
194 83f64091 bellard
        }
195 ea2384d3 bellard
        nb_sectors -= n;
196 ea2384d3 bellard
        sector_num += n;
197 ea2384d3 bellard
        buf += n * 512;
198 ea2384d3 bellard
    }
199 ea2384d3 bellard
    return 0;
200 ea2384d3 bellard
}
201 ea2384d3 bellard
202 5fafdf24 ths
static int cow_write(BlockDriverState *bs, int64_t sector_num,
203 ea2384d3 bellard
                     const uint8_t *buf, int nb_sectors)
204 ea2384d3 bellard
{
205 ea2384d3 bellard
    BDRVCowState *s = bs->opaque;
206 893a9cb4 Christoph Hellwig
    int ret;
207 3b46e624 ths
208 2063392a Christoph Hellwig
    ret = bdrv_pwrite(bs->file, s->cow_sectors_offset + sector_num * 512,
209 2063392a Christoph Hellwig
                      buf, nb_sectors * 512);
210 5fafdf24 ths
    if (ret != nb_sectors * 512)
211 ea2384d3 bellard
        return -1;
212 893a9cb4 Christoph Hellwig
213 893a9cb4 Christoph Hellwig
    return cow_update_bitmap(bs, sector_num, nb_sectors);
214 ea2384d3 bellard
}
215 ea2384d3 bellard
216 e2731add bellard
static void cow_close(BlockDriverState *bs)
217 ea2384d3 bellard
{
218 ea2384d3 bellard
}
219 ea2384d3 bellard
220 0e7e1989 Kevin Wolf
static int cow_create(const char *filename, QEMUOptionParameter *options)
221 ea2384d3 bellard
{
222 ea2384d3 bellard
    int fd, cow_fd;
223 ea2384d3 bellard
    struct cow_header_v2 cow_header;
224 ea2384d3 bellard
    struct stat st;
225 0e7e1989 Kevin Wolf
    int64_t image_sectors = 0;
226 0e7e1989 Kevin Wolf
    const char *image_filename = NULL;
227 31f38120 Kirill A. Shutemov
    int ret;
228 0e7e1989 Kevin Wolf
229 0e7e1989 Kevin Wolf
    /* Read out options */
230 0e7e1989 Kevin Wolf
    while (options && options->name) {
231 0e7e1989 Kevin Wolf
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
232 0e7e1989 Kevin Wolf
            image_sectors = options->value.n / 512;
233 0e7e1989 Kevin Wolf
        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
234 0e7e1989 Kevin Wolf
            image_filename = options->value.s;
235 0e7e1989 Kevin Wolf
        }
236 0e7e1989 Kevin Wolf
        options++;
237 0e7e1989 Kevin Wolf
    }
238 ea2384d3 bellard
239 5fafdf24 ths
    cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
240 ea2384d3 bellard
              0644);
241 ea2384d3 bellard
    if (cow_fd < 0)
242 48b66db9 Juan Quintela
        return -errno;
243 ea2384d3 bellard
    memset(&cow_header, 0, sizeof(cow_header));
244 ea2384d3 bellard
    cow_header.magic = cpu_to_be32(COW_MAGIC);
245 ea2384d3 bellard
    cow_header.version = cpu_to_be32(COW_VERSION);
246 ea2384d3 bellard
    if (image_filename) {
247 83f64091 bellard
        /* Note: if no file, we put a dummy mtime */
248 83f64091 bellard
        cow_header.mtime = cpu_to_be32(0);
249 83f64091 bellard
250 ea2384d3 bellard
        fd = open(image_filename, O_RDONLY | O_BINARY);
251 ea2384d3 bellard
        if (fd < 0) {
252 ea2384d3 bellard
            close(cow_fd);
253 83f64091 bellard
            goto mtime_fail;
254 ea2384d3 bellard
        }
255 ea2384d3 bellard
        if (fstat(fd, &st) != 0) {
256 ea2384d3 bellard
            close(fd);
257 83f64091 bellard
            goto mtime_fail;
258 ea2384d3 bellard
        }
259 ea2384d3 bellard
        close(fd);
260 ea2384d3 bellard
        cow_header.mtime = cpu_to_be32(st.st_mtime);
261 83f64091 bellard
    mtime_fail:
262 83f64091 bellard
        pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file),
263 83f64091 bellard
                image_filename);
264 ea2384d3 bellard
    }
265 ea2384d3 bellard
    cow_header.sectorsize = cpu_to_be32(512);
266 ea2384d3 bellard
    cow_header.size = cpu_to_be64(image_sectors * 512);
267 31f38120 Kirill A. Shutemov
    ret = qemu_write_full(cow_fd, &cow_header, sizeof(cow_header));
268 31f38120 Kirill A. Shutemov
    if (ret != sizeof(cow_header)) {
269 48b66db9 Juan Quintela
        ret = -errno;
270 31f38120 Kirill A. Shutemov
        goto exit;
271 31f38120 Kirill A. Shutemov
    }
272 31f38120 Kirill A. Shutemov
273 ea2384d3 bellard
    /* resize to include at least all the bitmap */
274 31f38120 Kirill A. Shutemov
    ret = ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
275 31f38120 Kirill A. Shutemov
    if (ret) {
276 31f38120 Kirill A. Shutemov
        ret = -errno;
277 31f38120 Kirill A. Shutemov
        goto exit;
278 31f38120 Kirill A. Shutemov
    }
279 31f38120 Kirill A. Shutemov
280 31f38120 Kirill A. Shutemov
exit:
281 ea2384d3 bellard
    close(cow_fd);
282 31f38120 Kirill A. Shutemov
    return ret;
283 ea2384d3 bellard
}
284 ea2384d3 bellard
285 205ef796 Kevin Wolf
static int cow_flush(BlockDriverState *bs)
286 7a6cba61 pbrook
{
287 205ef796 Kevin Wolf
    return bdrv_flush(bs->file);
288 7a6cba61 pbrook
}
289 7a6cba61 pbrook
290 0e7e1989 Kevin Wolf
static QEMUOptionParameter cow_create_options[] = {
291 db08adf5 Kevin Wolf
    {
292 db08adf5 Kevin Wolf
        .name = BLOCK_OPT_SIZE,
293 db08adf5 Kevin Wolf
        .type = OPT_SIZE,
294 db08adf5 Kevin Wolf
        .help = "Virtual disk size"
295 db08adf5 Kevin Wolf
    },
296 db08adf5 Kevin Wolf
    {
297 db08adf5 Kevin Wolf
        .name = BLOCK_OPT_BACKING_FILE,
298 db08adf5 Kevin Wolf
        .type = OPT_STRING,
299 db08adf5 Kevin Wolf
        .help = "File name of a base image"
300 db08adf5 Kevin Wolf
    },
301 0e7e1989 Kevin Wolf
    { NULL }
302 0e7e1989 Kevin Wolf
};
303 0e7e1989 Kevin Wolf
304 5efa9d5a Anthony Liguori
static BlockDriver bdrv_cow = {
305 e60f469c aurel32
    .format_name        = "cow",
306 e60f469c aurel32
    .instance_size        = sizeof(BDRVCowState),
307 e60f469c aurel32
    .bdrv_probe                = cow_probe,
308 2063392a Christoph Hellwig
    .bdrv_open                = cow_open,
309 e60f469c aurel32
    .bdrv_read                = cow_read,
310 e60f469c aurel32
    .bdrv_write                = cow_write,
311 e60f469c aurel32
    .bdrv_close                = cow_close,
312 e60f469c aurel32
    .bdrv_create        = cow_create,
313 e60f469c aurel32
    .bdrv_flush                = cow_flush,
314 e60f469c aurel32
    .bdrv_is_allocated        = cow_is_allocated,
315 0e7e1989 Kevin Wolf
316 0e7e1989 Kevin Wolf
    .create_options = cow_create_options,
317 ea2384d3 bellard
};
318 5efa9d5a Anthony Liguori
319 5efa9d5a Anthony Liguori
static void bdrv_cow_init(void)
320 5efa9d5a Anthony Liguori
{
321 5efa9d5a Anthony Liguori
    bdrv_register(&bdrv_cow);
322 5efa9d5a Anthony Liguori
}
323 5efa9d5a Anthony Liguori
324 5efa9d5a Anthony Liguori
block_init(bdrv_cow_init);