raid5-ppl.c (4536bf9ba2d03404655586b07f8830b6f2106242) raid5-ppl.c (6358c239d88c751a9f14152a8d4ad2b69f5be48f)
1/*
2 * Partial Parity Log for closing the RAID5 write hole
3 * Copyright (c) 2017, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *

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

395{
396 struct ppl_log *log = io->log;
397 struct ppl_conf *ppl_conf = log->ppl_conf;
398 struct ppl_header *pplhdr = page_address(io->header_page);
399 struct bio *bio = &io->bio;
400 struct stripe_head *sh;
401 int i;
402
1/*
2 * Partial Parity Log for closing the RAID5 write hole
3 * Copyright (c) 2017, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *

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

395{
396 struct ppl_log *log = io->log;
397 struct ppl_conf *ppl_conf = log->ppl_conf;
398 struct ppl_header *pplhdr = page_address(io->header_page);
399 struct bio *bio = &io->bio;
400 struct stripe_head *sh;
401 int i;
402
403 bio->bi_private = io;
404
405 if (!log->rdev || test_bit(Faulty, &log->rdev->flags)) {
406 ppl_log_endio(bio);
407 return;
408 }
409
403 for (i = 0; i < io->entries_count; i++) {
404 struct ppl_header_entry *e = &pplhdr->entries[i];
405
406 pr_debug("%s: seq: %llu entry: %d data_sector: %llu pp_size: %u data_size: %u\n",
407 __func__, io->seq, i, le64_to_cpu(e->data_sector),
408 le32_to_cpu(e->pp_size), le32_to_cpu(e->data_size));
409
410 e->data_sector = cpu_to_le64(le64_to_cpu(e->data_sector) >>
411 ilog2(ppl_conf->block_size >> 9));
412 e->checksum = cpu_to_le32(~le32_to_cpu(e->checksum));
413 }
414
415 pplhdr->entries_count = cpu_to_le32(io->entries_count);
416 pplhdr->checksum = cpu_to_le32(~crc32c_le(~0, pplhdr, PPL_HEADER_SIZE));
417
410 for (i = 0; i < io->entries_count; i++) {
411 struct ppl_header_entry *e = &pplhdr->entries[i];
412
413 pr_debug("%s: seq: %llu entry: %d data_sector: %llu pp_size: %u data_size: %u\n",
414 __func__, io->seq, i, le64_to_cpu(e->data_sector),
415 le32_to_cpu(e->pp_size), le32_to_cpu(e->data_size));
416
417 e->data_sector = cpu_to_le64(le64_to_cpu(e->data_sector) >>
418 ilog2(ppl_conf->block_size >> 9));
419 e->checksum = cpu_to_le32(~le32_to_cpu(e->checksum));
420 }
421
422 pplhdr->entries_count = cpu_to_le32(io->entries_count);
423 pplhdr->checksum = cpu_to_le32(~crc32c_le(~0, pplhdr, PPL_HEADER_SIZE));
424
418 bio->bi_private = io;
419 bio->bi_end_io = ppl_log_endio;
420 bio->bi_opf = REQ_OP_WRITE | REQ_FUA;
421 bio->bi_bdev = log->rdev->bdev;
422 bio->bi_iter.bi_sector = log->rdev->ppl.sector;
423 bio_add_page(bio, io->header_page, PAGE_SIZE, 0);
424
425 list_for_each_entry(sh, &io->stripe_list, log_list) {
426 /* entries for full stripe writes have no partial parity */

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

1185
1186 conf->log_private = ppl_conf;
1187
1188 return 0;
1189err:
1190 __ppl_exit_log(ppl_conf);
1191 return ret;
1192}
425 bio->bi_end_io = ppl_log_endio;
426 bio->bi_opf = REQ_OP_WRITE | REQ_FUA;
427 bio->bi_bdev = log->rdev->bdev;
428 bio->bi_iter.bi_sector = log->rdev->ppl.sector;
429 bio_add_page(bio, io->header_page, PAGE_SIZE, 0);
430
431 list_for_each_entry(sh, &io->stripe_list, log_list) {
432 /* entries for full stripe writes have no partial parity */

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

1191
1192 conf->log_private = ppl_conf;
1193
1194 return 0;
1195err:
1196 __ppl_exit_log(ppl_conf);
1197 return ret;
1198}
1199
1200int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add)
1201{
1202 struct ppl_conf *ppl_conf = conf->log_private;
1203 struct ppl_log *log;
1204 int ret = 0;
1205 char b[BDEVNAME_SIZE];
1206
1207 if (!rdev)
1208 return -EINVAL;
1209
1210 pr_debug("%s: disk: %d operation: %s dev: %s\n",
1211 __func__, rdev->raid_disk, add ? "add" : "remove",
1212 bdevname(rdev->bdev, b));
1213
1214 if (rdev->raid_disk < 0)
1215 return 0;
1216
1217 if (rdev->raid_disk >= ppl_conf->count)
1218 return -ENODEV;
1219
1220 log = &ppl_conf->child_logs[rdev->raid_disk];
1221
1222 mutex_lock(&log->io_mutex);
1223 if (add) {
1224 ret = ppl_validate_rdev(rdev);
1225 if (!ret) {
1226 log->rdev = rdev;
1227 ret = ppl_write_empty_header(log);
1228 }
1229 } else {
1230 log->rdev = NULL;
1231 }
1232 mutex_unlock(&log->io_mutex);
1233
1234 return ret;
1235}