Deleted Added
full compact
tr_raid5.c (234458) tr_raid5.c (234993)
1/*-
2 * Copyright (c) 2012 Alexander Motin <mav@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2012 Alexander Motin <mav@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/geom/raid/tr_raid5.c 234458 2012-04-19 12:30:12Z mav $");
28__FBSDID("$FreeBSD: head/sys/geom/raid/tr_raid5.c 234993 2012-05-04 07:32:57Z mav $");
29
30#include <sys/param.h>
31#include <sys/bio.h>
32#include <sys/endian.h>
33#include <sys/kernel.h>
34#include <sys/kobj.h>
35#include <sys/limits.h>
36#include <sys/lock.h>

--- 64 unchanged lines hidden (view full) ---

101static int
102g_raid_tr_taste_raid5(struct g_raid_tr_object *tr, struct g_raid_volume *vol)
103{
104 struct g_raid_tr_raid5_object *trs;
105 u_int qual;
106
107 trs = (struct g_raid_tr_raid5_object *)tr;
108 qual = tr->tro_volume->v_raid_level_qualifier;
29
30#include <sys/param.h>
31#include <sys/bio.h>
32#include <sys/endian.h>
33#include <sys/kernel.h>
34#include <sys/kobj.h>
35#include <sys/limits.h>
36#include <sys/lock.h>

--- 64 unchanged lines hidden (view full) ---

101static int
102g_raid_tr_taste_raid5(struct g_raid_tr_object *tr, struct g_raid_volume *vol)
103{
104 struct g_raid_tr_raid5_object *trs;
105 u_int qual;
106
107 trs = (struct g_raid_tr_raid5_object *)tr;
108 qual = tr->tro_volume->v_raid_level_qualifier;
109 if (tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5 &&
109 if (tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID4 &&
110 qual >= 0 && qual <= 1) {
111 /* RAID4 */
112 } else if ((tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5 ||
113 tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5E ||
114 tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID5EE ||
115 tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAID6 ||
116 tr->tro_volume->v_raid_level == G_RAID_VOLUME_RL_RAIDMDF) &&
110 qual >= 0 && qual <= 3) {
117 qual >= 0 && qual <= 3) {
111 /* RAID5 */
118 /* RAID5/5E/5EE/6/MDF */
112 } else
113 return (G_RAID_TR_TASTE_FAIL);
114 trs->trso_starting = 1;
115 return (G_RAID_TR_TASTE_SUCCEED);
116}
117
118static int
119g_raid_tr_update_state_raid5(struct g_raid_volume *vol,

--- 78 unchanged lines hidden (view full) ---

198g_raid_tr_iostart_raid5_read(struct g_raid_tr_object *tr, struct bio *bp)
199{
200 struct g_raid_volume *vol;
201 struct g_raid_subdisk *sd;
202 struct bio_queue_head queue;
203 struct bio *cbp;
204 char *addr;
205 off_t offset, start, length, nstripe, remain;
119 } else
120 return (G_RAID_TR_TASTE_FAIL);
121 trs->trso_starting = 1;
122 return (G_RAID_TR_TASTE_SUCCEED);
123}
124
125static int
126g_raid_tr_update_state_raid5(struct g_raid_volume *vol,

--- 78 unchanged lines hidden (view full) ---

205g_raid_tr_iostart_raid5_read(struct g_raid_tr_object *tr, struct bio *bp)
206{
207 struct g_raid_volume *vol;
208 struct g_raid_subdisk *sd;
209 struct bio_queue_head queue;
210 struct bio *cbp;
211 char *addr;
212 off_t offset, start, length, nstripe, remain;
206 int no, pno;
207 u_int strip_size, qual;
213 int no, pno, ddisks, pdisks;
214 u_int strip_size, lvl, qual;
208
209 vol = tr->tro_volume;
210 addr = bp->bio_data;
211 strip_size = vol->v_strip_size;
215
216 vol = tr->tro_volume;
217 addr = bp->bio_data;
218 strip_size = vol->v_strip_size;
219 lvl = tr->tro_volume->v_raid_level;
212 qual = tr->tro_volume->v_raid_level_qualifier;
213
214 /* Stripe number. */
215 nstripe = bp->bio_offset / strip_size;
216 /* Start position in stripe. */
217 start = bp->bio_offset % strip_size;
220 qual = tr->tro_volume->v_raid_level_qualifier;
221
222 /* Stripe number. */
223 nstripe = bp->bio_offset / strip_size;
224 /* Start position in stripe. */
225 start = bp->bio_offset % strip_size;
226 /* Number of data and parity disks. */
227 if (lvl == G_RAID_VOLUME_RL_RAIDMDF)
228 pdisks = 3;
229 else if (lvl == G_RAID_VOLUME_RL_RAID5EE ||
230 lvl == G_RAID_VOLUME_RL_RAID6)
231 pdisks = 2;
232 else
233 pdisks = 1;
234 ddisks = vol->v_disks_count - pdisks;
218 /* Parity disk number. */
235 /* Parity disk number. */
219 pno = nstripe / (vol->v_disks_count - 1) % vol->v_disks_count;
220 if (qual >= 2)
221 pno = (vol->v_disks_count - 1) - pno;
222 /* Disk number. */
223 no = nstripe % (vol->v_disks_count - 1);
224 if (qual & 1) {
225 no = (pno + no + 1) % vol->v_disks_count;
226 } else if (no >= pno)
227 no++;
236 if (lvl == G_RAID_VOLUME_RL_RAID4) {
237 if (qual == 0) /* P0 */
238 pno = 0;
239 else /* PN */
240 pno = ddisks;
241 } else {
242 pno = (nstripe / ddisks) % vol->v_disks_count;
243 if (qual >= 2) { /* PN/Left */
244 pno = ddisks - pno;
245 if (pno < 0)
246 pno += vol->v_disks_count;
247 }
248 }
249 /* Data disk number. */
250 no = nstripe % ddisks;
251 if (lvl == G_RAID_VOLUME_RL_RAID4) {
252 if (qual == 0)
253 no += pdisks;
254 } else if (qual & 1) { /* Continuation/Symmetric */
255 no = (pno + pdisks + no) % vol->v_disks_count;
256 } else if (no >= pno) /* Restart/Asymmetric */
257 no += pdisks;
258 else
259 no += imax(0, pno + pdisks - vol->v_disks_count);
228 /* Stripe start position in disk. */
260 /* Stripe start position in disk. */
229 offset = (nstripe / (vol->v_disks_count - 1)) * strip_size;
261 offset = (nstripe / ddisks) * strip_size;
230 /* Length of data to operate. */
231 remain = bp->bio_length;
232
233 bioq_init(&queue);
234 do {
235 length = MIN(strip_size - start, remain);
236 cbp = g_clone_bio(bp);
237 if (cbp == NULL)
238 goto failure;
239 cbp->bio_offset = offset + start;
240 cbp->bio_data = addr;
241 cbp->bio_length = length;
242 cbp->bio_caller1 = &vol->v_subdisks[no];
243 bioq_insert_tail(&queue, cbp);
244 no++;
262 /* Length of data to operate. */
263 remain = bp->bio_length;
264
265 bioq_init(&queue);
266 do {
267 length = MIN(strip_size - start, remain);
268 cbp = g_clone_bio(bp);
269 if (cbp == NULL)
270 goto failure;
271 cbp->bio_offset = offset + start;
272 cbp->bio_data = addr;
273 cbp->bio_length = length;
274 cbp->bio_caller1 = &vol->v_subdisks[no];
275 bioq_insert_tail(&queue, cbp);
276 no++;
245 if (qual & 1) {
277 if (lvl == G_RAID_VOLUME_RL_RAID4) {
246 no %= vol->v_disks_count;
278 no %= vol->v_disks_count;
279 if (no == pno)
280 no = (no + pdisks) % vol->v_disks_count;
281 } else if (qual & 1) { /* Continuation/Symmetric */
282 no %= vol->v_disks_count;
247 if (no == pno) {
283 if (no == pno) {
248 if (qual < 2) {
249 pno = (pno + 1) % vol->v_disks_count;
250 no = (no + 2) % vol->v_disks_count;
251 } else if (pno == 0)
252 pno = vol->v_disks_count - 1;
253 else
254 pno--;
284 if (qual < 2) /* P0/Right */
285 pno++;
286 else /* PN/Left */
287 pno += vol->v_disks_count - 1;
288 pno %= vol->v_disks_count;
289 no = (pno + pdisks) % vol->v_disks_count;
255 offset += strip_size;
256 }
290 offset += strip_size;
291 }
257 } else {
292 } else { /* Restart/Asymmetric */
258 if (no == pno)
293 if (no == pno)
259 no++;
294 no += pdisks;
260 if (no >= vol->v_disks_count) {
295 if (no >= vol->v_disks_count) {
261 no %= vol->v_disks_count;
262 if (qual < 2)
263 pno = (pno + 1) % vol->v_disks_count;
264 else if (pno == 0)
265 pno = vol->v_disks_count - 1;
296 no -= vol->v_disks_count;
297 if (qual < 2) /* P0/Right */
298 pno++;
299 else /* PN/Left */
300 pno += vol->v_disks_count - 1;
301 pno %= vol->v_disks_count;
302 if (no == pno)
303 no += pdisks;
266 else
304 else
267 pno--;
305 no += imax(0, pno + pdisks - vol->v_disks_count);
268 offset += strip_size;
269 }
306 offset += strip_size;
307 }
270 if (no == pno)
271 no++;
272 }
273 remain -= length;
274 addr += length;
275 start = 0;
276 } while (remain > 0);
277 for (cbp = bioq_first(&queue); cbp != NULL;
278 cbp = bioq_first(&queue)) {
279 bioq_remove(&queue, cbp);

--- 97 unchanged lines hidden ---
308 }
309 remain -= length;
310 addr += length;
311 start = 0;
312 } while (remain > 0);
313 for (cbp = bioq_first(&queue); cbp != NULL;
314 cbp = bioq_first(&queue)) {
315 bioq_remove(&queue, cbp);

--- 97 unchanged lines hidden ---