static inline int write_header(struct log_c *log) { unsigned long ebits; header_to_disk(&log->header, log->disk_header); return dm_io_sync_vm(1, &log->header_location, WRITE, log->disk_header, &ebits); }
/* * write_log * @lc * * Returns: 0 on success, -EIO on failure */ static int write_log(struct log_c *lc) { struct log_header lh; size_t bitset_size; lh.magic = MIRROR_MAGIC; lh.version = MIRROR_DISK_VERSION; lh.nr_regions = lc->region_count; header_to_disk(&lh, lc->disk_buffer); /* Write disk bits from clean_bits */ bitset_size = lc->region_count / 8; bitset_size += (lc->region_count % 8) ? 1 : 0; /* 'lc->clean_bits + 1' becasue dm_bitset_t leads with a uint32_t */ memcpy((char *)lc->disk_buffer + 1024, lc->clean_bits + 1, bitset_size); if (rw_log(lc, 1)) { lc->log_dev_failed = 1; return -EIO; /* Failed disk write */ } return 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; }
static inline int write_header(struct log_c *log) { header_to_disk(&log->header, log->disk_header); return rw_header(log, WRITE); }