fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!rdc: nsc_reserve(%s) failed %d\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (group->diskqrsrv > 0 && --group->diskqrsrv == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (q->busycnt > 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_close_diskq: NULL group!");
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!nsc_close on diskq failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&grp->diskq.disk_hdr, sizeof (diskq_header));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_open the diskq and attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the nsc_fd to krdc->diskqfd
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_open_diskq: Unable to open %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* just test a reserve release */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_open_diskq: Reserve failed for %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_count_vecs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * simply vec++'s until sb_addr is null
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns number of vectors encountered
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (i+1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_setid2idx
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * given setid, return index
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_idx2setid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * given an index, return its setid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_fill_ioheader
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fill in all the stuff you want to save on disk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * at the beginnig of each queued write
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_fill_ioheader(rdc_aio_t *aio, io_hdr *hd, int qpos)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&rdc_k_info[aio->index].group->diskq.disk_qlock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hd->dat.flag |= RDC_NULL_BUF; /* no real data to queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_dump_iohdrs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * give back the iohdr list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and clear out q->lastio
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(p, sizeof (*p));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_fail_diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set flags, throw away q info
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * clean up what you can
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait for flusher threads to stop (taking into account this may be one)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * takes group_lock, so conf, many, and bitmap may not be held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_fail_diskq(rdc_k_info_t *krdc, int wait, int flag)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!disk queue %s failure", q->disk_queue);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "disk queue failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * quick stop of the flushers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * other cleanup is done on the un-failing of the diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & RDC_DOLOG) /* otherwise, we already have the conf lock */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (p = krdc->group_next; p != krdc; p = p->group_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(p->bitmap_ref, p->bitmap_size * BITS_IN_BYTE *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* RDC_QUEUING is cleared in group_log() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* can't wait for myself to go away, I'm a flusher */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_stamp_diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * write out diskq header info
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * must have disk_qlock held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if rsrvd flag is 0, the nsc_reserve is done
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_stamp_diskq(rdc_k_info_t *krdc, int rsrvd, int failflags)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_stamp_diskq: %s reserve failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_alloc_buf(grp->diskqfd, 0, 1, flags, &head);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!Alloc buf failed for disk queue %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!rdc_stamp_diskq: hdr: %p magic: %x state: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%x head: %d tail: %d size: %d nitems: %d blocks: %d",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!disk queue %s failed rc %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_init_diskq_header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * load initial values into the header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_init_diskq_header(rdc_group_t *grp, dqheader *header)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* save q type if this is a failure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte header->h.state |= (RDC_SHUTDOWN_BAD|type); /* SHUTDOWN_OK on suspend */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* do this last, as this might be a failure. get the kernel state ok */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!init_diskq_hdr: Reserve failed for queue");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nsc_partsize(grp->diskqfd, &header->h.disk_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_unfail_diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the diskq failed for some reason, lets try and re-start it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the old stuff has already been thrown away
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * should just be called from rdc_sync
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* someone else won the race... */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (p = krdc->group_next; p != krdc; p = p->group_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* real i/o to the queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* clear RDC_AUXSYNCIP because we cannot halt a sync that's not here */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rdc_stamp_diskq(krdc, 0, RDC_GROUP_LOCKED | RDC_DOLOG) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SET_QSTATE(dq, RDC_SHUTDOWN_BAD); /* only suspend can write good */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* should be none, but.. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(buf, NSC_MAXPATH, "%s:%s", urdc->secondary.intf,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!Disk Queue Header read failed for %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = rdc_ns_io(krdc->group->diskqfd, NSC_RDBUF, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(buf, NSC_MAXPATH, "%s:%s", urdc->secondary.intf,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!Disk Queue Header read failed(%d) for %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_stop_diskq_flusher
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!stopping flusher threads");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* save the queue info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* lie a little */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* drop locks to allow flushers to die */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_enable_diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * open the diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and stamp the header onto it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* caller has to fail diskq after dropping conf & many locks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_resume_diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * open the diskq and read the header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check diskq magic number */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " incorrect magic number in header", urdc->disk_queue);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else switch (QVERS(q)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* version 1 diskq header, upgrade to 64bit version */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h1 = *(diskq_header1 *)(&group->diskq.disk_hdr.h);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: old version header for diskq %s,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " upgrading to current version", urdc->disk_queue);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " old version Q contains data", urdc->disk_queue);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " diskq header newer than current version",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* okay, current version diskq */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " unknown diskq header version", urdc->disk_queue);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: unable to resume diskq %s,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* bad, until proven not bad */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!rdc_resume_diskq: resuming diskq %s \n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* caller has to set the diskq failed after dropping it's locks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* grab both diskq locks as we are going to kill the flusher */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((krdc->group->rdc_thrnum) && (!IS_QSTATE(q, RDC_STOPPINGFLUSH))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->group->diskq.disk_hdr.h.state &= ~RDC_SHUTDOWN_BAD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->group->diskq.disk_hdr.h.state |= RDC_SHUTDOWN_OK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->group->diskq.disk_hdr.h.state &= ~RDC_QBADRESUME;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* let's make sure that the flusher has stopped.. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* write refcount to the bitmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fill in diskq header info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte krdc->group->diskq.disk_hdr.h.state &= ~RDC_QDISABLEPEND;
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!suspending disk queue\n" QDISPLAY(q));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* to avoid a possible deadlock, release in order, and reacquire */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_group_exit(krdc); /* in case this stamp fails */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* diskq already failed if stamp failed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy orig aio to copy, including the nsc_buf_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (orig->handle == NULL) /* no buf to alloc/copy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_alloc_abuf(orig->pos, orig->len, 0, ©->handle);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_dup_aio: alloc_buf failed (%d)", rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_copy(orig->handle, copy->handle, orig->pos,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_dup_aio: copy buf failed (%d)", rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_qfill_shldwakeup()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0 if the memory queue has filled, and the low water
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mark has not been reached. 0 if diskq is empty.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1 if less than low water mark
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * net_queue mutex is already held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_STATE(urdc, RDC_LOGGING) || IS_STATE(urdc, RDC_SYNCING))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((QNXTIO(dq) == QTAIL(dq)) && !IS_QSTATE(dq, RDC_QFULL)) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!Waking up diskq->memq flusher, flags 0x%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_diskq_enqueue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * enqueue one i/o to the diskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * after appending some metadata to the front
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_diskq_enqueue(rdc_k_info_t *krdc, rdc_aio_t *aio)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t iofbas; /* len of io + io header len */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * there is a thread that is blocking because the queue is full,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't try to set up this write until all is clear
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check before and after for logging or failed queue just
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in case a thread was in flight while the queue was full,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and in the proccess of failing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we're only going to write the header to the queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte numvecs = 2; /* kmem_alloc io header + null terminate */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* find out how many vecs */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte numvecs = rdc_count_vecs(aio->handle->sb_vec) + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this, in conjunction with QTAILBUSY, will prevent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * premature dequeuing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iohdr = (io_hdr *) kmem_zalloc(sizeof (io_hdr), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vec = (nsc_vec_t *) kmem_zalloc(sizeof (nsc_vec_t) * numvecs,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!vec kmem alloc failed");
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!iohdr kmem alloc failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* now add the write itself */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 1, j = 0; bp && bp->sb_vec[j].sv_addr &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i < numvecs; i++, j++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check for queue wrap, then check for overflow */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (IS_STATE(urdc, RDC_LOGGING) && !IS_STATE(urdc, RDC_QUEUING))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_QSTATE(q, RDC_QFULL)) { /* wakeup blocked threads */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just go back to the beginning of the disk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it's not worth the trouble breaking up the write
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!wrapping Q tail: " QDISPLAY(q));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * prepend the write's metadata
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check for tail < head */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't allow any more writes to start
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((!group->rdc_writer) && !IS_STATE(urdc, RDC_LOGGING))
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!enqueue: disk queue %s full",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!qinfo: " QDISPLAYND(q));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if this is a no-block queue, or this is a blocking
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * queue that is not flushing. reset and log
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: disk queue %s full and not flushing. "
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: %s:%s entering logging mode",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update tail pointer, nitems on queue and blocks on queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte INC_QTAIL(q, iofbas); /* increment tail over i/o size + ioheader size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* increment counter for i/o blocks only */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte INC_QBLOCKS(q, (iofbas - FBA_LEN(sizeof (io_hdr))));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if (krdc->io_kstats) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mutex_enter(krdc->io_kstats->ks_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kstat_waitq_enter(KSTAT_IO_PTR(krdc->io_kstats));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mutex_exit(krdc->io_kstats->ks_lock);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_enqueue: %s reserve failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* XXX for now do this, but later pre-alloc handle in enable/resume */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_alloc_buf(group->diskqfd, qtail, iofbas,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!disk queue %s alloc failed(%d) %" NSC_SZFMT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* move vec and write to queue */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!about to write to queue, qbuf: %p, qhead: %d, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "qtail: %d, len: %d contents: %c%c%c%c%c",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!qinfo: " QDISPLAYND(q));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE2(rdc_diskq_nswrite_start, int, qtail, nsc_size_t, iofbas);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE2(rdc_diskq_nswrite_end, int, qtail, nsc_size_t, iofbas);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!disk queue %s write failed %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return what should be returned
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the aio is returned in _rdc_write after status is gathered.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free the iohdr and the vecs */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if no flusher running, start one */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((!krdc->group->rdc_writer) && !IS_STATE(urdc, RDC_LOGGING))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * place this on the pending list of io_hdr's out for flushing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* paranoia */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!ADDING DUPLICATE HEADER %" NSC_SZFMT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mark an io header as flushed. If it is the qhead,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then update the qpointers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free the io_hdrs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called after the bitmap is cleared by flusher
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_clr_iohdr(rdc_k_info_t *krdc, nsc_size_t qpos)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(qpos >= 0); /* assertion to validate change for 64bit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* find outstanding io_hdr */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!iohdr already cleared? "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* mark it as flushed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if it is the head pointer, travel the list updating the queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pointers until the next unflushed is reached, freeing on the way.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!clr_iohdr info: magic %x type %d pos %d"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " qpos %d hpos %d len %d flag 0x%x iostatus %x setid %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hp->dat.magic, hp->dat.type, hp->dat.pos, hp->dat.qpos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte INC_QHEAD(q, FBA_LEN(sizeof (io_hdr)) + hp->dat.len);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!wrapping Q head: " QDISPLAY(q));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get rid of the iohdr */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!clr_iohdr: diskq %s empty, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* wakeup any blocked enqueue threads */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * put in whatever useful checks we can on the io header
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!Bad io header magic %x type %d pos %" NSC_SZFMT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " hpos %" NSC_SZFMT " qpos %" NSC_SZFMT " len %" NSC_SZFMT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->dat.type, hdr->dat.pos, hdr->dat.hpos, hdr->dat.qpos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->dat.len, hdr->dat.flag, hdr->dat.iostatus, hdr->dat.setid);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!Bad io header retrieved");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_netqueue_insert()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * add an item to a netqueue. No locks necessary as it should only
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be used in a single threaded manor. If that changes, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a lock or assertion should be done here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* paranoid check for bit set */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_fill_aio(aio, hdr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * take the pertinent info from an io_hdr and stick it in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * an aio, including seq number, abuf.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_fill_aio(rdc_group_t *grp, rdc_aio_t *aio, io_hdr *hdr, nsc_buf_t *abuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((aio->index = rdc_setid2idx(hdr->dat.setid)) < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_discard_tmpq()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free up the passed temporary queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: no cv's or mutexes have been initialized
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(q, sizeof (*q));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_diskq_buf2queue()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * take a chunk of the diskq, parse it and assemble
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a chain of rdc_aio_t's.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * updates QNXTIO()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_diskq_buf2queue(rdc_group_t *grp, nsc_buf_t **abuf, int index)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: unable to allocate net queue");
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!BUFFOFFENTER %d", bufoff);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get the iohdr information */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!SNDR: unable to alocate net queue header");
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!unable to retrieve i/o data from queue %s "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "at offset %" NSC_SZFMT " bp: %" NSC_SZFMT " bl: %"
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!FAILING QUEUE state: %x",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!VADDR %p, IOADDR %p", vaddr, ioaddr);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!qinfo: " QDISPLAYND(dq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* out of buffer, set nxtio to re read this last hdr */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!nullbuf && ((bufoff + hdr->dat.len) > endobuf)) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!SNDR: net queue aio alloc failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* move to next iohdr in big buf */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!Set id %d not found or no longer "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr = NULL; /* don't accidentally free on break or fail */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* no more buffer, skip the below logic */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((bufoff + FBA_NUM(sizeof (*hdr))) >= endobuf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* abuf = NULL; */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free extraneous header */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * probably won't happen, but if we didn't goto fail, but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we don't contain anything meaningful.. return NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and let the flusher or the sleep/wakeup routines
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte netq->net_qtail->orig_len = nullblocks; /* overload */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* the never can happen case ... */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fail) { /* real failure, not just state change */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_diskq_buf2queue: failing disk queue %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_diskq_unqueue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove one chunk from the diskq belonging to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_k_info[index]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * updates the head and tail pointers in the disk header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but does not write. The header should be written on ack
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flusher should free whatever..
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (group->diskqfd == NULL) /* we've been disabled */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iohdr = kmem_zalloc(sizeof (*iohdr), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_set_qbusy(q); /* make sure no one disables the queue */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_unqueue: %s reserve failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_STATE(urdc, RDC_DISKQ_FAILED) || IS_STATE(urdc, RDC_LOGGING)) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!wrapping Q nxtio: " QDISPLAY(q));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* read the metainfo at q->nxt_io first */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have to drop the lock here, sigh. Cannot block incoming io
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we have to wait until after this read to find out how
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * much to increment QNXTIO. Might as well grab the seq then too
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((qhead == LASTQTAIL(q)) && (IS_QSTATE(q, QTAILBUSY))) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!Qtail busy delay lastqtail: %d", qhead);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!unable to retrieve i/o data from queue %s"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " at offset %" NSC_SZFMT " rc %d", urdc->disk_queue,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* XXX process buffer here, creating rdc_aio_t's */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update the next pointer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte INC_QNXTIO(q, (FBA_LEN(sizeof (io_hdr)) + iohdr->dat.len));
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!unqueued iohdr from %d pos: %d len: %d flag: %d "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "iostatus: %d setid: %d time: %d", qhead, p->pos, p->len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* now that we know how much to get (iohdr.dat.len), get it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_alloc_buf(group->diskqfd, qhead + 1, iohdr->dat.len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* and get somewhere to keep it for a bit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc1 = nsc_alloc_abuf(qhead + 1, iohdr->dat.len, 0, &abuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!RDC_SUCCESS(rc) || !RDC_SUCCESS(rc1)) { /* uh-oh */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!disk queue %s read failure",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* move it on over... */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc2 = nsc_copy(buf, abuf, qhead + 1, qhead + 1, iohdr->dat.len);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!nsc_copy failed for diskq unqueue");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* let go of the real buf, we've got the abuf */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Hack in the original sb_pos */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* skip the RDC_HANDLE_LIMITS check */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* set up the rest of the aio values, seq set above ... */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_diskq_unqueue: index < 0");
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!stamping diskq header:\n"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "magic: %x\nstate: %d\nhead_offset: %d\n"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "tail_offset: %d\ndisk_size: %d\nnitems: %d\nblocks: %d\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->magic, h->state, h->head_offset, h->tail_offset,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " contents: %c%c%c%c%c pos: %d len: %d",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!UNQUEUING, NULL " QDISPLAY(q));
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!diskq_unqueue: failing diskq");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* same diskq different group */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* last, but not least, lets see if someone is getting really funky */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((strcmp(set->disk_queue, set->primary.file) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (strcmp(set->disk_queue, set->primary.bitmap) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_calc_len()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns the size of the diskq that can be read for dequeuing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * always <= RDC_MAX_DISKQREAD
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ---H-----N-----T--- */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = min(RDC_MAX_DISKQREAD, QTAIL(dq) - QNXTIO(dq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ---T-----H-----N--- */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = min(RDC_MAX_DISKQREAD, QWRAP(dq) - QNXTIO(dq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* should never happen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = min(RDC_MAX_DISKQREAD, QSIZE(dq) - QNXTIO(dq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = min(RDC_MAX_DISKQREAD, QWRAP(dq) - QNXTIO(dq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return ((int)len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lie a little if we can, so we don't get tied up in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_wait_dbuf() on the next read. sb_len MUST be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * restored before nsc_free_buf() however, or we will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be looking at memory leak city..
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so update the entire queue with the info as well
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and the one that ends up freeing it, can fix the len
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * IMPORTANT: This assumes that we are not cached, in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 3.2 caching was turned off for data volumes, if that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * changes, then this must too
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (q->blocks + q->nitems - q->net_qtail->orig_len))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->sb_len = (q->blocks + q->nitems - q->net_qtail->orig_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (p);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_read_diskq_buf()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * read a large as possible chunk of the diskq into a nsc_buf_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and convert it to a net_queue of rdc_aio_t's to be appended
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the group's netqueue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_set_qbusy(dq); /* prevent disables on the queue */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!rdc_readdiskqbuf: %s reserve failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_clr_qbusy(dq); /* prevent disables on the queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * real corner case here, we need to let the flusher wrap first.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we've gotten too far ahead, so just delay and try again
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_QSTATE(dq, QNXTIOWRAPD) && AUXQWRAP(dq)) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!wrapping Q nxtio: " QDISPLAY(dq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* read the metainfo at q->nxt_io first */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((len <= 0) || (IS_STATE(urdc, RDC_LOGGING)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a write could be trying to get on the queue, or if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the queue is really really small, a complete image
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of it could be on the net queue waiting for flush.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the latter being a fairly stupid scenario and a gross
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * misconfiguration.. but what the heck, why make the thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * thrash around.. just pause a little here.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE3(rdc_read_diskq_buf_bail4, int, len,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana int, rdc_get_vflags(urdc), int, nq->qfflags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE2(rdc_calc_len, int, len, int, (int)QNXTIO(dq));
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!CALC_LEN(%d) h:%d n%d t%d, w%d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len, QHEAD(dq), QNXTIO(dq), QTAIL(dq), QWRAP(dq));
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_CONT, "!qinfo: " QDISPLAYND(dq));
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!Qtail busy delay nxtio %d len %d "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "lastqtail: %d", QNXTIO(dq), len, LASTQTAIL(dq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one last check to see if we have gone logging, or should.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we may have released the mutex above, so check again
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE2(rdc_buf2q_preread, int, offset, int, len);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!disk queue %s read failure pos %" NSC_SZFMT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE2(rdc_buf2q_postread, int, offset, nsc_size_t, buf->sb_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * convert buf to a net_queue. buf2queue will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update the QNXTIO pointer for us, based on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the last readable queue item
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!QBUF p: %d l: %d p+l: %d users: %d qblocks: %d ",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "qitems: %d WASTED: %d", buf->sb_pos, buf->sb_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->sb_pos+buf->sb_len, buf->sb_user, tmpnq?tmpnq->blocks:-1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpnq?((buf->sb_len-tmpnq->nitems) - tmpnq->blocks):-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE3(rdc_buf2que_returned, net_queue *, tmpnq?tmpnq:0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we don't need to retain the buf */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_dequeue()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * removes the head of the memory queue
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana if (q->nitems != 0 || q->blocks != 0 || q->net_qtail != 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "rdc_dequeue(1): q %p, q blocks %" NSC_SZFMT
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana " , nitems %" NSC_SZFMT ", qhead %p qtail %p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (!IS_STATE(urdc, RDC_SYNCING)) && (QNITEMS(dq) > 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* aio remove from q */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana if (q->nitems != 0 || q->blocks != 0 || q->net_qtail != 0) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_PANIC, "rdc_dequeue(2): q %p, q blocks %"
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana " , qhead %p qtail %p",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (void *) q->net_qhead, (void *) q->net_qtail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * clear EAGAIN if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * logging or q filler thread is sleeping or stopping altogether
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or if q filler thread is dead already
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or if syncing, this will return a null aio, with no error code set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * telling the flusher to die
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (q->qfflags & (RDC_QFILLSLEEP | RDC_QFILLSTOP)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (IS_QSTATE(dq, (RDC_QDISABLEPEND | RDC_STOPPINGFLUSH))) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_qfill_shldsleep()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns 1 if the qfilling code should cv_wait() 0 if not.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reasons for going into cv_wait();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * there is nothing in the diskq to flush to mem.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the memory queue has gotten too big and needs more flushing attn.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!Sleeping diskq->memq flusher: QFILLSLEEP idx: %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_STATE(urdc, RDC_LOGGING) || IS_STATE(urdc, RDC_SYNCING)) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!Sleeping diskq->memq flusher: Sync|Log (0x%x)"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((QNXTIO(dq) == QTAIL(dq)) && !IS_QSTATE(dq, RDC_QFULL)) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!Sleeping diskq->memq flusher: QEMPTY");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* stuck flushers ? */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!Sleeping diskq->memq flusher: memq full:"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_join_netqueues(a, b)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * appends queue b to queue a updating all the queue info
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as it is assumed queue a is the important one,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it's mutex must be held. no one can add to queue b
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_PANIC, "rdc filler: q %p, qhead 0, "
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana " q blocks %" NSC_SZFMT ", nitems %" NSC_SZFMT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rdc_qfiller_thr() single thread that moves
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data from the diskq to a memory queue for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the flusher to pick up.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* race with log, redundant yet paranoid */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sleep for a while if we can.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the enqueuing or flushing code will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wake us if if necessary.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!rdc_qfiller_thr: recieved kill signal");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte q->qfill_sleeping = RDC_QFILL_DEAD; /* the big sleep */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!rdc_qfiller_thr stopping");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!diskq || urdc->disk_queue[0]) { /* how'd that happen? */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!NULL diskq in _rdc_add_diskq");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if the enable fails, this is bzero'ed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(urdc->disk_queue, diskq, NSC_MAXPATH);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!adding diskq to group %s", urdc->group_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (kp = krdc->group_next; kp != krdc; kp = kp->group_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(up->disk_queue, diskq, NSC_MAXPATH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* size lives in the diskq structure, already set by enable */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * add a diskq to an existing set/group
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_add_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EQWRONGMODE, urdc->primary.intf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* make sure that we have enough bitmap vol */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!rdc_open_diskq: Bitmap reserve failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EQALREADY, urdc->primary.intf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (uparms->options & RDC_OPT_SECONDARY) { /* how'd we get here? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rdc_diskq_inuse(uparms->rdc_set, uparms->rdc_set->disk_queue)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EQNOADD, uparms->rdc_set->disk_queue);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_init_diskq_header(group, &group->diskq.disk_hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * inititalize the disk queue. This is a destructive
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * operation that will not check for emptiness of the queue.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_init_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EALREADY, uset->primary.file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!IS_STATE(urdc, RDC_SYNCING) && !IS_STATE(urdc, RDC_LOGGING)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EQUEISREP, urdc->disk_queue);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a couple of big "ifs" here. in the first implementation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * neither of these will be possible. This will come into
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * play when we persist the queue across reboots
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (kp = krdc->group_next; kp != krdc; kp = kp->group_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* generic queue failure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EQINITFAIL, urdc->disk_queue);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!disabling disk queue %s", urdc->disk_queue);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_close the queue and zero out the queue name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (p = krdc->group_next; p != krdc; p = p->group_next) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!_rdc_kill_diskq: enabling memory queue");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove this diskq regardless of whether it is draining or not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stops the flusher by invalidating the qdata (ie, instant empty)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove the disk qeueue from the group, leaving the group with a memory
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_kill_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EALREADY, rdc_set->primary.file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EQNOQUEUE, rdc_set->primary.intf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if (!IS_STATE(urdc, RDC_LOGGING)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * spcs_s_add(kstatus, RDC_EQNOTLOGGING,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * uparms->rdc_set->disk_queue);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rc = RDC_EQNOTLOGGING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * goto failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_unintercept_diskq(krdc->group); /* stop protecting queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_group_enter(krdc); /* to prevent further flushing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove a diskq from a group.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * removal of a diskq from a set, or rather
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a set from a queue, is done by reconfigging out
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the group. This removes the diskq from a whole
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * group and replaces it with a memory based queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NUM_RETRIES 15 /* Number of retries to wait if no progress */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_rem_diskq(rdc_config_t *uparms, spcs_s_info_t kstatus)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spcs_s_add(kstatus, RDC_EALREADY, uparms->rdc_set->primary.file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there is no group or diskq configured, we can leave now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(group = krdc->group) || !(diskq = &group->diskq))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wait if not QEMPTY or threads still active
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Capture counters to determine if progress is being made
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Has the group or disk queue gone away while delayed?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(group = krdc->group) || !(diskq = &group->diskq))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Are we still seeing progress?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (blocks == QBLOCKS(diskq) && threads == group->rdc_thrnum) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No progress see, decrement retry counter
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No progress seen, increment retry counter
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reset counter, as we've made progress