qemu

Форк
0
/
filter-compress.c 
160 строк · 4.6 Кб
1
/*
2
 * Compress filter block driver
3
 *
4
 * Copyright (c) 2019 Virtuozzo International GmbH
5
 *
6
 * Author:
7
 *   Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
8
 *   (based on block/copy-on-read.c by Max Reitz)
9
 *
10
 * This program is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU General Public License as
12
 * published by the Free Software Foundation; either version 2 or
13
 * (at your option) any later version of the License.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22
 */
23

24
#include "qemu/osdep.h"
25
#include "block/block-io.h"
26
#include "block/block_int.h"
27
#include "qemu/module.h"
28
#include "qapi/error.h"
29

30

31
static int compress_open(BlockDriverState *bs, QDict *options, int flags,
32
                         Error **errp)
33
{
34
    int ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
35
    if (ret < 0) {
36
        return ret;
37
    }
38

39
    GRAPH_RDLOCK_GUARD_MAINLOOP();
40

41
    if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) {
42
        error_setg(errp,
43
                   "Compression is not supported for underlying format: %s",
44
                   bdrv_get_format_name(bs->file->bs) ?: "(no format)");
45

46
        return -ENOTSUP;
47
    }
48

49
    bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
50
        (BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
51

52
    bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
53
        ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
54
            bs->file->bs->supported_zero_flags);
55

56
    return 0;
57
}
58

59

60
static int64_t coroutine_fn GRAPH_RDLOCK
61
compress_co_getlength(BlockDriverState *bs)
62
{
63
    return bdrv_co_getlength(bs->file->bs);
64
}
65

66

67
static int coroutine_fn GRAPH_RDLOCK
68
compress_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
69
                        QEMUIOVector *qiov, size_t qiov_offset,
70
                        BdrvRequestFlags flags)
71
{
72
    return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
73
                               flags);
74
}
75

76

77
static int coroutine_fn GRAPH_RDLOCK
78
compress_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
79
                         QEMUIOVector *qiov, size_t qiov_offset,
80
                         BdrvRequestFlags flags)
81
{
82
    return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
83
                                flags | BDRV_REQ_WRITE_COMPRESSED);
84
}
85

86

87
static int coroutine_fn GRAPH_RDLOCK
88
compress_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
89
                          BdrvRequestFlags flags)
90
{
91
    return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
92
}
93

94

95
static int coroutine_fn GRAPH_RDLOCK
96
compress_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
97
{
98
    return bdrv_co_pdiscard(bs->file, offset, bytes);
99
}
100

101

102
static void GRAPH_RDLOCK
103
compress_refresh_limits(BlockDriverState *bs, Error **errp)
104
{
105
    BlockDriverInfo bdi;
106
    int ret;
107

108
    if (!bs->file) {
109
        return;
110
    }
111

112
    ret = bdrv_get_info(bs->file->bs, &bdi);
113
    if (ret < 0 || bdi.cluster_size == 0) {
114
        return;
115
    }
116

117
    bs->bl.request_alignment = bdi.cluster_size;
118
}
119

120

121
static void coroutine_fn GRAPH_RDLOCK
122
compress_co_eject(BlockDriverState *bs, bool eject_flag)
123
{
124
    bdrv_co_eject(bs->file->bs, eject_flag);
125
}
126

127

128
static void coroutine_fn GRAPH_RDLOCK
129
compress_co_lock_medium(BlockDriverState *bs, bool locked)
130
{
131
    bdrv_co_lock_medium(bs->file->bs, locked);
132
}
133

134

135
static BlockDriver bdrv_compress = {
136
    .format_name                        = "compress",
137

138
    .bdrv_open                          = compress_open,
139
    .bdrv_child_perm                    = bdrv_default_perms,
140

141
    .bdrv_co_getlength                  = compress_co_getlength,
142

143
    .bdrv_co_preadv_part                = compress_co_preadv_part,
144
    .bdrv_co_pwritev_part               = compress_co_pwritev_part,
145
    .bdrv_co_pwrite_zeroes              = compress_co_pwrite_zeroes,
146
    .bdrv_co_pdiscard                   = compress_co_pdiscard,
147
    .bdrv_refresh_limits                = compress_refresh_limits,
148

149
    .bdrv_co_eject                      = compress_co_eject,
150
    .bdrv_co_lock_medium                = compress_co_lock_medium,
151

152
    .is_filter                          = true,
153
};
154

155
static void bdrv_compress_init(void)
156
{
157
    bdrv_register(&bdrv_compress);
158
}
159

160
block_init(bdrv_compress_init);
161

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.