mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:24:47 +01:00
verity_fec_is_enabled() is very short and is called in quite a few places, so make it an inline function. Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Signed-off-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
166 lines
4.6 KiB
C
166 lines
4.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Copyright (C) 2015 Google, Inc.
|
|
*
|
|
* Author: Sami Tolvanen <samitolvanen@google.com>
|
|
*/
|
|
|
|
#ifndef DM_VERITY_FEC_H
|
|
#define DM_VERITY_FEC_H
|
|
|
|
#include "dm-verity.h"
|
|
#include <linux/rslib.h>
|
|
|
|
/* Reed-Solomon(M, N) parameters */
|
|
#define DM_VERITY_FEC_RSM 255
|
|
#define DM_VERITY_FEC_MAX_RSN 253
|
|
#define DM_VERITY_FEC_MIN_RSN 231 /* ~10% space overhead */
|
|
|
|
/* buffers for deinterleaving and decoding */
|
|
#define DM_VERITY_FEC_BUF_RS_BITS 4 /* 1 << RS blocks per buffer */
|
|
|
|
#define DM_VERITY_OPT_FEC_DEV "use_fec_from_device"
|
|
#define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks"
|
|
#define DM_VERITY_OPT_FEC_START "fec_start"
|
|
#define DM_VERITY_OPT_FEC_ROOTS "fec_roots"
|
|
|
|
/* configuration */
|
|
struct dm_verity_fec {
|
|
struct dm_dev *dev; /* parity data device */
|
|
struct dm_bufio_client *data_bufio; /* for data dev access */
|
|
struct dm_bufio_client *bufio; /* for parity data access */
|
|
size_t io_size; /* IO size for roots */
|
|
sector_t start; /* parity data start in blocks */
|
|
sector_t blocks; /* number of blocks covered */
|
|
sector_t rounds; /* number of interleaving rounds */
|
|
sector_t hash_blocks; /* blocks covered after v->hash_start */
|
|
unsigned char roots; /* number of parity bytes, M-N of RS(M, N) */
|
|
unsigned char rsn; /* N of RS(M, N) */
|
|
mempool_t fio_pool; /* mempool for dm_verity_fec_io */
|
|
mempool_t rs_pool; /* mempool for fio->rs */
|
|
mempool_t prealloc_pool; /* mempool for preallocated buffers */
|
|
mempool_t output_pool; /* mempool for output */
|
|
struct kmem_cache *cache; /* cache for buffers */
|
|
atomic64_t corrected; /* corrected errors */
|
|
};
|
|
|
|
/* per-bio data */
|
|
struct dm_verity_fec_io {
|
|
struct rs_control *rs; /* Reed-Solomon state */
|
|
int erasures[DM_VERITY_FEC_MAX_RSN]; /* erasures for decode_rs8 */
|
|
u8 *output; /* buffer for corrected output */
|
|
unsigned int level; /* recursion level */
|
|
unsigned int nbufs; /* number of buffers allocated */
|
|
/*
|
|
* Buffers for deinterleaving RS blocks. Each buffer has space for
|
|
* the data bytes of (1 << DM_VERITY_FEC_BUF_RS_BITS) RS blocks. The
|
|
* array length is fec_max_nbufs(v), and we try to allocate that many
|
|
* buffers. However, in low-memory situations we may be unable to
|
|
* allocate all buffers. 'nbufs' holds the number actually allocated.
|
|
*/
|
|
u8 *bufs[];
|
|
};
|
|
|
|
#ifdef CONFIG_DM_VERITY_FEC
|
|
|
|
/* each feature parameter requires a value */
|
|
#define DM_VERITY_OPTS_FEC 8
|
|
|
|
/* Returns true if forward error correction is enabled. */
|
|
static inline bool verity_fec_is_enabled(struct dm_verity *v)
|
|
{
|
|
return v->fec && v->fec->dev;
|
|
}
|
|
|
|
extern int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io,
|
|
enum verity_block_type type, const u8 *want_digest,
|
|
sector_t block, u8 *dest);
|
|
|
|
extern unsigned int verity_fec_status_table(struct dm_verity *v, unsigned int sz,
|
|
char *result, unsigned int maxlen);
|
|
|
|
extern void __verity_fec_finish_io(struct dm_verity_io *io);
|
|
static inline void verity_fec_finish_io(struct dm_verity_io *io)
|
|
{
|
|
if (unlikely(io->fec_io))
|
|
__verity_fec_finish_io(io);
|
|
}
|
|
|
|
static inline void verity_fec_init_io(struct dm_verity_io *io)
|
|
{
|
|
io->fec_io = NULL;
|
|
}
|
|
|
|
extern bool verity_is_fec_opt_arg(const char *arg_name);
|
|
extern int verity_fec_parse_opt_args(struct dm_arg_set *as,
|
|
struct dm_verity *v, unsigned int *argc,
|
|
const char *arg_name);
|
|
|
|
extern void verity_fec_dtr(struct dm_verity *v);
|
|
|
|
extern int verity_fec_ctr_alloc(struct dm_verity *v);
|
|
extern int verity_fec_ctr(struct dm_verity *v);
|
|
|
|
#else /* !CONFIG_DM_VERITY_FEC */
|
|
|
|
#define DM_VERITY_OPTS_FEC 0
|
|
|
|
static inline bool verity_fec_is_enabled(struct dm_verity *v)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline int verity_fec_decode(struct dm_verity *v,
|
|
struct dm_verity_io *io,
|
|
enum verity_block_type type,
|
|
const u8 *want_digest,
|
|
sector_t block, u8 *dest)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline unsigned int verity_fec_status_table(struct dm_verity *v,
|
|
unsigned int sz, char *result,
|
|
unsigned int maxlen)
|
|
{
|
|
return sz;
|
|
}
|
|
|
|
static inline void verity_fec_finish_io(struct dm_verity_io *io)
|
|
{
|
|
}
|
|
|
|
static inline void verity_fec_init_io(struct dm_verity_io *io)
|
|
{
|
|
}
|
|
|
|
static inline bool verity_is_fec_opt_arg(const char *arg_name)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline int verity_fec_parse_opt_args(struct dm_arg_set *as,
|
|
struct dm_verity *v,
|
|
unsigned int *argc,
|
|
const char *arg_name)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline void verity_fec_dtr(struct dm_verity *v)
|
|
{
|
|
}
|
|
|
|
static inline int verity_fec_ctr_alloc(struct dm_verity *v)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int verity_fec_ctr(struct dm_verity *v)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif /* CONFIG_DM_VERITY_FEC */
|
|
|
|
#endif /* DM_VERITY_FEC_H */
|