コード例 #1
0
ファイル: recovery.c プロジェクト: 513855417/linux
static inline unsigned long long read_tag_block(journal_t *journal,
						journal_block_tag_t *tag)
{
	unsigned long long block = be32_to_cpu(tag->t_blocknr);
	if (jbd2_has_feature_64bit(journal))
		block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
	return block;
}
コード例 #2
0
ファイル: recovery.c プロジェクト: 513855417/linux
static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
			       tid_t sequence, struct recovery_info *info)
{
	jbd2_journal_revoke_header_t *header;
	int offset, max;
	int csum_size = 0;
	__u32 rcount;
	int record_len = 4;

	header = (jbd2_journal_revoke_header_t *) bh->b_data;
	offset = sizeof(jbd2_journal_revoke_header_t);
	rcount = be32_to_cpu(header->r_count);

	if (!jbd2_descriptor_block_csum_verify(journal, header))
		return -EFSBADCRC;

	if (jbd2_journal_has_csum_v2or3(journal))
		csum_size = sizeof(struct jbd2_journal_block_tail);
	if (rcount > journal->j_blocksize - csum_size)
		return -EINVAL;
	max = rcount;

	if (jbd2_has_feature_64bit(journal))
		record_len = 8;

	while (offset + record_len <= max) {
		unsigned long long blocknr;
		int err;

		if (record_len == 4)
			blocknr = be32_to_cpu(* ((__be32 *) (bh->b_data+offset)));
		else
			blocknr = be64_to_cpu(* ((__be64 *) (bh->b_data+offset)));
		offset += record_len;
		err = jbd2_journal_set_revoke(journal, blocknr, sequence);
		if (err)
			return err;
		++info->nr_revokes;
	}
	return 0;
}
コード例 #3
0
ファイル: revoke.c プロジェクト: AlexShiLucky/linux
static void write_one_revoke_record(transaction_t *transaction,
				    struct list_head *log_bufs,
				    struct buffer_head **descriptorp,
				    int *offsetp,
				    struct jbd2_revoke_record_s *record)
{
	journal_t *journal = transaction->t_journal;
	int csum_size = 0;
	struct buffer_head *descriptor;
	int sz, offset;

	/* If we are already aborting, this all becomes a noop.  We
           still need to go round the loop in
           jbd2_journal_write_revoke_records in order to free all of the
           revoke records: only the IO to the journal is omitted. */
	if (is_journal_aborted(journal))
		return;

	descriptor = *descriptorp;
	offset = *offsetp;

	/* Do we need to leave space at the end for a checksum? */
	if (jbd2_journal_has_csum_v2or3(journal))
		csum_size = sizeof(struct jbd2_journal_block_tail);

	if (jbd2_has_feature_64bit(journal))
		sz = 8;
	else
		sz = 4;

	/* Make sure we have a descriptor with space left for the record */
	if (descriptor) {
		if (offset + sz > journal->j_blocksize - csum_size) {
			flush_descriptor(journal, descriptor, offset);
			descriptor = NULL;
		}
	}

	if (!descriptor) {
		descriptor = jbd2_journal_get_descriptor_buffer(transaction,
							JBD2_REVOKE_BLOCK);
		if (!descriptor)
			return;

		/* Record it so that we can wait for IO completion later */
		BUFFER_TRACE(descriptor, "file in log_bufs");
		jbd2_file_log_bh(log_bufs, descriptor);

		offset = sizeof(jbd2_journal_revoke_header_t);
		*descriptorp = descriptor;
	}

	if (jbd2_has_feature_64bit(journal))
		* ((__be64 *)(&descriptor->b_data[offset])) =
			cpu_to_be64(record->blocknr);
	else
		* ((__be32 *)(&descriptor->b_data[offset])) =
			cpu_to_be32(record->blocknr);
	offset += sz;

	*offsetp = offset;
}