Deleted Added
full compact
g_mirror.c (155174) g_mirror.c (155539)
1/*-
2 * Copyright (c) 2004-2005 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-2005 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/mirror/g_mirror.c 155174 2006-02-01 12:06:01Z pjd $");
28__FBSDID("$FreeBSD: head/sys/geom/mirror/g_mirror.c 155539 2006-02-11 14:42:23Z 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>

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

750 if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE ||
751 disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) {
752 disk->d_genid = sc->sc_genid;
753 g_mirror_update_metadata(disk);
754 }
755 }
756}
757
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>

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

750 if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE ||
751 disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) {
752 disk->d_genid = sc->sc_genid;
753 g_mirror_update_metadata(disk);
754 }
755 }
756}
757
758static void
759g_mirror_idle(struct g_mirror_softc *sc)
758static int
759g_mirror_idle(struct g_mirror_softc *sc, int from_access)
760{
761 struct g_mirror_disk *disk;
760{
761 struct g_mirror_disk *disk;
762 int timeout;
762
763
763 if (sc->sc_provider == NULL || sc->sc_provider->acw == 0)
764 return;
764 if (sc->sc_provider == NULL)
765 return (0);
766 if (sc->sc_idle)
767 return (0);
768 if (sc->sc_writes > 0)
769 return (0);
770 if (!from_access && sc->sc_provider->acw > 0) {
771 timeout = g_mirror_idletime - (time_second - sc->sc_last_write);
772 if (timeout > 0)
773 return (timeout);
774 }
765 sc->sc_idle = 1;
775 sc->sc_idle = 1;
766 g_topology_lock();
776 if (!from_access)
777 g_topology_lock();
767 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
768 if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
769 continue;
770 G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as clean.",
771 g_mirror_get_diskname(disk), sc->sc_name);
772 disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
773 g_mirror_update_metadata(disk);
774 }
778 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
779 if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
780 continue;
781 G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as clean.",
782 g_mirror_get_diskname(disk), sc->sc_name);
783 disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
784 g_mirror_update_metadata(disk);
785 }
775 g_topology_unlock();
786 if (!from_access)
787 g_topology_unlock();
788 return (0);
776}
777
778static void
779g_mirror_unidle(struct g_mirror_softc *sc)
780{
781 struct g_mirror_disk *disk;
782
783 sc->sc_idle = 0;
789}
790
791static void
792g_mirror_unidle(struct g_mirror_softc *sc)
793{
794 struct g_mirror_disk *disk;
795
796 sc->sc_idle = 0;
797 sc->sc_last_write = time_second;
784 g_topology_lock();
785 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
786 if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
787 continue;
788 G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as dirty.",
789 g_mirror_get_diskname(disk), sc->sc_name);
790 disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY;
791 g_mirror_update_metadata(disk);
792 }
793 g_topology_unlock();
794}
795
798 g_topology_lock();
799 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
800 if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
801 continue;
802 G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as dirty.",
803 g_mirror_get_diskname(disk), sc->sc_name);
804 disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY;
805 g_mirror_update_metadata(disk);
806 }
807 g_topology_unlock();
808}
809
796/*
797 * Return 1 if we should check if mirror is idling.
798 */
799static int
800g_mirror_check_idle(struct g_mirror_softc *sc)
801{
802 struct g_mirror_disk *disk;
803
804 if (sc->sc_idle)
805 return (0);
806 if (sc->sc_provider != NULL && sc->sc_provider->acw == 0)
807 return (0);
808 /*
809 * Check if there are no in-flight requests.
810 */
811 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
812 if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
813 continue;
814 if (disk->d_consumer->index > 0)
815 return (0);
816 }
817 return (1);
818}
819
820static __inline int
821bintime_cmp(struct bintime *bt1, struct bintime *bt2)
822{
823
824 if (bt1->sec < bt2->sec)
825 return (-1);
826 else if (bt1->sec > bt2->sec)
827 return (1);

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

859g_mirror_regular_request(struct bio *bp)
860{
861 struct g_mirror_softc *sc;
862 struct g_mirror_disk *disk;
863 struct bio *pbp;
864
865 g_topology_assert_not();
866
810static __inline int
811bintime_cmp(struct bintime *bt1, struct bintime *bt2)
812{
813
814 if (bt1->sec < bt2->sec)
815 return (-1);
816 else if (bt1->sec > bt2->sec)
817 return (1);

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

849g_mirror_regular_request(struct bio *bp)
850{
851 struct g_mirror_softc *sc;
852 struct g_mirror_disk *disk;
853 struct bio *pbp;
854
855 g_topology_assert_not();
856
867 bp->bio_from->index--;
868 pbp = bp->bio_parent;
869 sc = pbp->bio_to->geom->softc;
857 pbp = bp->bio_parent;
858 sc = pbp->bio_to->geom->softc;
859 bp->bio_from->index--;
860 if (bp->bio_cmd == BIO_WRITE)
861 sc->sc_writes--;
870 disk = bp->bio_from->private;
871 if (disk == NULL) {
872 g_topology_lock();
873 g_mirror_kill_consumer(sc, bp->bio_from);
874 g_topology_unlock();
875 } else {
876 g_mirror_update_delay(disk, bp);
877 }

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

1335 struct g_mirror_disk *disk;
1336 struct g_mirror_disk_sync *sync;
1337 struct bio_queue_head queue;
1338 struct g_consumer *cp;
1339 struct bio *cbp;
1340
1341 if (sc->sc_idle)
1342 g_mirror_unidle(sc);
862 disk = bp->bio_from->private;
863 if (disk == NULL) {
864 g_topology_lock();
865 g_mirror_kill_consumer(sc, bp->bio_from);
866 g_topology_unlock();
867 } else {
868 g_mirror_update_delay(disk, bp);
869 }

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

1327 struct g_mirror_disk *disk;
1328 struct g_mirror_disk_sync *sync;
1329 struct bio_queue_head queue;
1330 struct g_consumer *cp;
1331 struct bio *cbp;
1332
1333 if (sc->sc_idle)
1334 g_mirror_unidle(sc);
1335 else
1336 sc->sc_last_write = time_second;
1337
1343 /*
1344 * Allocate all bios before sending any request, so we can
1345 * return ENOMEM in nice and clean way.
1346 */
1347 bioq_init(&queue);
1348 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
1349 sync = &disk->d_sync;
1350 switch (disk->d_state) {

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

1387 }
1388 for (cbp = bioq_first(&queue); cbp != NULL;
1389 cbp = bioq_first(&queue)) {
1390 bioq_remove(&queue, cbp);
1391 G_MIRROR_LOGREQ(3, cbp, "Sending request.");
1392 cp = cbp->bio_caller1;
1393 cbp->bio_caller1 = NULL;
1394 cp->index++;
1338 /*
1339 * Allocate all bios before sending any request, so we can
1340 * return ENOMEM in nice and clean way.
1341 */
1342 bioq_init(&queue);
1343 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
1344 sync = &disk->d_sync;
1345 switch (disk->d_state) {

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

1382 }
1383 for (cbp = bioq_first(&queue); cbp != NULL;
1384 cbp = bioq_first(&queue)) {
1385 bioq_remove(&queue, cbp);
1386 G_MIRROR_LOGREQ(3, cbp, "Sending request.");
1387 cp = cbp->bio_caller1;
1388 cbp->bio_caller1 = NULL;
1389 cp->index++;
1390 sc->sc_writes++;
1395 g_io_request(cbp, cp);
1396 }
1397 /*
1398 * Bump syncid on first write.
1399 */
1400 if ((sc->sc_bump_id & G_MIRROR_BUMP_SYNCID) != 0) {
1401 sc->sc_bump_id &= ~G_MIRROR_BUMP_SYNCID;
1402 g_topology_lock();

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

1470g_mirror_worker(void *arg)
1471{
1472 struct g_mirror_softc *sc;
1473 struct g_mirror_disk *disk;
1474 struct g_mirror_disk_sync *sync;
1475 struct g_mirror_event *ep;
1476 struct bio *bp;
1477 u_int nreqs;
1391 g_io_request(cbp, cp);
1392 }
1393 /*
1394 * Bump syncid on first write.
1395 */
1396 if ((sc->sc_bump_id & G_MIRROR_BUMP_SYNCID) != 0) {
1397 sc->sc_bump_id &= ~G_MIRROR_BUMP_SYNCID;
1398 g_topology_lock();

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

1466g_mirror_worker(void *arg)
1467{
1468 struct g_mirror_softc *sc;
1469 struct g_mirror_disk *disk;
1470 struct g_mirror_disk_sync *sync;
1471 struct g_mirror_event *ep;
1472 struct bio *bp;
1473 u_int nreqs;
1474 int timeout;
1478
1479 sc = arg;
1480 mtx_lock_spin(&sched_lock);
1481 sched_prio(curthread, PRIBIO);
1482 mtx_unlock_spin(&sched_lock);
1483
1484 nreqs = 0;
1485 for (;;) {

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

1524 G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
1525 if (g_mirror_try_destroy(sc))
1526 kthread_exit(0);
1527 }
1528 G_MIRROR_DEBUG(5, "%s: I'm here 1.", __func__);
1529 continue;
1530 }
1531 /*
1475
1476 sc = arg;
1477 mtx_lock_spin(&sched_lock);
1478 sched_prio(curthread, PRIBIO);
1479 mtx_unlock_spin(&sched_lock);
1480
1481 nreqs = 0;
1482 for (;;) {

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

1521 G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
1522 if (g_mirror_try_destroy(sc))
1523 kthread_exit(0);
1524 }
1525 G_MIRROR_DEBUG(5, "%s: I'm here 1.", __func__);
1526 continue;
1527 }
1528 /*
1529 * Check if we can mark array as CLEAN and if we can't take
1530 * how much seconds should we wait.
1531 */
1532 timeout = g_mirror_idle(sc, 0);
1533 /*
1532 * Now I/O requests.
1533 */
1534 /* Get first request from the queue. */
1535 mtx_lock(&sc->sc_queue_mtx);
1536 bp = bioq_first(&sc->sc_queue);
1537 if (bp == NULL) {
1538 if (ep != NULL) {
1539 /*

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

1576 sync->ds_resync = -1;
1577 }
1578 g_mirror_sync_one(disk);
1579 }
1580 G_MIRROR_DEBUG(5, "%s: I'm here 2.", __func__);
1581 goto sleep;
1582 }
1583 if (bp == NULL) {
1534 * Now I/O requests.
1535 */
1536 /* Get first request from the queue. */
1537 mtx_lock(&sc->sc_queue_mtx);
1538 bp = bioq_first(&sc->sc_queue);
1539 if (bp == NULL) {
1540 if (ep != NULL) {
1541 /*

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

1578 sync->ds_resync = -1;
1579 }
1580 g_mirror_sync_one(disk);
1581 }
1582 G_MIRROR_DEBUG(5, "%s: I'm here 2.", __func__);
1583 goto sleep;
1584 }
1585 if (bp == NULL) {
1584 if (g_mirror_check_idle(sc)) {
1585 u_int idletime;
1586
1587 idletime = g_mirror_idletime;
1588 if (idletime == 0)
1589 idletime = 1;
1590 idletime *= hz;
1591 if (msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
1592 "m:w1", idletime) == EWOULDBLOCK) {
1593 G_MIRROR_DEBUG(5, "%s: I'm here 3.",
1594 __func__);
1595 /*
1596 * No I/O requests in 'idletime' seconds,
1597 * so mark components as clean.
1598 */
1599 g_mirror_idle(sc);
1600 }
1601 G_MIRROR_DEBUG(5, "%s: I'm here 4.", __func__);
1602 } else {
1603 MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
1604 "m:w2", 0);
1605 G_MIRROR_DEBUG(5, "%s: I'm here 5.", __func__);
1606 }
1586 MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "m:w1",
1587 timeout * hz);
1588 G_MIRROR_DEBUG(5, "%s: I'm here 4.", __func__);
1607 continue;
1608 }
1609 nreqs++;
1610 bioq_remove(&sc->sc_queue, bp);
1611 mtx_unlock(&sc->sc_queue_mtx);
1612
1613 if ((bp->bio_cflags & G_MIRROR_BIO_FLAG_REGULAR) != 0) {
1614 g_mirror_regular_request(bp);

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

1642 timeout);
1643 } else {
1644 g_mirror_register_request(bp);
1645 }
1646 G_MIRROR_DEBUG(5, "%s: I'm here 9.", __func__);
1647 }
1648}
1649
1589 continue;
1590 }
1591 nreqs++;
1592 bioq_remove(&sc->sc_queue, bp);
1593 mtx_unlock(&sc->sc_queue_mtx);
1594
1595 if ((bp->bio_cflags & G_MIRROR_BIO_FLAG_REGULAR) != 0) {
1596 g_mirror_regular_request(bp);

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

1624 timeout);
1625 } else {
1626 g_mirror_register_request(bp);
1627 }
1628 G_MIRROR_DEBUG(5, "%s: I'm here 9.", __func__);
1629 }
1630}
1631
1650/*
1651 * Open disk's consumer if needed.
1652 */
1653static void
1632static void
1654g_mirror_update_access(struct g_mirror_disk *disk)
1633g_mirror_update_idle(struct g_mirror_softc *sc, struct g_mirror_disk *disk)
1655{
1634{
1656 struct g_provider *pp;
1657
1658 g_topology_assert();
1635
1636 g_topology_assert();
1659
1660 pp = disk->d_softc->sc_provider;
1661 if (pp == NULL)
1662 return;
1663 if (pp->acw > 0) {
1664 if ((disk->d_flags & G_MIRROR_DISK_FLAG_DIRTY) == 0) {
1665 G_MIRROR_DEBUG(1,
1666 "Disk %s (device %s) marked as dirty.",
1667 g_mirror_get_diskname(disk),
1668 disk->d_softc->sc_name);
1669 disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY;
1670 }
1671 } else if (pp->acw == 0) {
1672 if ((disk->d_flags & G_MIRROR_DISK_FLAG_DIRTY) != 0) {
1673 G_MIRROR_DEBUG(1,
1674 "Disk %s (device %s) marked as clean.",
1675 g_mirror_get_diskname(disk),
1676 disk->d_softc->sc_name);
1677 disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
1678 }
1637 if (!sc->sc_idle && (disk->d_flags & G_MIRROR_DISK_FLAG_DIRTY) == 0) {
1638 G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as dirty.",
1639 g_mirror_get_diskname(disk), disk->d_softc->sc_name);
1640 disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY;
1641 } else if (sc->sc_idle &&
1642 (disk->d_flags & G_MIRROR_DISK_FLAG_DIRTY) != 0) {
1643 G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as clean.",
1644 g_mirror_get_diskname(disk), disk->d_softc->sc_name);
1645 disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
1679 }
1680}
1681
1682static void
1683g_mirror_sync_start(struct g_mirror_disk *disk)
1684{
1685 struct g_mirror_softc *sc;
1686 int error;

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

2191 else if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) {
2192 disk->d_flags &= ~G_MIRROR_DISK_FLAG_SYNCHRONIZING;
2193 disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC;
2194 g_mirror_sync_stop(disk, 0);
2195 }
2196 disk->d_state = state;
2197 disk->d_sync.ds_offset = 0;
2198 disk->d_sync.ds_offset_done = 0;
1646 }
1647}
1648
1649static void
1650g_mirror_sync_start(struct g_mirror_disk *disk)
1651{
1652 struct g_mirror_softc *sc;
1653 int error;

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

2158 else if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) {
2159 disk->d_flags &= ~G_MIRROR_DISK_FLAG_SYNCHRONIZING;
2160 disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC;
2161 g_mirror_sync_stop(disk, 0);
2162 }
2163 disk->d_state = state;
2164 disk->d_sync.ds_offset = 0;
2165 disk->d_sync.ds_offset_done = 0;
2199 g_mirror_update_access(disk);
2200 g_mirror_update_metadata(disk);
2166 g_mirror_update_idle(sc, disk);
2201 G_MIRROR_DEBUG(0, "Device %s: provider %s activated.",
2202 sc->sc_name, g_mirror_get_diskname(disk));
2203 break;
2204 case G_MIRROR_DISK_STATE_STALE:
2205 /*
2206 * Possible scenarios:
2207 * 1. Stale disk was connected.
2208 */

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

