Exemplo n.º 1
0
/**
 * Create a logpack.
 *
 * @logh_sectdp pointer to sector data pointer
 *   for logpack header (will be set).
 * @logd_sect_aryp pointer to sector data array pointer
 *   for logpack data (will be set).
 * @pbs physical block size [byte].
 * @bufsize buffer size for log data [byte].
 *
 * RETURN:
 *    allocated logpack in success, or NULL.
 */
struct logpack *alloc_logpack(
	unsigned int pbs, unsigned int n_sectors)
{
	struct logpack *pack;

	ASSERT(is_valid_pbs(pbs));
	ASSERT(0 < n_sectors);

	pack = (struct logpack *)malloc(sizeof(*pack));
	if (!pack) { goto error1; }
	memset(pack, 0, sizeof(*pack));

	/* Buffer for logpack header. */
	pack->sectd = sector_alloc(pbs);
	if (!pack->sectd) { goto error1; }
	pack->header = get_logpack_header(pack->sectd);

	/* Buffer for logpack data. */
	pack->sectd_ary = sector_array_alloc(pbs, n_sectors);
	if (!pack->sectd_ary) { goto error1; }
	return pack;

error1:
	LOGe("Memory allocation failure.\n");
	free_logpack(pack);
	return NULL;
}
Exemplo n.º 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;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/**
 * Write an end logpack header block.
 */
bool write_end_logpack_header(int fd, unsigned int pbs, u32 salt)
{
	bool ret = false;
	struct walb_logpack_header *h;
	struct sector_data *sect = sector_alloc(pbs);
	if (!sect) {
		LOGe("sector_alloc failed.\n");
		return false;
	}
	h = get_logpack_header(sect);

	memset(h, 0, pbs);
	h->sector_type = SECTOR_TYPE_LOGPACK;
	h->n_records = 0;
	h->logpack_lsid = (u64)(-1);
	h->checksum = 0;
	h->checksum = checksum((const u8 *)h, pbs, salt);

	ret = write_data(fd, (const u8 *)h, pbs);
	if (!ret) LOGe("write_data failed.\n");
	sector_free(sect);
	return ret;
}