static void core_clear_region(struct dirty_log *log, region_t region) { struct log_c *lc = (struct log_c *) log->context; /* Only clear the region if it is also in sync */ if (log_test_bit(lc->sync_bits, region)) log_set_bit(lc, lc->clean_bits, region); }
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++; } }
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); } }
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; }
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); }
static int core_get_resync_work(struct dm_dirty_log *log, region_t *region) { struct log_c *lc = (struct log_c *) log->context; if (lc->sync_search >= lc->region_count) return 0; do { *region = find_next_zero_bit_le(lc->sync_bits, lc->region_count, lc->sync_search); lc->sync_search = *region + 1; if (*region >= lc->region_count) return 0; } while (log_test_bit(lc->recovering_bits, *region)); log_set_bit(lc, lc->recovering_bits, *region); return 1; }
static void core_clear_region(struct dm_dirty_log *log, region_t region) { struct log_c *lc = (struct log_c *) log->context; if (likely(!lc->flush_failed)) log_set_bit(lc, lc->clean_bits, region); }
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; }
static void core_clear_region(struct dirty_log *log, region_t region) { struct log_c *lc = (struct log_c *) log->context; log_set_bit(lc, lc->clean_bits, region); }