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