コード例 #1
0
/**
 * Shrink logpack header.
 *
 * @logh logpack header to shrink.
 * @invalid_idx new logpack header's n_records must be invalid_idx.
 * @pbs physical block size [byte].
 * @salt checksum salt.
 */
void shrink_logpack_header(
	struct walb_logpack_header *logh, unsigned int invalid_idx,
	unsigned int pbs, u32 salt)
{
	unsigned int i;

	/* Invalidate records. */
	ASSERT(invalid_idx < logh->n_records);
	for (i = invalid_idx; i < logh->n_records; i++) {
		log_record_init(&logh->record[i]);
	}

	/* Set n_records, n_padding, and total_io_size. */
	logh->n_records = invalid_idx;
	logh->n_padding = 0;
	logh->total_io_size = 0;
	for (i = 0; i < invalid_idx; i++) {
		const struct walb_log_record *rec = &logh->record[i];
		if (!test_bit_u32(LOG_RECORD_DISCARD, &rec->flags)) {
			logh->total_io_size += capacity_pb(pbs, rec->io_size);
		}
		if (test_bit_u32(LOG_RECORD_PADDING, &rec->flags)) {
			logh->n_padding++;
		}
	}

	/* Calculate checksum. */
	logh->checksum = 0;
	logh->checksum = checksum((const u8 *)logh, pbs, salt);
	ASSERT(is_valid_logpack_header_with_checksum(logh, pbs, salt));
}
コード例 #2
0
/**
 * Read logpack header sector from log device.
 *
 * @fd log device fd opened.
 * @super_sectp super sector.
 * @lsid logpack lsid to read.
 * @logh_sect buffer to store logpack header data.
 *   This allocated size must be sector size.
 * @salt log checksum salt.
 *
 * RETURN:
 *   ture in success, or false.
 */
bool read_logpack_header_from_wldev(
	int fd, const struct walb_super_sector* super_sectp,
	u64 lsid, u32 salt, struct sector_data *logh_sect)
{
	/* calc offset in the ring buffer */
	u64 ring_buffer_offset = get_ring_buffer_offset_2(super_sectp);
	u64 ring_buffer_size = super_sectp->ring_buffer_size;
	u64 off = ring_buffer_offset + lsid % ring_buffer_size;
	struct walb_logpack_header *logh = get_logpack_header(logh_sect);

	/* read sector */
	if (!sector_read(fd, off, logh_sect)) {
		LOGe("read logpack header (lsid %"PRIu64") failed.\n", lsid);
		return false;
	}

	/* check lsid */
	if (lsid != logh->logpack_lsid) {
		LOGe("lsid (given %"PRIu64" read %"PRIu64") is invalid.\n",
			lsid, logh->logpack_lsid);
		return false;
	}
	if (!is_valid_logpack_header_with_checksum(
			logh, super_sectp->physical_bs, salt)) {
		LOGe("check logpack header failed.\n");
		return false;
	}
	return true;
}
コード例 #3
0
/**
 * Read logpack header from fd.
 *
 * @fd file descriptor (opened, seeked)
 * @pbs physical block size [byte].
 * @salt checksum salt.
 * @logpack logpack to be filled. (allocated size must be physical_bs).
 *
 * RETURN:
 *   true in success, or false.
 */
bool read_logpack_header(
	int fd, unsigned int pbs, u32 salt,
	struct walb_logpack_header* logh)
{
	/* Read */
	if (!read_data(fd, (u8 *)logh, pbs)) {
		return false;
	}

	/* Check */
	if (!is_valid_logpack_header_with_checksum(logh, pbs, salt)) {
		return false;
	}

	return true;
}
コード例 #4
0
/**
 * Check logpack of the given lsid exists.
 *
 * @lsid lsid to check.
 *
 * @return Non-zero if valid, or 0.
 */
int walb_check_lsid_valid(struct walb_dev *wdev, u64 lsid)
{
	struct sector_data *sect;
	struct walb_logpack_header *logh;
	u64 off;

	ASSERT(wdev);

	sect = sector_alloc(wdev->physical_bs, GFP_NOIO);
	if (!sect) {
		LOGe("walb_check_lsid_valid: alloc sector failed.\n");
		goto error0;
	}
	ASSERT(is_same_size_sector(sect, wdev->lsuper0));
	logh = get_logpack_header(sect);

	spin_lock(&wdev->lsuper0_lock);
	off = get_offset_of_lsid_2(get_super_sector(wdev->lsuper0), lsid);
	spin_unlock(&wdev->lsuper0_lock);
	if (!sector_io(READ, wdev->ldev, off, sect)) {
		LOGe("walb_check_lsid_valid: read sector failed.\n");
		goto error1;
	}

	/* Check valid logpack header. */
	if (!is_valid_logpack_header_with_checksum(
			logh, wdev->physical_bs, wdev->log_checksum_salt)) {
		goto error1;
	}

	/* Check lsid. */
	if (logh->logpack_lsid != lsid) {
		goto error1;
	}

	sector_free(sect);
	return 1;

error1:
	sector_free(sect);
error0:
	return 0;
}