fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
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 *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
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 *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cred.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/buf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsc_thread.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_bcache.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_trace.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_io.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_bio.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_ft.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_misc.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_pcu.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PCU (aka UPS) handling -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define bitmap_next cc_dirty_link
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define bitmap_tail cc_dirty_next
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define anon_next cc_dirty_link
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define anon_tail cc_dirty_next
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define anon_data cc_data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct bitmap {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *bmps;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int bmaps_per_block;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int inuse; /* In use in the _last_ block */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define SDBC_PCU_MAXSWAPIL 3 /* Watch for 5 fields in ioctl arg. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct swapfiles {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int nswpf; /* Number of filenames */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int colsize; /* In cache blocks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *names[SDBC_PCU_MAXSWAPIL];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sdbc_pcu_cleanup(struct swapfiles *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Forward declare functions containing 64-bit argument types to enforce
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * type-checking.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int add_bitmap_entry(struct bitmap *bmp, _sd_bitmap_t bits, int any_fail,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t fba_num);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int flush_bitmap_list(struct bitmap *bmp, dev_t dev, nsc_off_t *blkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int flush_centry_list(_sd_cd_info_t *cdi, _sd_cctl_t *dirty, dev_t dev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t *blkno, int failed, struct bitmap *bmaps);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int flush_hdr(_sd_cctl_t *hdr, dev_t dev, nsc_off_t blkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int flush_anon_list(_sd_cctl_t *anon_list, dev_t dev, nsc_off_t *blkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void sdbc_anon_copy(caddr_t src, nsc_size_t len, _sd_cctl_t *dest,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t dest_off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void sdbc_anon_get(_sd_cctl_t *src, nsc_off_t src_off, caddr_t dest,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic _sd_cctl_t *sdbc_get_anon_list(nsc_size_t bytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int got_hint; /* did we capture hint at power_lost */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic unsigned int wrthru_hint; /* saved hint at power_lost */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int saw_power_lost;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar _sdbc_shutdown_in_progress;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct swapfiles swfs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sdbc_get_anon_list - allocate a set of anonymous cache block
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * entries that can pretend to be a single blocks of data holding
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a virtual character array holding "bytes" entries.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns - the cache block heading the chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic _sd_cctl_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesdbc_get_anon_list(nsc_size_t bytes)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *list, *prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t i, blks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blks = (bytes + CACHE_BLOCK_SIZE - 1) / CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < blks; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(list->cc_data, CACHE_BLOCK_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->anon_next = prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sdbc_anon_get - gets "len" bytes of data virtual character array represented
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by "src" begining at index "dest_off" and copy to buffer "dest".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dest - pointer to our virtual array (chain of cache blocks).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dest_off - first location to copy data to.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * src - pointer to data to copy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * len - the number of bytes of data to copy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesdbc_anon_get(_sd_cctl_t *src, nsc_off_t src_off, caddr_t dest, nsc_size_t len)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t nlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t blk_start, blk_end;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blk_start = src_off / CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blk_end = (src_off + len) / CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < blk_start; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src = src->anon_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_off -= CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlen = min(len, CACHE_BLOCK_SIZE - src_off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&src->anon_data[src_off], dest, (size_t)nlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 1; i < blk_end - blk_start; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(src->anon_data, &dest[nlen], (size_t)CACHE_BLOCK_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlen += CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src = src->anon_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nlen != len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(src->anon_data, &dest[nlen], (size_t)(len - nlen));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sdbc_anon_copy - copies "len" bytes of data from "src" to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * virtual character array represented by "dest" begining at index
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * "dest_off".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * src - pointer to data to copy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * len - the number of bytes of data to copy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dest - pointer to our virtual array (chain of cache blocks).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dest_off - first location to copy data to.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesdbc_anon_copy(caddr_t src, nsc_size_t len, _sd_cctl_t *dest,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t dest_off)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t nlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t blk_start, blk_end;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blk_start = dest_off / CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blk_end = (dest_off + len) / CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < blk_start; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest = dest->anon_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_off -= CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlen = min(len, CACHE_BLOCK_SIZE - dest_off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(src, &dest->anon_data[dest_off], (size_t)nlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 1; i < blk_end - blk_start; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&src[nlen], dest->anon_data, (size_t)CACHE_BLOCK_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlen += CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest = dest->anon_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nlen != len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&src[nlen], dest->anon_data, (size_t)(len - nlen));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flush_anon_list - flush a chain of anonymous cache blocks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the state file. Anonymous chains of cache blocks represent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * virtual arrays for the state flushing code and can contain
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * various types of data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anon_list - chain of cache blocks to flush.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev - the state file device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * blkno - on input the cache block number to begin writing at.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * On exit the next cache block number following the data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just written.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns - 0 on success, error number on failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteflush_anon_list(_sd_cctl_t *anon_list,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t dev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t *blkno)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t bcnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (anon_list == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte BLK_TO_FBA_NUM(1), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sd_add_fba(bp, &anon_list->cc_addr, 0, BLK_FBAS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sd_start_io(bp, NULL, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*blkno)++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A failure here is death. This is harsh but not sure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * what else to do
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != NSC_DONE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = anon_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte anon_list = anon_list->anon_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_centry_release(prev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (anon_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "sdbc(flush_anon_list) %" NSC_SZFMT "\n", bcnt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * start_bitmap_list - allocate an anonymous cache block entry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to anchor a chain of cache blocks representing a virtual
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * array of bitmap entries.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns - the cache block heading the chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestart_bitmap_list(struct bitmap *bmp, int bpb)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(list->cc_data, CACHE_BLOCK_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->bitmap_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->bitmap_tail = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bmp->bmps = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bmp->inuse = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bmp->bmaps_per_block = bpb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * add_bitmap_entry - Add a bitmap entry to the chain of bitmap
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * entries we are creating for cd's entry in the state file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bitmaps are stored in a chain of anonymous cache blocks. Each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cache block can hold bmaps_per_block in it. As each block is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * filled a new block is added to the tail of the chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list - the chain of cache blocks containing the bitmaps.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bits - the bitmap entry to add.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any_fail - flag saying whether the data corresponding to this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bitmap entry had previously failed going to disk.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fba_num - FBA number corresponding to the entry.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns - 0 on success, error number on failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteadd_bitmap_entry(struct bitmap *bmp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_bitmap_t bits, int any_fail, nsc_off_t fba_num)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_pwf_bitmap_t *bmap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *list = bmp->bmps;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bmap = (sdbc_pwf_bitmap_t *)list->bitmap_tail->cc_data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bmp->inuse == bmp->bmaps_per_block) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *nlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlist = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(nlist->cc_data, CACHE_BLOCK_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlist->bitmap_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nlist->bitmap_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->bitmap_tail->bitmap_next = nlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->bitmap_tail = nlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bmp->inuse = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i = bmp->inuse++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bmap->bitmaps[i].fba_num = fba_num;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bmap->bitmaps[i].dirty = bits;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bmap->bitmaps[i].errs = (char)any_fail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flush_bitmap_list - flush a chain of anonymous cache blocks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * containing the dirty/valid bitmaps for a set of cache blocks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * b_list - the chain of bitmap data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev - the state file device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * blkno - on input the cache block number to begin writing at.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * On exit the next cache block number following the data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just written.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns - 0 on success, error number on failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteflush_bitmap_list(struct bitmap *bmp, dev_t dev, nsc_off_t *blkno)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *b_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int bcnt = 0; /* P3 temp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((b_list = bmp->bmps) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte BLK_TO_FBA_NUM(1), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sd_add_fba(bp, &b_list->cc_addr, 0, BLK_FBAS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sd_start_io(bp, NULL, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*blkno)++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A failure here is death. This is harsh but not sure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * what else to do
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != NSC_DONE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = b_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte b_list = b_list->bitmap_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_centry_release(prev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (b_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "sdbc(flush_bitmap_list) %d\n", bcnt); /* P3 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flush_centry_list - flush a chain of cache blocks for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cache descriptor described by "cdi" to the state file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In addition the bitmaps describing the validity and dirty
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state of each entry are captured to the bitmap chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cdi - pointer to description of the cd we are writing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dirty - chain of dirty cache blocks to flush (linked
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by dirty_next (sequential) and dirty_link (disjoint).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev - the state file device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * blkno - on input the cache block number to begin writing at.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * On exit the next cache block number following the data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just written.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * failed - a flag noting whether these blocks had already
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * been attempted to write to their true destination and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * failed. (i.e. is the chain from fail_head).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bmaps - a chain of anonymous cache blocks containing all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the dirty/valid bitmaps for the cache blocks we write.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns - 0 on success, error number on failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteflush_centry_list(_sd_cd_info_t *cdi,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *dirty,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t dev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t *blkno,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int failed,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct bitmap *bmaps)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *cc_ent;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t count; /* count of cache blocks in a sequential chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int bcnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dirty == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&cdi->cd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * each cache block is written to the disk regardless of its
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * valid/dirty masks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cc_ent = dirty;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cc_ent = cc_ent->cc_dirty_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(*blkno),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte BLK_TO_FBA_NUM(count), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cc_ent = dirty;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sd_add_fba(bp, &cc_ent->cc_addr, 0, BLK_FBAS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = add_bitmap_entry(bmaps,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cc_ent->cc_dirty | cc_ent->cc_toflush, failed,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cc_ent = cc_ent->cc_dirty_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *blkno += count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sd_start_io(bp, NULL, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A failure here is death. This is harsh but not sure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * what else to do
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != NSC_DONE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcnt += count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dirty = dirty->cc_dirty_link;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (dirty);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "sdbc(flush_centry_list) %d\n", bcnt); /* P3 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&cdi->cd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flush_hdr - Flush the state file header to the disk partition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * "dev" at FBA "blkno". Return the result of the i/o operation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hdr - a cache block containing the header.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev - the state file device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * blkno - cache block position to write the header.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns - 0 on success, error number on failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteflush_hdr(_sd_cctl_t *hdr, dev_t dev, nsc_off_t blkno)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp = sd_alloc_iob(dev, BLK_TO_FBA_NUM(blkno), BLK_TO_FBA_NUM(1), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sd_add_fba(bp, &hdr->cc_addr, 0, BLK_FBAS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = sd_start_io(bp, NULL, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_centry_release(hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_power_flush - flushd the state of sdbc to the state "file"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on the system disk. All dirty blocks (in progress, unscheduled,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * failed) are written along with the bitmap for each block. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data is written using normal sdbc i/o via anonymous cache blocks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is done to simplify the job here (and to limit memory
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * requests) at the expense of making the recovery programs more
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * complex. Since recovery is done at user level this seems to be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a good trade off.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns: 0 on success, error number on failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_power_flush(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *name_pool;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int string_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_pwf_hdr_t *hdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *hdrblk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct bitmap bmap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cd_info_t *cdi;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int open_files;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *file_pool;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_pwf_desc_t current;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_fd_t *state_fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t state_rdev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int devmaj, devmin;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t blkno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte long len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte long total_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int pending;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Force wrthru just in case SLM software didn't really send us a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * warning. (Also makes for easier testing)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* disable all (dangerous) cache entry points */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "sdbc(sdbc_power_flush) hint set..\n"); /* P3 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_shutdown_in_progress = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sdbc_io && (rc = nsc_unregister_io(sdbc_io, NSC_PCATCH)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this is bad, in theory we could just busy-out all our
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * interfaces and continue.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "sdbc(_sdbc_power_flush) couldn't unregister i/o %d", rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_io = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* wait for all i/o to finish/timeout ? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pending = _sdbc_wait_pending()) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "sdbc(_sdbc_power_flush) %d I/Os were"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " pending at power shutdown", pending);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "sdbc(sdbc_power_flush) over pending\n"); /* P3 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* prevent any further async flushing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_flush_deconfigure();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * At this point no higher level clients should be able to get thru.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Failover i/o from the other node is our only other concern as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * far as disturbing the state of sdbc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* figure out the names for the string pool */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte string_size = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte open_files = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi = _sd_cache_files;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->cd_info == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->cd_info->sh_alloc == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte open_files++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte string_size += strlen(cdi->cd_info->sh_filename) + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (++cdi != &_sd_cache_files[sdbc_max_devs]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (open_files == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdrblk = sdbc_centry_alloc_blks(_CD_NOHASH, 0, 1, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(hdrblk->cc_data, CACHE_BLOCK_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr = (sdbc_pwf_hdr_t *)hdrblk->cc_data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->magic = SDBC_PWF_MAGIC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->alignment = CACHE_BLOCK_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->cd_count = open_files;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX bmap_size is redundant */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->bmap_size = CACHE_BLOCK_SIZE / sizeof (sdbc_pwf_bitmap_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name_pool = sdbc_get_anon_list(string_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte file_pool = sdbc_get_anon_list(sizeof (sdbc_pwf_desc_t) * open_files);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte open_files = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi = _sd_cache_files;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->cd_info == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->cd_info->sh_alloc == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = strlen(cdi->cd_info->sh_filename) + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy the name to string pool */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_anon_copy(cdi->cd_info->sh_filename,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len, name_pool, total_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&current, sizeof (current));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte current.name = total_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_anon_copy((caddr_t)&current, sizeof (current), file_pool,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte open_files * sizeof (sdbc_pwf_desc_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte open_files++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_len += len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (++cdi != &_sd_cache_files[sdbc_max_devs]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* flush dirty data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (swfs.nswpf == 0 || swfs.names[0] == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "sdbc(_sdbc_power_flush): State file"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " is not configured");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ENODEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(state_fd =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_open(swfs.names[0], NSC_DEVICE, NULL, NULL, &rc)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !nsc_getval(state_fd, "DevMaj", (int *)&devmaj) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !nsc_getval(state_fd, "DevMin", (int *)&devmin)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state_fd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nsc_close(state_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We are hosed big time. We can't get device to write the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state file opened.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "sdbc(_sdbc_power_flush): Couldn't "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "open %s for saved state file", swfs.names[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state_rdev = makedevice(devmaj, devmin);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blkno = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->string_pool = blkno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = flush_anon_list(name_pool, state_rdev, &blkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->descriptor_pool = blkno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = flush_anon_list(file_pool, state_rdev, &blkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iterate across all devices, flushing the data and collecting bitmaps
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte open_files = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cdi = _sd_cache_files;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi != &_sd_cache_files[sdbc_max_devs]; cdi++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t blk2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t fp_off;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->cd_info == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->cd_info->sh_alloc == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* retrieve the file description so we can update it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_off = (open_files++) * sizeof (sdbc_pwf_desc_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_anon_get(file_pool, fp_off,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&current, sizeof (current));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte current.blocks = blkno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->cd_io_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Need to wait for this to timeout?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Seems like worst case we just write the data twice
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so we should be ok.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte start_bitmap_list(&bmap, hdr->bmap_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Flush the enqueued dirty data blocks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) flush_centry_list(cdi, cdi->cd_dirty_head, state_rdev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &blkno, 0, &bmap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->cd_dirty_head = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->cd_dirty_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Flush the failed dirty data blocks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) flush_centry_list(cdi, cdi->cd_fail_head, state_rdev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &blkno, 1, &bmap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->cd_fail_head = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Flush the in progress dirty data blocks. These really should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * really be null by now. Worst case we write the data again
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on recovery as we know the dirty masks won't change since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flusher is stopped.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) flush_centry_list(cdi, cdi->cd_io_head, state_rdev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &blkno, 0, &bmap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->cd_io_head = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->cd_io_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte current.bitmaps = blkno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte current.nblocks = blkno - current.blocks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) flush_bitmap_list(&bmap, state_rdev, &blkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* update the current cd's file description */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_anon_copy((caddr_t)&current, sizeof (current), file_pool,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blk2 = hdr->descriptor_pool;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = flush_anon_list(file_pool, state_rdev, &blk2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(_SunOS_5_6)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->dump_time = ddi_get_time();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hdr->dump_time = hrestime.tv_sec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* write the header at front and back */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) flush_hdr(hdrblk, state_rdev, blkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) flush_hdr(hdrblk, state_rdev, 0L);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* P3 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "sdbc(sdbc_power_flush) %" NSC_SZFMT " total\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blkno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecleanup:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_power_lost - System is running on UPS power we have "rideout"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * minutes of power left prior to shutdown. Get into a state where we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will be ready should we need to shutdown.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rideout - minutes of power left prior to shutdown.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_power_lost(int rideout)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "sdbc(_sdbc_power_lost) battery time "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "remaining %d minute(s)", rideout);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte got_hint = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_get_node_hint(&wrthru_hint))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte got_hint = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "sdbc(_sdbc_power_lost) got hint %d "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "hint 0x%x", got_hint, wrthru_hint);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _sd_set_node_hint(NSC_FORCED_WRTHRU);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte saw_power_lost = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_power_ok - System is back running on mains power after
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * seeing a power fail. Return to normal power up operation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_power_ok(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "sdbc(_sdbc_power_ok) power ok");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (saw_power_lost && got_hint) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In theory we have a race here between _sdbc_power_lost
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and here. However it is expected that power ioctls that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cause these to be generated are sequential in nature
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so there is no race.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte saw_power_lost = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (wrthru_hint & _SD_WRTHRU_MASK)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _sd_set_node_hint(wrthru_hint & _SD_WRTHRU_MASK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _sd_clear_node_hint(_SD_WRTHRU_MASK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_power_down - System is running on UPS power and we must stop
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * operation as the machine is now going down. Schedule a shutdown
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When we return all cache activity will be blocked.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_power_down(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "sdbc(_sdbc_power_down) powering down...");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _sdbc_power_flush();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Configure safe store from the general cache configuration ioctl.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_pcu_config(int namec, char **namev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (swfs.nswpf != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This should not happen because cache protects itself
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from double configuration in sd_conf.c.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "sdbc(_sdbc_pcu_config) double "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "configuration of Safe Store\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte swfs.colsize = 32; /* No way to configure in the general ioctl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < namec; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((swfs.names[i] = kmem_alloc(strlen(namev[i])+1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_pcu_cleanup(&swfs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte swfs.nswpf++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(swfs.names[i], namev[i]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_pcu_unload()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_pcu_cleanup(&swfs);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Destructor for struct swapfiles.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_pcu_cleanup(struct swapfiles *swp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *s;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < swp->nswpf; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((s = swp->names[i]) != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(s, strlen(s)+1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte swp->names[i] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte swp->nswpf = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}