qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

filter-compress.c (4941B)


      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_int.h"
     26 #include "qemu/module.h"
     27 #include "qapi/error.h"
     28 
     29 
     30 static int compress_open(BlockDriverState *bs, QDict *options, int flags,
     31                          Error **errp)
     32 {
     33     int ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
     34     if (ret < 0) {
     35         return ret;
     36     }
     37 
     38     if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) {
     39         error_setg(errp,
     40                    "Compression is not supported for underlying format: %s",
     41                    bdrv_get_format_name(bs->file->bs) ?: "(no format)");
     42 
     43         return -ENOTSUP;
     44     }
     45 
     46     bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
     47         (BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
     48 
     49     bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
     50         ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
     51             bs->file->bs->supported_zero_flags);
     52 
     53     return 0;
     54 }
     55 
     56 
     57 static int64_t compress_getlength(BlockDriverState *bs)
     58 {
     59     return bdrv_getlength(bs->file->bs);
     60 }
     61 
     62 
     63 static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs,
     64                                                 int64_t offset, int64_t bytes,
     65                                                 QEMUIOVector *qiov,
     66                                                 size_t qiov_offset,
     67                                                 BdrvRequestFlags flags)
     68 {
     69     return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
     70                                flags);
     71 }
     72 
     73 
     74 static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs,
     75                                                  int64_t offset,
     76                                                  int64_t bytes,
     77                                                  QEMUIOVector *qiov,
     78                                                  size_t qiov_offset,
     79                                                  BdrvRequestFlags flags)
     80 {
     81     return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
     82                                 flags | BDRV_REQ_WRITE_COMPRESSED);
     83 }
     84 
     85 
     86 static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs,
     87                                                   int64_t offset, int64_t bytes,
     88                                                   BdrvRequestFlags flags)
     89 {
     90     return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
     91 }
     92 
     93 
     94 static int coroutine_fn compress_co_pdiscard(BlockDriverState *bs,
     95                                              int64_t offset, int64_t bytes)
     96 {
     97     return bdrv_co_pdiscard(bs->file, offset, bytes);
     98 }
     99 
    100 
    101 static void compress_refresh_limits(BlockDriverState *bs, Error **errp)
    102 {
    103     BlockDriverInfo bdi;
    104     int ret;
    105 
    106     if (!bs->file) {
    107         return;
    108     }
    109 
    110     ret = bdrv_get_info(bs->file->bs, &bdi);
    111     if (ret < 0 || bdi.cluster_size == 0) {
    112         return;
    113     }
    114 
    115     bs->bl.request_alignment = bdi.cluster_size;
    116 }
    117 
    118 
    119 static void compress_eject(BlockDriverState *bs, bool eject_flag)
    120 {
    121     bdrv_eject(bs->file->bs, eject_flag);
    122 }
    123 
    124 
    125 static void compress_lock_medium(BlockDriverState *bs, bool locked)
    126 {
    127     bdrv_lock_medium(bs->file->bs, locked);
    128 }
    129 
    130 
    131 static BlockDriver bdrv_compress = {
    132     .format_name                        = "compress",
    133 
    134     .bdrv_open                          = compress_open,
    135     .bdrv_child_perm                    = bdrv_default_perms,
    136 
    137     .bdrv_getlength                     = compress_getlength,
    138 
    139     .bdrv_co_preadv_part                = compress_co_preadv_part,
    140     .bdrv_co_pwritev_part               = compress_co_pwritev_part,
    141     .bdrv_co_pwrite_zeroes              = compress_co_pwrite_zeroes,
    142     .bdrv_co_pdiscard                   = compress_co_pdiscard,
    143     .bdrv_refresh_limits                = compress_refresh_limits,
    144 
    145     .bdrv_eject                         = compress_eject,
    146     .bdrv_lock_medium                   = compress_lock_medium,
    147 
    148     .has_variable_length                = true,
    149     .is_filter                          = true,
    150 };
    151 
    152 static void bdrv_compress_init(void)
    153 {
    154     bdrv_register(&bdrv_compress);
    155 }
    156 
    157 block_init(bdrv_compress_init);