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 --- |