Exemplo n.º 1
0
static void core_complete_resync_work(struct dirty_log *log, region_t region,
				      int success)
{
	struct log_c *lc = (struct log_c *) log->context;

	log_clear_bit(lc, lc->recovering_bits, region);
	if (success) {
		log_set_bit(lc, lc->sync_bits, region);
                lc->sync_count++;
        } else if (log_test_bit(lc->sync_bits, region)) {
		lc->sync_count--;
		log_clear_bit(lc, lc->sync_bits, region);
	}
}
Exemplo n.º 2
0
static void core_set_region_sync(struct dm_dirty_log *log, region_t region,
				 int in_sync)
{
	struct log_c *lc = (struct log_c *) log->context;

	log_clear_bit(lc, lc->recovering_bits, region);
	if (in_sync) {
		log_set_bit(lc, lc->sync_bits, region);
                lc->sync_count++;
        } else if (log_test_bit(lc->sync_bits, region)) {
		lc->sync_count--;
		log_clear_bit(lc, lc->sync_bits, region);
	}
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;

	/* 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);

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

	/* write the new header */
	return write_header(lc);
}
Exemplo n.º 5
0
static int disk_flush(struct dm_dirty_log *log)
{
	int r, i;
	struct log_c *lc = log->context;

	/* only write if the log has changed */
	if (!lc->touched_cleaned && !lc->touched_dirtied)
		return 0;

	if (lc->touched_cleaned && log->flush_callback_fn &&
	    log->flush_callback_fn(lc->ti)) {
		/*
		 * At this point it is impossible to determine which
		 * regions are clean and which are dirty (without
		 * re-reading the log off disk). So mark all of them
		 * dirty.
		 */
		lc->flush_failed = 1;
		for (i = 0; i < lc->region_count; i++)
			log_clear_bit(lc, lc->clean_bits, i);
	}

	r = rw_header(lc, REQ_OP_WRITE);
	if (r)
		fail_log_device(lc);
	else {
		if (lc->touched_dirtied) {
			r = flush_header(lc);
			if (r) {
				lc->log_dev_flush_failed = 1;
				fail_log_device(lc);
			} else
				lc->touched_dirtied = 0;
		}
		lc->touched_cleaned = 0;
	}

	return r;
}
Exemplo n.º 6
0
static void core_mark_region(struct dm_dirty_log *log, region_t region)
{
	struct log_c *lc = (struct log_c *) log->context;
	log_clear_bit(lc, lc->clean_bits, region);
}
Exemplo n.º 7
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 = memweight(lc->clean_bits,
				lc->bitset_uint32_count * sizeof(uint32_t));
	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, REQ_OP_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;
}