Commit | Line | Data |
---|---|---|
a739ff3f ST |
1 | /* |
2 | * Copyright (C) 2015 Google, Inc. | |
3 | * | |
4 | * Author: Sami Tolvanen <samitolvanen@google.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the Free | |
8 | * Software Foundation; either version 2 of the License, or (at your option) | |
9 | * any later version. | |
10 | */ | |
11 | ||
12 | #ifndef DM_VERITY_FEC_H | |
13 | #define DM_VERITY_FEC_H | |
14 | ||
15 | #include "dm-verity.h" | |
16 | #include <linux/rslib.h> | |
17 | ||
18 | /* Reed-Solomon(M, N) parameters */ | |
19 | #define DM_VERITY_FEC_RSM 255 | |
20 | #define DM_VERITY_FEC_MAX_RSN 253 | |
21 | #define DM_VERITY_FEC_MIN_RSN 231 /* ~10% space overhead */ | |
22 | ||
23 | /* buffers for deinterleaving and decoding */ | |
24 | #define DM_VERITY_FEC_BUF_PREALLOC 1 /* buffers to preallocate */ | |
25 | #define DM_VERITY_FEC_BUF_RS_BITS 4 /* 1 << RS blocks per buffer */ | |
26 | /* we need buffers for at most 1 << block size RS blocks */ | |
27 | #define DM_VERITY_FEC_BUF_MAX \ | |
28 | (1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS)) | |
29 | ||
f1a880a9 ST |
30 | /* maximum recursion level for verity_fec_decode */ |
31 | #define DM_VERITY_FEC_MAX_RECURSION 4 | |
32 | ||
a739ff3f ST |
33 | #define DM_VERITY_OPT_FEC_DEV "use_fec_from_device" |
34 | #define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks" | |
35 | #define DM_VERITY_OPT_FEC_START "fec_start" | |
36 | #define DM_VERITY_OPT_FEC_ROOTS "fec_roots" | |
37 | ||
38 | /* configuration */ | |
39 | struct dm_verity_fec { | |
40 | struct dm_dev *dev; /* parity data device */ | |
41 | struct dm_bufio_client *data_bufio; /* for data dev access */ | |
42 | struct dm_bufio_client *bufio; /* for parity data access */ | |
43 | sector_t start; /* parity data start in blocks */ | |
44 | sector_t blocks; /* number of blocks covered */ | |
45 | sector_t rounds; /* number of interleaving rounds */ | |
46 | sector_t hash_blocks; /* blocks covered after v->hash_start */ | |
47 | unsigned char roots; /* number of parity bytes, M-N of RS(M, N) */ | |
48 | unsigned char rsn; /* N of RS(M, N) */ | |
6f1c819c KO |
49 | mempool_t rs_pool; /* mempool for fio->rs */ |
50 | mempool_t prealloc_pool; /* mempool for preallocated buffers */ | |
51 | mempool_t extra_pool; /* mempool for extra buffers */ | |
52 | mempool_t output_pool; /* mempool for output */ | |
a739ff3f ST |
53 | struct kmem_cache *cache; /* cache for buffers */ |
54 | }; | |
55 | ||
56 | /* per-bio data */ | |
57 | struct dm_verity_fec_io { | |
58 | struct rs_control *rs; /* Reed-Solomon state */ | |
59 | int erasures[DM_VERITY_FEC_MAX_RSN]; /* erasures for decode_rs8 */ | |
60 | u8 *bufs[DM_VERITY_FEC_BUF_MAX]; /* bufs for deinterleaving */ | |
61 | unsigned nbufs; /* number of buffers allocated */ | |
62 | u8 *output; /* buffer for corrected output */ | |
63 | size_t output_pos; | |
f1a880a9 | 64 | unsigned level; /* recursion level */ |
a739ff3f ST |
65 | }; |
66 | ||
67 | #ifdef CONFIG_DM_VERITY_FEC | |
68 | ||
69 | /* each feature parameter requires a value */ | |
70 | #define DM_VERITY_OPTS_FEC 8 | |
71 | ||
72 | extern bool verity_fec_is_enabled(struct dm_verity *v); | |
73 | ||
74 | extern int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, | |
75 | enum verity_block_type type, sector_t block, | |
76 | u8 *dest, struct bvec_iter *iter); | |
77 | ||
78 | extern unsigned verity_fec_status_table(struct dm_verity *v, unsigned sz, | |
79 | char *result, unsigned maxlen); | |
80 | ||
81 | extern void verity_fec_finish_io(struct dm_verity_io *io); | |
82 | extern void verity_fec_init_io(struct dm_verity_io *io); | |
83 | ||
84 | extern bool verity_is_fec_opt_arg(const char *arg_name); | |
85 | extern int verity_fec_parse_opt_args(struct dm_arg_set *as, | |
86 | struct dm_verity *v, unsigned *argc, | |
87 | const char *arg_name); | |
88 | ||
89 | extern void verity_fec_dtr(struct dm_verity *v); | |
90 | ||
91 | extern int verity_fec_ctr_alloc(struct dm_verity *v); | |
92 | extern int verity_fec_ctr(struct dm_verity *v); | |
93 | ||
94 | #else /* !CONFIG_DM_VERITY_FEC */ | |
95 | ||
96 | #define DM_VERITY_OPTS_FEC 0 | |
97 | ||
98 | static inline bool verity_fec_is_enabled(struct dm_verity *v) | |
99 | { | |
100 | return false; | |
101 | } | |
102 | ||
103 | static inline int verity_fec_decode(struct dm_verity *v, | |
104 | struct dm_verity_io *io, | |
105 | enum verity_block_type type, | |
106 | sector_t block, u8 *dest, | |
107 | struct bvec_iter *iter) | |
108 | { | |
109 | return -EOPNOTSUPP; | |
110 | } | |
111 | ||
112 | static inline unsigned verity_fec_status_table(struct dm_verity *v, | |
113 | unsigned sz, char *result, | |
114 | unsigned maxlen) | |
115 | { | |
116 | return sz; | |
117 | } | |
118 | ||
119 | static inline void verity_fec_finish_io(struct dm_verity_io *io) | |
120 | { | |
121 | } | |
122 | ||
123 | static inline void verity_fec_init_io(struct dm_verity_io *io) | |
124 | { | |
125 | } | |
126 | ||
127 | static inline bool verity_is_fec_opt_arg(const char *arg_name) | |
128 | { | |
129 | return false; | |
130 | } | |
131 | ||
132 | static inline int verity_fec_parse_opt_args(struct dm_arg_set *as, | |
133 | struct dm_verity *v, | |
134 | unsigned *argc, | |
135 | const char *arg_name) | |
136 | { | |
137 | return -EINVAL; | |
138 | } | |
139 | ||
140 | static inline void verity_fec_dtr(struct dm_verity *v) | |
141 | { | |
142 | } | |
143 | ||
144 | static inline int verity_fec_ctr_alloc(struct dm_verity *v) | |
145 | { | |
146 | return 0; | |
147 | } | |
148 | ||
149 | static inline int verity_fec_ctr(struct dm_verity *v) | |
150 | { | |
151 | return 0; | |
152 | } | |
153 | ||
154 | #endif /* CONFIG_DM_VERITY_FEC */ | |
155 | ||
156 | #endif /* DM_VERITY_FEC_H */ |