Esempio n. 1
0
static int disk_resume(struct dirty_log *log)
{
	int r = 0;
	unsigned i;
	struct log_c *lc = (struct log_c *) log->context;
	size_t size = lc->bitset_uint32_count * sizeof(uint32_t);

	/* 
	 * Read the disk header, but only if we know it is good.
	 * Assume the worst in the event of failure.
	 */
	if (!lc->log_dev_failed && (r = read_header(lc))) {
		DMWARN("Read %s failed on mirror log device, %s.",
		      r ? "header" : "bits", lc->log_dev->name);
		fail_log_device(lc);
		lc->header.nr_regions = 0;
	}

	/* set or clear any new bits -- device has grown */
	if (lc->sync == NOSYNC)
		for (i = lc->header.nr_regions; i < lc->region_count; i++)
			/* FIXME: amazingly inefficient */
			log_set_bit(lc, lc->clean_bits, i);
	else
		for (i = lc->header.nr_regions; i < lc->region_count; i++)
			/* FIXME: amazingly inefficient */
			log_clear_bit(lc, lc->clean_bits, i);

	/* clear any old bits if device has shrunk */
	for (i = lc->region_count; i % 32; i++)
		log_clear_bit(lc, lc->clean_bits, i);

	/* copy clean across to sync */
	memcpy(lc->sync_bits, lc->clean_bits, size);
	lc->sync_count = count_bits32(lc->clean_bits, lc->bitset_uint32_count);
	lc->sync_search = 0;

	/* set the correct number of regions in the header */
	lc->header.nr_regions = lc->region_count;

	/* write out the log */
	if ((r = write_header(lc))) {
		DMWARN("Write header failed on mirror log device, %s.",
		      lc->log_dev->name);
		fail_log_device(lc);
	} else
		restore_log_device(lc);

	return r;
}
Esempio n. 2
0
static int disk_resume(struct dirty_log *log)
{
	int r;
	unsigned i;
	struct log_c *lc = (struct log_c *) log->context;
	size_t size = lc->bitset_uint32_count * sizeof(uint32_t);

	/* read the disk header */
	r = read_header(lc);
	if (r)
		return r;

	/* read the bits */
	r = read_bits(lc);
	if (r)
		return r;

	/* set or clear any new bits */
	if (lc->sync == NOSYNC)
		for (i = lc->header.nr_regions; i < lc->region_count; i++)
			/* FIXME: amazingly inefficient */
			log_set_bit(lc, lc->clean_bits, i);
	else
		for (i = lc->header.nr_regions; i < lc->region_count; i++)
			/* FIXME: amazingly inefficient */
			log_clear_bit(lc, lc->clean_bits, i);

	/* copy clean across to sync */
	memcpy(lc->sync_bits, lc->clean_bits, size);
	lc->sync_count = count_bits32(lc->clean_bits, lc->bitset_uint32_count);

	/* write the bits */
	r = write_bits(lc);
	if (r)
		return r;

	/* set the correct number of regions in the header */
	lc->header.nr_regions = lc->region_count;

	/* write the new header */
	return write_header(lc);
}
Esempio n. 3
0
static int disk_resume(struct dm_dirty_log *log)
{
    int r;
    unsigned i;
    struct log_c *lc = (struct log_c *) log->context;
    size_t size = lc->bitset_uint32_count * sizeof(uint32_t);

    /* read the disk header */
    r = read_header(lc);
    if (r) {
        DMWARN("%s: Failed to read header on dirty region log device",
               lc->log_dev->name);
        fail_log_device(lc);
        /*
         * If the log device cannot be read, we must assume
         * all regions are out-of-sync.  If we simply return
         * here, the state will be uninitialized and could
         * lead us to return 'in-sync' status for regions
         * that are actually 'out-of-sync'.
         */
        lc->header.nr_regions = 0;
    }

    /* set or clear any new bits -- device has grown */
    if (lc->sync == NOSYNC)
        for (i = lc->header.nr_regions; i < lc->region_count; i++)
            /* FIXME: amazingly inefficient */
            log_set_bit(lc, lc->clean_bits, i);
    else
        for (i = lc->header.nr_regions; i < lc->region_count; i++)
            /* FIXME: amazingly inefficient */
            log_clear_bit(lc, lc->clean_bits, i);

    /* clear any old bits -- device has shrunk */
    for (i = lc->region_count; i % (sizeof(*lc->clean_bits) << BYTE_SHIFT); i++)
        log_clear_bit(lc, lc->clean_bits, i);

    /* copy clean across to sync */
    memcpy(lc->sync_bits, lc->clean_bits, size);
    lc->sync_count = count_bits32(lc->clean_bits, lc->bitset_uint32_count);
    lc->sync_search = 0;

    /* set the correct number of regions in the header */
    lc->header.nr_regions = lc->region_count;

    header_to_disk(&lc->header, lc->disk_header);

    /* write the new header */
    r = rw_header(lc, WRITE);
    if (!r) {
        r = flush_header(lc);
        if (r)
            lc->log_dev_flush_failed = 1;
    }
    if (r) {
        DMWARN("%s: Failed to write header on dirty region log device",
               lc->log_dev->name);
        fail_log_device(lc);
    }

    return r;
}