static int read_header(struct log_c *log) { int r; unsigned long ebits; r = dm_io_sync_vm(1, &log->header_location, READ, log->disk_header, &ebits); if (r) return r; header_from_disk(&log->header, log->disk_header); /* New log required? */ if (log->sync != DEFAULTSYNC || log->header.magic != MIRROR_MAGIC) { log->header.magic = MIRROR_MAGIC; log->header.version = MIRROR_DISK_VERSION; log->header.nr_regions = 0; } #ifdef __LITTLE_ENDIAN if (log->header.version == 1) log->header.version = 2; #endif if (log->header.version != MIRROR_DISK_VERSION) { DMWARN("incompatible disk log version"); return -EINVAL; } return 0; }
static int read_header(struct log_c *log) { int r; r = rw_header(log, READ); if (r) return r; header_from_disk(&log->header, log->disk_header); /* New log required? */ if (log->sync != DEFAULTSYNC || log->header.magic != MIRROR_MAGIC) { log->header.magic = MIRROR_MAGIC; log->header.version = MIRROR_DISK_VERSION; log->header.nr_regions = 0; } /* Version 2 is like version 1 but always little endian on disk. */ #ifdef __LITTLE_ENDIAN if (log->header.version == 1) log->header.version = 2; #endif if (log->header.version != MIRROR_DISK_VERSION) { DMWARN("incompatible disk log version"); return -EINVAL; } return 0; }
/* * read_log * @lc * * Valid return codes: * -EINVAL: Invalid header, bits not copied * -EIO: Unable to read disk log * 0: Valid header, disk bit -> lc->clean_bits * * Returns: 0 on success, -EXXX on failure */ static int read_log(struct log_c *lc) { struct log_header lh; size_t bitset_size; memset(&lh, 0, sizeof(struct log_header)); if (rw_log(lc, 0)) return -EIO; /* Failed disk read */ header_from_disk(&lh, lc->disk_buffer); if (lh.magic != MIRROR_MAGIC) return -EINVAL; lc->disk_nr_regions = lh.nr_regions; /* Read disk bits into sync_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(lc->clean_bits + 1, (char *)lc->disk_buffer + 1024, bitset_size); return 0; }
static int flush_header(struct log_c *lc) { struct dm_io_region null_location = { .bdev = lc->header_location.bdev, .sector = 0, .count = 0, }; lc->io_req.bi_op = REQ_OP_WRITE; lc->io_req.bi_op_flags = WRITE_FLUSH; return dm_io(&lc->io_req, 1, &null_location, NULL); } static int read_header(struct log_c *log) { int r; r = rw_header(log, REQ_OP_READ); if (r) return r; header_from_disk(&log->header, log->disk_header); /* New log required? */ if (log->sync != DEFAULTSYNC || log->header.magic != MIRROR_MAGIC) { log->header.magic = MIRROR_MAGIC; log->header.version = MIRROR_DISK_VERSION; log->header.nr_regions = 0; } #ifdef __LITTLE_ENDIAN if (log->header.version == 1) log->header.version = 2; #endif if (log->header.version != MIRROR_DISK_VERSION) { DMWARN("incompatible disk log version"); return -EINVAL; } return 0; }