~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to block/cloop.c

  • Committer: Bazaar Package Importer
  • Author(s): Riku Voipio, Josh Triplett, Riku Voipio
  • Date: 2009-07-29 13:28:05 UTC
  • mfrom: (1.4.1 upstream)
  • mto: (12.1.1 sid) (10.1.13 sid)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20090729132805-cau7rfexh7dawyb8
Tags: 0.10.50+git20090729-1
[ Josh Triplett ]
* Remove myself from Uploaders.

[ Riku Voipio ]
* new upstream RC version
* nuke all linux-user patches (applied upstream)
  06_exit_segfault
  12_signal_powerpc_support
  21_net_soopts
  30_syscall_ipc
  32_syscall_sysctl
  35_syscall_sockaddr
  48_signal_terminate
  55_unmux_socketcall
* nuke all other applied-upstream patches
  01_nostrip (better version upstream)
  07_i386_exec_name (can be reintroduced in debian/rules)
  50_linuxbios_isa_bios_ram (shouldn't be needed anymore)
  51_linuxbios_piix_ram_size (applied)
  56_dhcp (crap)
  60_ppc_ld (reintroduce if needed)
  64_ppc_asm_constraints (ditto)
  66_tls_ld.patch (ditto)
  81_compile_dtb.patch (applied upstream)
  82_qemu-img_decimal (ditto)
* move to git
* simplify build rules
* Correct my email address

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU Block driver for CLOOP images
 
3
 *
 
4
 * Copyright (c) 2004 Johannes E. Schindelin
 
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
#include <zlib.h>
 
28
 
 
29
typedef struct BDRVCloopState {
 
30
    int fd;
 
31
    uint32_t block_size;
 
32
    uint32_t n_blocks;
 
33
    uint64_t* offsets;
 
34
    uint32_t sectors_per_block;
 
35
    uint32_t current_block;
 
36
    uint8_t *compressed_block;
 
37
    uint8_t *uncompressed_block;
 
38
    z_stream zstream;
 
39
} BDRVCloopState;
 
40
 
 
41
static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
 
42
{
 
43
    const char* magic_version_2_0="#!/bin/sh\n"
 
44
        "#V2.0 Format\n"
 
45
        "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
 
46
    int length=strlen(magic_version_2_0);
 
47
    if(length>buf_size)
 
48
        length=buf_size;
 
49
    if(!memcmp(magic_version_2_0,buf,length))
 
50
        return 2;
 
51
    return 0;
 
52
}
 
53
 
 
54
static int cloop_open(BlockDriverState *bs, const char *filename, int flags)
 
55
{
 
56
    BDRVCloopState *s = bs->opaque;
 
57
    uint32_t offsets_size,max_compressed_block_size=1,i;
 
58
 
 
59
    s->fd = open(filename, O_RDONLY | O_BINARY);
 
60
    if (s->fd < 0)
 
61
        return -errno;
 
62
    bs->read_only = 1;
 
63
 
 
64
    /* read header */
 
65
    if(lseek(s->fd,128,SEEK_SET)<0) {
 
66
cloop_close:
 
67
        close(s->fd);
 
68
        return -1;
 
69
    }
 
70
    if(read(s->fd,&s->block_size,4)<4)
 
71
        goto cloop_close;
 
72
    s->block_size=be32_to_cpu(s->block_size);
 
73
    if(read(s->fd,&s->n_blocks,4)<4)
 
74
        goto cloop_close;
 
75
    s->n_blocks=be32_to_cpu(s->n_blocks);
 
76
 
 
77
    /* read offsets */
 
78
    offsets_size=s->n_blocks*sizeof(uint64_t);
 
79
    s->offsets=(uint64_t*)qemu_malloc(offsets_size);
 
80
    if(read(s->fd,s->offsets,offsets_size)<offsets_size)
 
81
        goto cloop_close;
 
82
    for(i=0;i<s->n_blocks;i++) {
 
83
        s->offsets[i]=be64_to_cpu(s->offsets[i]);
 
84
        if(i>0) {
 
85
            uint32_t size=s->offsets[i]-s->offsets[i-1];
 
86
            if(size>max_compressed_block_size)
 
87
                max_compressed_block_size=size;
 
88
        }
 
89
    }
 
90
 
 
91
    /* initialize zlib engine */
 
92
    s->compressed_block = qemu_malloc(max_compressed_block_size+1);
 
93
    s->uncompressed_block = qemu_malloc(s->block_size);
 
94
    if(inflateInit(&s->zstream) != Z_OK)
 
95
        goto cloop_close;
 
96
    s->current_block=s->n_blocks;
 
97
 
 
98
    s->sectors_per_block = s->block_size/512;
 
99
    bs->total_sectors = s->n_blocks*s->sectors_per_block;
 
100
    return 0;
 
101
}
 
102
 
 
103
static inline int cloop_read_block(BDRVCloopState *s,int block_num)
 
104
{
 
105
    if(s->current_block != block_num) {
 
106
        int ret;
 
107
        uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
 
108
 
 
109
        lseek(s->fd, s->offsets[block_num], SEEK_SET);
 
110
        ret = read(s->fd, s->compressed_block, bytes);
 
111
        if (ret != bytes)
 
112
            return -1;
 
113
 
 
114
        s->zstream.next_in = s->compressed_block;
 
115
        s->zstream.avail_in = bytes;
 
116
        s->zstream.next_out = s->uncompressed_block;
 
117
        s->zstream.avail_out = s->block_size;
 
118
        ret = inflateReset(&s->zstream);
 
119
        if(ret != Z_OK)
 
120
            return -1;
 
121
        ret = inflate(&s->zstream, Z_FINISH);
 
122
        if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
 
123
            return -1;
 
124
 
 
125
        s->current_block = block_num;
 
126
    }
 
127
    return 0;
 
128
}
 
129
 
 
130
static int cloop_read(BlockDriverState *bs, int64_t sector_num,
 
131
                    uint8_t *buf, int nb_sectors)
 
132
{
 
133
    BDRVCloopState *s = bs->opaque;
 
134
    int i;
 
135
 
 
136
    for(i=0;i<nb_sectors;i++) {
 
137
        uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block),
 
138
            block_num=(sector_num+i)/s->sectors_per_block;
 
139
        if(cloop_read_block(s, block_num) != 0)
 
140
            return -1;
 
141
        memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512);
 
142
    }
 
143
    return 0;
 
144
}
 
145
 
 
146
static void cloop_close(BlockDriverState *bs)
 
147
{
 
148
    BDRVCloopState *s = bs->opaque;
 
149
    close(s->fd);
 
150
    if(s->n_blocks>0)
 
151
        free(s->offsets);
 
152
    free(s->compressed_block);
 
153
    free(s->uncompressed_block);
 
154
    inflateEnd(&s->zstream);
 
155
}
 
156
 
 
157
static BlockDriver bdrv_cloop = {
 
158
    .format_name        = "cloop",
 
159
    .instance_size      = sizeof(BDRVCloopState),
 
160
    .bdrv_probe         = cloop_probe,
 
161
    .bdrv_open          = cloop_open,
 
162
    .bdrv_read          = cloop_read,
 
163
    .bdrv_close         = cloop_close,
 
164
};
 
165
 
 
166
static void bdrv_cloop_init(void)
 
167
{
 
168
    bdrv_register(&bdrv_cloop);
 
169
}
 
170
 
 
171
block_init(bdrv_cloop_init);