2472 }
2473 return (0);
2474}
2475
2476static int
2477g_mirror_access(struct g_provider *pp, int acr, int acw, int ace)
2478{
2479 struct g_mirror_softc *sc;
2167 G_MIRROR_DEBUG(0, "Device %s: provider %s activated.",
2168 sc->sc_name, g_mirror_get_diskname(disk));
2169 break;
2170 case G_MIRROR_DISK_STATE_STALE:
2171 /*
2172 * Possible scenarios:
2173 * 1. Stale disk was connected.
2174 */

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

2438 }
2439 return (0);
2440}
2441
2442static int
2443g_mirror_access(struct g_provider *pp, int acr, int acw, int ace)
2444{
2445 struct g_mirror_softc *sc;
2480 struct g_mirror_disk *disk;
2481 int dcr, dcw, dce;
2482
2483 g_topology_assert();
2484 G_MIRROR_DEBUG(2, "Access request for %s: r%dw%de%d.", pp->name, acr,
2485 acw, ace);
2486
2487 dcr = pp->acr + acr;
2488 dcw = pp->acw + acw;
2489 dce = pp->ace + ace;
2490
2491 sc = pp->geom->softc;
2492 if (sc == NULL || LIST_EMPTY(&sc->sc_disks) ||
2493 (sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
2494 if (acr <= 0 && acw <= 0 && ace <= 0)
2495 return (0);
2496 else
2497 return (ENXIO);
2498 }
2446 int dcr, dcw, dce;
2447
2448 g_topology_assert();
2449 G_MIRROR_DEBUG(2, "Access request for %s: r%dw%de%d.", pp->name, acr,
2450 acw, ace);
2451
2452 dcr = pp->acr + acr;
2453 dcw = pp->acw + acw;
2454 dce = pp->ace + ace;
2455
2456 sc = pp->geom->softc;
2457 if (sc == NULL || LIST_EMPTY(&sc->sc_disks) ||
2458 (sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
2459 if (acr <= 0 && acw <= 0 && ace <= 0)
2460 return (0);
2461 else
2462 return (ENXIO);
2463 }
2499 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
2500 if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
2501 continue;
2502 /*
2503 * Mark disk as dirty on open and unmark on close.
2504 */
2505 if (pp->acw == 0 && dcw > 0) {
2506 G_MIRROR_DEBUG(1,
2507 "Disk %s (device %s) marked as dirty.",
2508 g_mirror_get_diskname(disk), sc->sc_name);
2509 disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY;
2510 g_mirror_update_metadata(disk);
2511 } else if (pp->acw > 0 && dcw == 0) {
2512 G_MIRROR_DEBUG(1,
2513 "Disk %s (device %s) marked as clean.",
2514 g_mirror_get_diskname(disk), sc->sc_name);
2515 disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
2516 g_mirror_update_metadata(disk);
2517 }
2518 }
2464 if (dcw == 0 && !sc->sc_idle)
2465 g_mirror_idle(sc, 1);
2519 return (0);
2520}
2521
2522static struct g_geom *
2523g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md)
2524{
2525 struct g_mirror_softc *sc;
2526 struct g_geom *gp;

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

2546 sc->sc_id = md->md_mid;
2547 sc->sc_slice = md->md_slice;
2548 sc->sc_balance = md->md_balance;
2549 sc->sc_mediasize = md->md_mediasize;
2550 sc->sc_sectorsize = md->md_sectorsize;
2551 sc->sc_ndisks = md->md_all;
2552 sc->sc_flags = md->md_mflags;
2553 sc->sc_bump_id = 0;
2466 return (0);
2467}
2468
2469static struct g_geom *
2470g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md)
2471{
2472 struct g_mirror_softc *sc;
2473 struct g_geom *gp;

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

2493 sc->sc_id = md->md_mid;
2494 sc->sc_slice = md->md_slice;
2495 sc->sc_balance = md->md_balance;
2496 sc->sc_mediasize = md->md_mediasize;
2497 sc->sc_sectorsize = md->md_sectorsize;
2498 sc->sc_ndisks = md->md_all;
2499 sc->sc_flags = md->md_mflags;
2500 sc->sc_bump_id = 0;
2554 sc->sc_idle = 0;
2501 sc->sc_idle = 1;
2502 sc->sc_last_write = time_second;
2503 sc->sc_writes = 0;
2555 bioq_init(&sc->sc_queue);
2556 mtx_init(&sc->sc_queue_mtx, "gmirror:queue", NULL, MTX_DEF);
2557 LIST_INIT(&sc->sc_disks);
2558 TAILQ_INIT(&sc->sc_events);
2559 mtx_init(&sc->sc_events_mtx, "gmirror:events", NULL, MTX_DEF);
2560 callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
2561 sc->sc_state = G_MIRROR_DEVICE_STATE_STARTING;
2562 gp->softc = sc;

--- 319 unchanged lines hidden ---
2504 bioq_init(&sc->sc_queue);
2505 mtx_init(&sc->sc_queue_mtx, "gmirror:queue", NULL, MTX_DEF);
2506 LIST_INIT(&sc->sc_disks);
2507 TAILQ_INIT(&sc->sc_events);
2508 mtx_init(&sc->sc_events_mtx, "gmirror:events", NULL, MTX_DEF);
2509 callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
2510 sc->sc_state = G_MIRROR_DEVICE_STATE_STARTING;
2511 gp->softc = sc;

--- 319 unchanged lines hidden ---