Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 354fa8be authored by Ryusuke Konishi's avatar Ryusuke Konishi
Browse files

nilfs2: divide load_segment_summary function



load_segment_summary function has two distinct roles: getting summary
header of a log, and verifying consistencies of the log.

This divide it into two corresponding functions, nilfs_read_log_header
and nilfs_validate_log to clarify the meaning.

Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
parent aee5ce2f
Loading
Loading
Loading
Loading
+69 −41
Original line number Diff line number Diff line
@@ -202,57 +202,62 @@ int nilfs_read_super_root_block(struct the_nilfs *nilfs, sector_t sr_block,
}

/**
 * load_segment_summary - read segment summary of the specified partial segment
 * nilfs_read_log_header - read summary header of the specified log
 * @nilfs: nilfs object
 * @pseg_start: start disk block number of partial segment
 * @seg_seq: sequence number requested
 * @ssi: pointer to nilfs_segsum_info struct to store information
 * @start_blocknr: start block number of the log
 * @sum: pointer to return segment summary structure
 */
static int
load_segment_summary(struct the_nilfs *nilfs, sector_t pseg_start,
		     u64 seg_seq, struct nilfs_segsum_info *ssi)
static struct buffer_head *
nilfs_read_log_header(struct the_nilfs *nilfs, sector_t start_blocknr,
		      struct nilfs_segment_summary **sum)
{
	struct buffer_head *bh_sum;
	struct nilfs_segment_summary *sum;

	bh_sum = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize);
	if (bh_sum)
		*sum = (struct nilfs_segment_summary *)bh_sum->b_data;
	return bh_sum;
}

/**
 * nilfs_validate_log - verify consistency of log
 * @nilfs: nilfs object
 * @seg_seq: sequence number of segment
 * @bh_sum: buffer head of summary block
 * @sum: segment summary struct
 */
static int nilfs_validate_log(struct the_nilfs *nilfs, u64 seg_seq,
			      struct buffer_head *bh_sum,
			      struct nilfs_segment_summary *sum)
{
	unsigned long nblock;
	u32 crc;
	int ret = NILFS_SEG_FAIL_IO;
	int ret;

	bh_sum = __bread(nilfs->ns_bdev, pseg_start, nilfs->ns_blocksize);
	if (!bh_sum)
	ret = NILFS_SEG_FAIL_MAGIC;
	if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC)
		goto out;

	sum = (struct nilfs_segment_summary *)bh_sum->b_data;

	/* Check consistency of segment summary */
	if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC) {
		ret = NILFS_SEG_FAIL_MAGIC;
		goto failed;
	}
	store_segsum_info(ssi, sum, nilfs->ns_blocksize);
	if (seg_seq != ssi->seg_seq) {
	ret = NILFS_SEG_FAIL_SEQ;
		goto failed;
	}
	if (le64_to_cpu(sum->ss_seq) != seg_seq)
		goto out;

	nblock = ssi->nblocks;
	if (unlikely(nblock == 0 || nblock > nilfs->ns_blocks_per_segment)) {
		/* This limits the number of blocks read in the CRC check */
	nblock = le32_to_cpu(sum->ss_nblocks);
	ret = NILFS_SEG_FAIL_CONSISTENCY;
		goto failed;
	}
	if (unlikely(nblock == 0 || nblock > nilfs->ns_blocks_per_segment))
		/* This limits the number of blocks read in the CRC check */
		goto out;

	ret = NILFS_SEG_FAIL_IO;
	if (nilfs_compute_checksum(nilfs, bh_sum, &crc, sizeof(sum->ss_datasum),
				   ((u64)nblock << nilfs->ns_blocksize_bits),
				   pseg_start, nblock)) {
		ret = NILFS_SEG_FAIL_IO;
		goto failed;
	}
	if (crc == le32_to_cpu(sum->ss_datasum))
		ret = 0;
	else
				   bh_sum->b_blocknr, nblock))
		goto out;

	ret = NILFS_SEG_FAIL_CHECKSUM_FULL;
 failed:
	brelse(bh_sum);
	if (crc != le32_to_cpu(sum->ss_datasum))
		goto out;
	ret = 0;
out:
	return ret;
}
@@ -589,6 +594,8 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
				 struct nilfs_recovery_info *ri)
{
	struct nilfs_segsum_info ssi;
	struct buffer_head *bh_sum = NULL;
	struct nilfs_segment_summary *sum;
	sector_t pseg_start;
	sector_t seg_start, seg_end;  /* Starting/ending DBN of full segment */
	unsigned long nsalvaged_blocks = 0;
@@ -610,8 +617,14 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
	nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);

	while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) {
		brelse(bh_sum);
		bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum);
		if (!bh_sum) {
			err = -EIO;
			goto failed;
		}

		ret = load_segment_summary(nilfs, pseg_start, seg_seq, &ssi);
		ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum);
		if (ret) {
			if (ret == NILFS_SEG_FAIL_IO) {
				err = -EIO;
@@ -619,6 +632,8 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
			}
			goto strayed;
		}

		store_segsum_info(&ssi, sum, nilfs->ns_blocksize);
		if (unlikely(NILFS_SEG_HAS_SR(&ssi)))
			goto confused;

@@ -682,6 +697,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
		ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE;
	}
 out:
	brelse(bh_sum);
	dispose_recovery_list(&dsync_blocks);
	nilfs_detach_writer(nilfs, sbi);
	return err;
@@ -807,6 +823,8 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
			    struct nilfs_recovery_info *ri)
{
	struct nilfs_segsum_info ssi;
	struct buffer_head *bh_sum = NULL;
	struct nilfs_segment_summary *sum;
	sector_t pseg_start, pseg_end, sr_pseg_start = 0;
	sector_t seg_start, seg_end; /* range of full segment (block number) */
	sector_t b, end;
@@ -831,12 +849,20 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
		__breadahead(nilfs->ns_bdev, b++, nilfs->ns_blocksize);

	for (;;) {
		ret = load_segment_summary(nilfs, pseg_start, seg_seq, &ssi);
		brelse(bh_sum);
		ret = NILFS_SEG_FAIL_IO;
		bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum);
		if (!bh_sum)
			goto failed;

		ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum);
		if (ret) {
			if (ret == NILFS_SEG_FAIL_IO)
				goto failed;
			goto strayed;
		}

		store_segsum_info(&ssi, sum, nilfs->ns_blocksize);
		pseg_end = pseg_start + ssi.nblocks - 1;
		if (unlikely(pseg_end > seg_end)) {
			ret = NILFS_SEG_FAIL_CONSISTENCY;
@@ -936,6 +962,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,

 super_root_found:
	/* Updating pointers relating to the latest checkpoint */
	brelse(bh_sum);
	list_splice_tail(&segments, &ri->ri_used_segments);
	nilfs->ns_last_pseg = sr_pseg_start;
	nilfs->ns_last_seq = nilfs->ns_seg_seq;
@@ -943,6 +970,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
	return 0;

 failed:
	brelse(bh_sum);
	nilfs_dispose_segment_list(&segments);
	return (ret < 0) ? ret : nilfs_warn_segment_error(ret);
}