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 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; }