From owner-svn-src-projects@FreeBSD.ORG Sun Jan 30 10:35:42 2011 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 35D2A106566C; Sun, 30 Jan 2011 10:35:42 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 25D568FC12; Sun, 30 Jan 2011 10:35:42 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p0UAZg6X068476; Sun, 30 Jan 2011 10:35:42 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p0UAZgdZ068473; Sun, 30 Jan 2011 10:35:42 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201101301035.p0UAZgdZ068473@svn.freebsd.org> From: Alexander Motin Date: Sun, 30 Jan 2011 10:35:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r218084 - projects/graid/head/sys/geom/raid X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Jan 2011 10:35:42 -0000 Author: mav Date: Sun Jan 30 10:35:41 2011 New Revision: 218084 URL: http://svn.freebsd.org/changeset/base/218084 Log: Implement volume idle state tracking. Volume counted as idle when no payload write requests were running for specified number of seconds. Write volume dirty flag of Intel metadata as !v_idle. This should trigger volume resynchronization or work in SUBOPTIMAL mode after dirty reboot. Modified: projects/graid/head/sys/geom/raid/g_raid.c projects/graid/head/sys/geom/raid/md_intel.c Modified: projects/graid/head/sys/geom/raid/g_raid.c ============================================================================== --- projects/graid/head/sys/geom/raid/g_raid.c Sun Jan 30 07:49:44 2011 (r218083) +++ projects/graid/head/sys/geom/raid/g_raid.c Sun Jan 30 10:35:41 2011 (r218084) @@ -657,7 +657,6 @@ g_raid_bump_genid(struct g_raid_softc *s static int g_raid_idle(struct g_raid_volume *vol, int acw) { - struct g_raid_disk *disk; struct g_raid_softc *sc; int timeout; @@ -665,38 +664,28 @@ g_raid_idle(struct g_raid_volume *vol, i g_topology_assert_not(); sx_assert(&sc->sc_lock, SX_XLOCKED); - if (vol->v_provider == NULL) - return (0); // if ((sc->sc_flags & G_RAID_DEVICE_FLAG_NOFAILSYNC) != 0) // return (0); if (vol->v_idle) return (0); if (vol->v_writes > 0) return (0); - if (acw > 0 || (acw == -1 && vol->v_provider->acw > 0)) { + if (acw > 0 || (acw == -1 && + vol->v_provider != NULL && vol->v_provider->acw > 0)) { timeout = g_raid_idletime - (time_uptime - vol->v_last_write); if (timeout > 0) return (timeout); } vol->v_idle = 1; -// ZZZ - TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { - if (disk->d_state != G_RAID_DISK_S_ACTIVE) - continue; -// if (!(disk->d_flags & G_RAID_DISK_FLAG_DIRTY)) -// continue; - G_RAID_DEBUG(1, "Disk %s (device %s) marked as clean.", - g_raid_get_diskname(disk), sc->sc_name); -// disk->d_flags &= ~G_RAID_DISK_FLAG_DIRTY; -// g_raid_update_metadata(disk); - } + G_RAID_DEBUG(1, "Volume %s (node %s) marked as clean.", + vol->v_name, sc->sc_name); + g_raid_write_metadata(sc, vol, NULL, NULL); return (0); } static void g_raid_unidle(struct g_raid_volume *vol) { - struct g_raid_disk *disk; struct g_raid_softc *sc; sc = vol->v_softc; @@ -706,16 +695,9 @@ g_raid_unidle(struct g_raid_volume *vol) // if ((sc->sc_flags & G_RAID_DEVICE_FLAG_NOFAILSYNC) != 0) // return; vol->v_idle = 0; - vol->v_last_write = time_uptime; -//ZZZ - TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { - if (disk->d_state != G_RAID_DISK_S_ACTIVE) - continue; - G_RAID_DEBUG(1, "Disk %s (device %s) marked as dirty.", - g_raid_get_diskname(disk), sc->sc_name); -// disk->d_flags |= G_RAID_DISK_FLAG_DIRTY; -// g_raid_update_metadata(disk); - } + G_RAID_DEBUG(1, "Volume %s (node %s) marked as dirty.", + vol->v_name, sc->sc_name); + g_raid_write_metadata(sc, vol, NULL, NULL); } static void @@ -911,14 +893,13 @@ g_raid_start_request(struct bio *bp) if (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_DELETE) { if (vol->v_idle) g_raid_unidle(vol); - else - vol->v_last_write = time_uptime; + vol->v_writes++; } /* * Put request onto inflight queue, so we can check if new * synchronization requests don't collide with it. Then tell - * the tranlsation layer to start the I/O. + * the transformation layer to start the I/O. */ bioq_insert_tail(&vol->v_inflight, bp); G_RAID_TR_IOSTART(vol->v_tr, bp); @@ -936,6 +917,13 @@ g_raid_iodone(struct bio *bp, int error) vol = bp->bio_to->private; G_RAID_LOGREQ(3, bp, "Request done: %d.", error); + + /* Update stats if we done write/delete. */ + if (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_DELETE) { + vol->v_writes--; + vol->v_last_write = time_uptime; + } + bioq_remove(&vol->v_inflight, bp); if (bp->bio_cmd == BIO_WRITE && vol->v_pending_lock && g_raid_is_in_locked_range(vol, bp)) { @@ -1040,13 +1028,8 @@ g_raid_unlock_range(struct g_raid_volume void g_raid_subdisk_iostart(struct g_raid_subdisk *sd, struct bio *bp) { - struct g_raid_volume *vol; struct g_consumer *cp; - vol = sd->sd_volume; - if (bp->bio_cmd == BIO_WRITE) - vol->v_writes++; - cp = sd->sd_disk->d_consumer; bp->bio_from = sd->sd_disk->d_consumer; bp->bio_to = sd->sd_disk->d_consumer->provider; @@ -1111,8 +1094,6 @@ g_raid_disk_done_request(struct bio *bp) sc = sd->sd_softc; vol = sd->sd_volume; bp->bio_from->index--; - if (bp->bio_cmd == BIO_WRITE) - vol->v_writes--; disk = bp->bio_from->private; if (disk == NULL) { g_topology_lock(); @@ -1205,8 +1186,7 @@ process: } if (rv == EWOULDBLOCK) { TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) { - if (bioq_first(&vol->v_inflight) == NULL && - !vol->v_idle) + if (vol->v_writes == 0 && !vol->v_idle) g_raid_idle(vol, -1); if (vol->v_timeout) vol->v_timeout(vol, vol->v_to_arg); @@ -1465,8 +1445,8 @@ g_raid_access(struct g_provider *pp, int error = ENXIO; goto out; } -// if (dcw == 0 && !vol->v_idle) -// g_raid_idle(vol, dcw); + if (dcw == 0 && !vol->v_idle) + g_raid_idle(vol, dcw); vol->v_provider_open += acr + acw + ace; /* Handle delayed node destruction. */ if (sc->sc_stopping == G_RAID_DESTROY_DELAYED && Modified: projects/graid/head/sys/geom/raid/md_intel.c ============================================================================== --- projects/graid/head/sys/geom/raid/md_intel.c Sun Jan 30 07:49:44 2011 (r218083) +++ projects/graid/head/sys/geom/raid/md_intel.c Sun Jan 30 10:35:41 2011 (r218084) @@ -1956,6 +1956,7 @@ g_raid_md_write_intel(struct g_raid_md_o mvol->migr_type = INTEL_MT_REPAIR; } else mvol->migr_state = 0; + mvol->dirty = !vol->v_idle; mmap0 = intel_get_map(mvol, 0);