/** * Tells that a unusable device is now available again. We'll put it * in the EXA_REALDEV_UPDATING state, which doesn't mean we can safely * use it, but that a rebuilding process must take place before * changing the status to EXA_REALDEV_OK. * * @param[in] rdev The real device which is now available again * * @return always EXA_SUCCESS */ int vrt_rdev_up(struct vrt_realdev *rdev) { uint64_t size; uint64_t required_size; int err; /* Admind can send an up message even if the device is not down */ if (rdev_is_ok(rdev)) return EXA_SUCCESS; rdev->up = TRUE; size = __get_block_aligned_bdev_size(rdev->blockdevice); err = vrt_rdev_set_real_size(rdev, size); if (err != EXA_SUCCESS) return err; /* Check that the size of the device correspond to the real size of the * device. * This test is also done at group start (see vrt_group_start) * * FIXME: This kind of verification could be done by the service in * charge of the devices */ required_size = rdev_chunk_based_size(rdev); if (vrt_realdev_get_usable_size(rdev) < required_size) { /* XXX Duplicate: same error in vrt_group_start() */ exalog_error("Real size of device "UUID_FMT" is too small: %"PRIu64" < %"PRIu64, UUID_VAL(&rdev->uuid), vrt_realdev_get_usable_size(rdev), required_size); rdev->corrupted = TRUE; rdev->real_size = 0; return EXA_SUCCESS; } rdev->corrupted = FALSE; return EXA_SUCCESS; }
/** * Cut an rdev into chunks * * @param[in] storage The storage * @param[in] rdev The rdev to cut in chunks * * @return 0 if successful, a negative error code otherwise */ int storage_cut_rdev_in_chunks(storage_t *storage, vrt_realdev_t *rdev) { uint64_t total_size = vrt_realdev_get_usable_size(rdev); uint32_t chunk_size = KBYTES_2_SECTORS(storage->chunk_size); EXA_ASSERT(total_size > 0); EXA_ASSERT(chunk_size > 0); if (chunk_size > total_size) return -VRT_ERR_RDEV_TOO_SMALL; storage_initialize_rdev_chunks_info(storage, rdev, total_size / chunk_size); return EXA_SUCCESS; }