Deleted Added
full compact
g_raid3.c (133991) g_raid3.c (134124)
1/*-
2 * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@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) 2004 Pawel Jakub Dawidek <pjd@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/raid3/g_raid3.c 133991 2004-08-18 23:33:37Z pjd $");
28__FBSDID("$FreeBSD: head/sys/geom/raid3/g_raid3.c 134124 2004-08-21 18:11:46Z pjd $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/limits.h>
35#include <sys/lock.h>
36#include <sys/mutex.h>

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

867 }
868}
869
870static void
871g_raid3_gather(struct bio *pbp)
872{
873 struct g_raid3_softc *sc;
874 struct g_raid3_disk *disk;
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/limits.h>
35#include <sys/lock.h>
36#include <sys/mutex.h>

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

867 }
868}
869
870static void
871g_raid3_gather(struct bio *pbp)
872{
873 struct g_raid3_softc *sc;
874 struct g_raid3_disk *disk;
875 struct bio *bp, *cbp;
875 struct bio *xbp, *fbp, *cbp;
876 off_t atom, cadd, padd, left;
877
878 sc = pbp->bio_to->geom->softc;
876 off_t atom, cadd, padd, left;
877
878 sc = pbp->bio_to->geom->softc;
879 if ((pbp->bio_pflags & G_RAID3_BIO_PFLAG_DEGRADED) != 0) {
879 /*
880 * Find bio for which we have to calculate data.
881 * While going through this path, check if all requests
882 * succeeded, if not, deny whole request.
883 * If we're in COMPLETE mode, we allow one request to fail,
884 * so if we find one, we're sending it to the parity consumer.
885 * If there are more failed requests, we deny whole request.
886 */
887 xbp = fbp = NULL;
888 G_RAID3_FOREACH_BIO(pbp, cbp) {
889 if ((cbp->bio_cflags & G_RAID3_BIO_CFLAG_PARITY) != 0) {
890 KASSERT(xbp == NULL, ("More than one parity bio."));
891 xbp = cbp;
892 }
893 if (cbp->bio_error == 0)
894 continue;
880 /*
895 /*
881 * Find bio for which we should calculate data.
882 * While going through this path, check if all requests
883 * succeeded, if not, deny whole request.
896 * Found failed request.
884 */
897 */
885 bp = NULL;
886 G_RAID3_FOREACH_BIO(pbp, cbp) {
887 if ((cbp->bio_cflags & G_RAID3_BIO_CFLAG_PARITY) != 0) {
888 KASSERT(bp == NULL,
889 ("More than one parity bio."));
890 bp = cbp;
891 }
892 if (cbp->bio_error == 0)
893 continue;
898 G_RAID3_LOGREQ(0, cbp, "Request failed.");
899 disk = cbp->bio_caller2;
900 if (disk != NULL) {
894 /*
901 /*
895 * Found failed request.
902 * Actually this is pointless to bump syncid,
903 * because whole device is fucked up.
896 */
904 */
897 if (pbp->bio_error == 0)
898 pbp->bio_error = cbp->bio_error;
899 disk = cbp->bio_caller2;
900 if (disk != NULL) {
905 sc->sc_bump_syncid = G_RAID3_BUMP_IMMEDIATELY;
906 g_raid3_event_send(disk,
907 G_RAID3_DISK_STATE_DISCONNECTED,
908 G_RAID3_EVENT_DONTWAIT);
909 }
910 if (fbp == NULL) {
911 if ((pbp->bio_pflags & G_RAID3_BIO_PFLAG_DEGRADED) != 0) {
901 /*
912 /*
902 * Actually this is pointless to bump syncid,
903 * because whole device is fucked up.
913 * We are already in degraded mode, so we can't
914 * accept any failures.
904 */
915 */
905 sc->sc_bump_syncid = G_RAID3_BUMP_IMMEDIATELY;
906 g_raid3_event_send(disk,
907 G_RAID3_DISK_STATE_DISCONNECTED,
908 G_RAID3_EVENT_DONTWAIT);
916 if (pbp->bio_error == 0)
917 pbp->bio_error = fbp->bio_error;
918 } else {
919 fbp = cbp;
909 }
920 }
910 }
911 KASSERT(bp != NULL, ("NULL parity bio."));
912 if (pbp->bio_error != 0) {
921 } else {
913 /*
922 /*
914 * Deny whole request.
923 * Next failed request, that's too many.
915 */
924 */
925 if (pbp->bio_error == 0)
926 pbp->bio_error = fbp->bio_error;
927 }
928 }
929 if (pbp->bio_error != 0)
930 goto finish;
931 if (fbp != NULL) {
932 struct g_consumer *cp;
933
934 /*
935 * One request failed, so send the same request to
936 * the parity consumer.
937 */
938 disk = pbp->bio_driver2;
939 if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE) {
940 pbp->bio_error = fbp->bio_error;
916 goto finish;
917 }
941 goto finish;
942 }
943 pbp->bio_pflags |= G_RAID3_BIO_PFLAG_DEGRADED;
944 pbp->bio_inbed--;
945 fbp->bio_flags &= ~(BIO_DONE | BIO_ERROR);
946 if (disk->d_no == sc->sc_ndisks - 1)
947 fbp->bio_cflags |= G_RAID3_BIO_CFLAG_PARITY;
948 fbp->bio_error = 0;
949 fbp->bio_completed = 0;
950 fbp->bio_children = 0;
951 fbp->bio_inbed = 0;
952 cp = disk->d_consumer;
953 fbp->bio_caller2 = disk;
954 fbp->bio_to = cp->provider;
955 G_RAID3_LOGREQ(3, fbp, "Sending request (recover).");
956 KASSERT(cp->acr > 0 && cp->ace > 0,
957 ("Consumer %s not opened (r%dw%de%d).", cp->provider->name,
958 cp->acr, cp->acw, cp->ace));
959 g_io_request(fbp, cp);
960 return;
961 }
962 if (xbp != NULL) {
918 /*
919 * Calculate parity.
920 */
921 G_RAID3_FOREACH_BIO(pbp, cbp) {
922 if ((cbp->bio_cflags & G_RAID3_BIO_CFLAG_PARITY) != 0)
923 continue;
963 /*
964 * Calculate parity.
965 */
966 G_RAID3_FOREACH_BIO(pbp, cbp) {
967 if ((cbp->bio_cflags & G_RAID3_BIO_CFLAG_PARITY) != 0)
968 continue;
924 g_raid3_xor(cbp->bio_data, bp->bio_data, bp->bio_data,
925 bp->bio_length);
969 g_raid3_xor(cbp->bio_data, xbp->bio_data, xbp->bio_data,
970 xbp->bio_length);
926 }
971 }
927 bp->bio_cflags &= ~G_RAID3_BIO_CFLAG_PARITY;
928 } else {
929 /*
930 * If we're in COMPLETE mode, we allow one request to fail,
931 * so if we find one, we're sending it to the parity consumer.
932 * If there are more failed requests, we deny whole request.
933 */
934 bp = NULL;
935 G_RAID3_FOREACH_BIO(pbp, cbp) {
936 if (cbp->bio_error == 0)
937 continue;
938 /*
939 * Found failed request.
940 */
941 G_RAID3_LOGREQ(0, cbp, "Request failed.");
942 disk = cbp->bio_caller2;
943 if (disk != NULL) {
944 sc->sc_bump_syncid = G_RAID3_BUMP_IMMEDIATELY;
945 g_raid3_event_send(disk,
946 G_RAID3_DISK_STATE_DISCONNECTED,
947 G_RAID3_EVENT_DONTWAIT);
948 }
949 if (bp == NULL)
950 bp = cbp;
951 else {
952 /*
953 * Next failed request, that's too many.
954 */
955 if (pbp->bio_error == 0)
956 pbp->bio_error = bp->bio_error;
957 }
958 }
959 if (pbp->bio_error != 0)
960 goto finish;
961 if (bp != NULL) {
962 struct g_consumer *cp;
963
964 /*
965 * One request failed, so send the same request to
966 * the parity consumer.
967 */
968 disk = &sc->sc_disks[sc->sc_ndisks - 1];
969 if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE) {
970 pbp->bio_error = bp->bio_error;
971 goto finish;
972 }
973 pbp->bio_pflags |= G_RAID3_BIO_PFLAG_DEGRADED;
974 pbp->bio_inbed--;
975 bp->bio_flags &= ~(BIO_DONE | BIO_ERROR);
976 bp->bio_cflags |= G_RAID3_BIO_CFLAG_PARITY;
977 bp->bio_error = 0;
978 bp->bio_completed = 0;
979 bp->bio_children = 0;
980 bp->bio_inbed = 0;
981 cp = disk->d_consumer;
982 bp->bio_caller2 = disk;
983 bp->bio_to = cp->provider;
984 G_RAID3_LOGREQ(3, bp, "Sending request (parity).");
985 KASSERT(cp->acr > 0 && cp->ace > 0,
986 ("Consumer %s not opened (r%dw%de%d).", cp->provider->name,
987 cp->acr, cp->acw, cp->ace));
988 g_io_request(bp, cp);
989 return;
990 }
972 xbp->bio_cflags &= ~G_RAID3_BIO_CFLAG_PARITY;
991 }
992 atom = sc->sc_sectorsize / (sc->sc_ndisks - 1);
993 cadd = padd = 0;
994 for (left = pbp->bio_length; left > 0; left -= sc->sc_sectorsize) {
995 G_RAID3_FOREACH_BIO(pbp, cbp) {
996 bcopy(cbp->bio_data + cadd, pbp->bio_data + padd, atom);
997 pbp->bio_completed += atom;
998 padd += atom;

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

1299g_raid3_register_request(struct bio *pbp)
1300{
1301 struct g_raid3_softc *sc;
1302 struct g_raid3_disk *disk;
1303 struct g_consumer *cp;
1304 struct bio *cbp;
1305 off_t offset, length;
1306 u_int n, ndisks;
973 }
974 atom = sc->sc_sectorsize / (sc->sc_ndisks - 1);
975 cadd = padd = 0;
976 for (left = pbp->bio_length; left > 0; left -= sc->sc_sectorsize) {
977 G_RAID3_FOREACH_BIO(pbp, cbp) {
978 bcopy(cbp->bio_data + cadd, pbp->bio_data + padd, atom);
979 pbp->bio_completed += atom;
980 padd += atom;

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

1281g_raid3_register_request(struct bio *pbp)
1282{
1283 struct g_raid3_softc *sc;
1284 struct g_raid3_disk *disk;
1285 struct g_consumer *cp;
1286 struct bio *cbp;
1287 off_t offset, length;
1288 u_int n, ndisks;
1289 int round_robin;
1307
1308 ndisks = 0;
1309 sc = pbp->bio_to->geom->softc;
1310 if ((pbp->bio_cflags & G_RAID3_BIO_CFLAG_REGSYNC) != 0 &&
1311 sc->sc_syncdisk == NULL) {
1312 g_io_deliver(pbp, EIO);
1313 return (0);
1314 }
1315 g_raid3_init_bio(pbp);
1316 length = pbp->bio_length / (sc->sc_ndisks - 1);
1317 offset = pbp->bio_offset / (sc->sc_ndisks - 1);
1318 switch (pbp->bio_cmd) {
1319 case BIO_READ:
1320 ndisks = sc->sc_ndisks - 1;
1290
1291 ndisks = 0;
1292 sc = pbp->bio_to->geom->softc;
1293 if ((pbp->bio_cflags & G_RAID3_BIO_CFLAG_REGSYNC) != 0 &&
1294 sc->sc_syncdisk == NULL) {
1295 g_io_deliver(pbp, EIO);
1296 return (0);
1297 }
1298 g_raid3_init_bio(pbp);
1299 length = pbp->bio_length / (sc->sc_ndisks - 1);
1300 offset = pbp->bio_offset / (sc->sc_ndisks - 1);
1301 switch (pbp->bio_cmd) {
1302 case BIO_READ:
1303 ndisks = sc->sc_ndisks - 1;
1304 pbp->bio_driver2 = &sc->sc_disks[sc->sc_ndisks - 1];
1321 break;
1322 case BIO_WRITE:
1323 case BIO_DELETE:
1324 ndisks = sc->sc_ndisks;
1325 break;
1326 }
1305 break;
1306 case BIO_WRITE:
1307 case BIO_DELETE:
1308 ndisks = sc->sc_ndisks;
1309 break;
1310 }
1311 if (sc->sc_state == G_RAID3_DEVICE_STATE_COMPLETE &&
1312 (sc->sc_flags & G_RAID3_DEVICE_FLAG_ROUND_ROBIN) != 0) {
1313 round_robin = 1;
1314 } else {
1315 round_robin = 0;
1316 }
1327 for (n = 0; n < ndisks; n++) {
1328 disk = &sc->sc_disks[n];
1329 cbp = g_raid3_clone_bio(sc, pbp);
1330 if (cbp == NULL) {
1331 while ((cbp = G_RAID3_HEAD_BIO(pbp)) != NULL)
1332 g_raid3_destroy_bio(sc, cbp);
1333 return (ENOMEM);
1334 }

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

1340 if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE) {
1341 /*
1342 * Replace invalid component with the parity
1343 * component.
1344 */
1345 disk = &sc->sc_disks[sc->sc_ndisks - 1];
1346 cbp->bio_cflags |= G_RAID3_BIO_CFLAG_PARITY;
1347 pbp->bio_pflags |= G_RAID3_BIO_PFLAG_DEGRADED;
1317 for (n = 0; n < ndisks; n++) {
1318 disk = &sc->sc_disks[n];
1319 cbp = g_raid3_clone_bio(sc, pbp);
1320 if (cbp == NULL) {
1321 while ((cbp = G_RAID3_HEAD_BIO(pbp)) != NULL)
1322 g_raid3_destroy_bio(sc, cbp);
1323 return (ENOMEM);
1324 }

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

1330 if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE) {
1331 /*
1332 * Replace invalid component with the parity
1333 * component.
1334 */
1335 disk = &sc->sc_disks[sc->sc_ndisks - 1];
1336 cbp->bio_cflags |= G_RAID3_BIO_CFLAG_PARITY;
1337 pbp->bio_pflags |= G_RAID3_BIO_PFLAG_DEGRADED;
1338 } else if (round_robin &&
1339 disk->d_no == sc->sc_round_robin) {
1340 /*
1341 * In round-robin mode skip one data component
1342 * and use parity component when reading.
1343 */
1344 pbp->bio_driver2 = disk;
1345 disk = &sc->sc_disks[sc->sc_ndisks - 1];
1346 cbp->bio_cflags |= G_RAID3_BIO_CFLAG_PARITY;
1347 sc->sc_round_robin++;
1348 round_robin = 0;
1348 }
1349 break;
1350 case BIO_WRITE:
1351 case BIO_DELETE:
1352 if (disk->d_state == G_RAID3_DISK_STATE_ACTIVE ||
1353 disk->d_state == G_RAID3_DISK_STATE_SYNCHRONIZING) {
1354 if (n == ndisks - 1) {
1355 /*

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

1377 }
1378 break;
1379 }
1380 if (cbp != NULL)
1381 cbp->bio_caller2 = disk;
1382 }
1383 switch (pbp->bio_cmd) {
1384 case BIO_READ:
1349 }
1350 break;
1351 case BIO_WRITE:
1352 case BIO_DELETE:
1353 if (disk->d_state == G_RAID3_DISK_STATE_ACTIVE ||
1354 disk->d_state == G_RAID3_DISK_STATE_SYNCHRONIZING) {
1355 if (n == ndisks - 1) {
1356 /*

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

1378 }
1379 break;
1380 }
1381 if (cbp != NULL)
1382 cbp->bio_caller2 = disk;
1383 }
1384 switch (pbp->bio_cmd) {
1385 case BIO_READ:
1386 if (round_robin) {
1387 /*
1388 * If we are in round-robin mode and 'round_robin' is
1389 * still 1, it means, that we skipped parity component
1390 * for this read and must reset sc_round_robin field.
1391 */
1392 sc->sc_round_robin = 0;
1393 }
1385 G_RAID3_FOREACH_BIO(pbp, cbp) {
1386 disk = cbp->bio_caller2;
1387 cp = disk->d_consumer;
1388 cbp->bio_to = cp->provider;
1389 G_RAID3_LOGREQ(3, cbp, "Sending request.");
1390 KASSERT(cp->acr > 0 && cp->ace > 0,
1391 ("Consumer %s not opened (r%dw%de%d).",
1392 cp->provider->name, cp->acr, cp->acw, cp->ace));

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

2469 gp->orphan = g_raid3_orphan;
2470 gp->access = g_raid3_access;
2471 gp->dumpconf = g_raid3_dumpconf;
2472
2473 sc->sc_id = md->md_id;
2474 sc->sc_mediasize = md->md_mediasize;
2475 sc->sc_sectorsize = md->md_sectorsize;
2476 sc->sc_ndisks = md->md_all;
1394 G_RAID3_FOREACH_BIO(pbp, cbp) {
1395 disk = cbp->bio_caller2;
1396 cp = disk->d_consumer;
1397 cbp->bio_to = cp->provider;
1398 G_RAID3_LOGREQ(3, cbp, "Sending request.");
1399 KASSERT(cp->acr > 0 && cp->ace > 0,
1400 ("Consumer %s not opened (r%dw%de%d).",
1401 cp->provider->name, cp->acr, cp->acw, cp->ace));

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

2478 gp->orphan = g_raid3_orphan;
2479 gp->access = g_raid3_access;
2480 gp->dumpconf = g_raid3_dumpconf;
2481
2482 sc->sc_id = md->md_id;
2483 sc->sc_mediasize = md->md_mediasize;
2484 sc->sc_sectorsize = md->md_sectorsize;
2485 sc->sc_ndisks = md->md_all;
2486 sc->sc_round_robin = 0;
2477 sc->sc_flags = md->md_mflags;
2478 sc->sc_bump_syncid = 0;
2479 for (n = 0; n < sc->sc_ndisks; n++)
2480 sc->sc_disks[n].d_state = G_RAID3_DISK_STATE_NODISK;
2481 bioq_init(&sc->sc_queue);
2482 mtx_init(&sc->sc_queue_mtx, "graid3:queue", NULL, MTX_DEF);
2483 TAILQ_INIT(&sc->sc_events);
2484 mtx_init(&sc->sc_events_mtx, "graid3:events", NULL, MTX_DEF);

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

2747 if (!first) \
2748 sbuf_printf(sb, ", "); \
2749 else \
2750 first = 0; \
2751 sbuf_printf(sb, name); \
2752 } \
2753} while (0)
2754 ADD_FLAG(G_RAID3_DEVICE_FLAG_NOAUTOSYNC, "NOAUTOSYNC");
2487 sc->sc_flags = md->md_mflags;
2488 sc->sc_bump_syncid = 0;
2489 for (n = 0; n < sc->sc_ndisks; n++)
2490 sc->sc_disks[n].d_state = G_RAID3_DISK_STATE_NODISK;
2491 bioq_init(&sc->sc_queue);
2492 mtx_init(&sc->sc_queue_mtx, "graid3:queue", NULL, MTX_DEF);
2493 TAILQ_INIT(&sc->sc_events);
2494 mtx_init(&sc->sc_events_mtx, "graid3:events", NULL, MTX_DEF);

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

2757 if (!first) \
2758 sbuf_printf(sb, ", "); \
2759 else \
2760 first = 0; \
2761 sbuf_printf(sb, name); \
2762 } \
2763} while (0)
2764 ADD_FLAG(G_RAID3_DEVICE_FLAG_NOAUTOSYNC, "NOAUTOSYNC");
2765 ADD_FLAG(G_RAID3_DEVICE_FLAG_ROUND_ROBIN,
2766 "ROUND-ROBIN");
2755#undef ADD_FLAG
2756 }
2757 sbuf_printf(sb, "</Flags>\n");
2758 sbuf_printf(sb, "%s<Components>%u</Components>\n", indent,
2759 sc->sc_ndisks);
2760 sbuf_printf(sb, "%s<State>%s</State>\n", indent,
2761 g_raid3_device_state2str(sc->sc_state));
2762 }
2763}
2764
2765DECLARE_GEOM_CLASS(g_raid3_class, g_raid3);
2767#undef ADD_FLAG
2768 }
2769 sbuf_printf(sb, "</Flags>\n");
2770 sbuf_printf(sb, "%s<Components>%u</Components>\n", indent,
2771 sc->sc_ndisks);
2772 sbuf_printf(sb, "%s<State>%s</State>\n", indent,
2773 g_raid3_device_state2str(sc->sc_state));
2774 }
2775}
2776
2777DECLARE_GEOM_CLASS(g_raid3_class, g_raid3);