Unverified Commit c2fa4e76 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!10237 ocfs2: fix NULL pointer dereference in ocfs2_abort_trigger()

parents c0afd3d4 9d4f82ab
Loading
Loading
Loading
Loading
+101 −81
Original line number Diff line number Diff line
@@ -479,12 +479,6 @@ int ocfs2_allocate_extend_trans(handle_t *handle, int thresh)
	return status;
}


struct ocfs2_triggers {
	struct jbd2_buffer_trigger_type	ot_triggers;
	int				ot_offset;
};

static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger_type *triggers)
{
	return container_of(triggers, struct ocfs2_triggers, ot_triggers);
@@ -548,85 +542,76 @@ static void ocfs2_db_frozen_trigger(struct jbd2_buffer_trigger_type *triggers,
static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers,
				struct buffer_head *bh)
{
	struct ocfs2_triggers *ot = to_ocfs2_trigger(triggers);

	mlog(ML_ERROR,
	     "ocfs2_abort_trigger called by JBD2.  bh = 0x%lx, "
	     "bh->b_blocknr = %llu\n",
	     (unsigned long)bh,
	     (unsigned long long)bh->b_blocknr);

	ocfs2_error(bh->b_assoc_map->host->i_sb,
	ocfs2_error(ot->sb,
		    "JBD2 has aborted our journal, ocfs2 cannot continue\n");
}

static struct ocfs2_triggers di_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
	.ot_offset	= offsetof(struct ocfs2_dinode, i_check),
};

static struct ocfs2_triggers eb_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
	.ot_offset	= offsetof(struct ocfs2_extent_block, h_check),
};

static struct ocfs2_triggers rb_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
	.ot_offset	= offsetof(struct ocfs2_refcount_block, rf_check),
};

static struct ocfs2_triggers gd_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
	.ot_offset	= offsetof(struct ocfs2_group_desc, bg_check),
};

static struct ocfs2_triggers db_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_db_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
};
static void ocfs2_setup_csum_triggers(struct super_block *sb,
				      enum ocfs2_journal_trigger_type type,
				      struct ocfs2_triggers *ot)
{
	BUG_ON(type >= OCFS2_JOURNAL_TRIGGER_COUNT);

static struct ocfs2_triggers xb_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
	.ot_offset	= offsetof(struct ocfs2_xattr_block, xb_check),
};
	switch (type) {
	case OCFS2_JTR_DI:
		ot->ot_triggers.t_frozen = ocfs2_frozen_trigger;
		ot->ot_offset = offsetof(struct ocfs2_dinode, i_check);
		break;
	case OCFS2_JTR_EB:
		ot->ot_triggers.t_frozen = ocfs2_frozen_trigger;
		ot->ot_offset = offsetof(struct ocfs2_extent_block, h_check);
		break;
	case OCFS2_JTR_RB:
		ot->ot_triggers.t_frozen = ocfs2_frozen_trigger;
		ot->ot_offset = offsetof(struct ocfs2_refcount_block, rf_check);
		break;
	case OCFS2_JTR_GD:
		ot->ot_triggers.t_frozen = ocfs2_frozen_trigger;
		ot->ot_offset = offsetof(struct ocfs2_group_desc, bg_check);
		break;
	case OCFS2_JTR_DB:
		ot->ot_triggers.t_frozen = ocfs2_db_frozen_trigger;
		break;
	case OCFS2_JTR_XB:
		ot->ot_triggers.t_frozen = ocfs2_frozen_trigger;
		ot->ot_offset = offsetof(struct ocfs2_xattr_block, xb_check);
		break;
	case OCFS2_JTR_DQ:
		ot->ot_triggers.t_frozen = ocfs2_dq_frozen_trigger;
		break;
	case OCFS2_JTR_DR:
		ot->ot_triggers.t_frozen = ocfs2_frozen_trigger;
		ot->ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check);
		break;
	case OCFS2_JTR_DL:
		ot->ot_triggers.t_frozen = ocfs2_frozen_trigger;
		ot->ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check);
		break;
	case OCFS2_JTR_NONE:
		/* To make compiler happy... */
		return;
	}

static struct ocfs2_triggers dq_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_dq_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
};
	ot->ot_triggers.t_abort = ocfs2_abort_trigger;
	ot->sb = sb;
}

static struct ocfs2_triggers dr_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
	.ot_offset	= offsetof(struct ocfs2_dx_root_block, dr_check),
};
void ocfs2_initialize_journal_triggers(struct super_block *sb,
				       struct ocfs2_triggers triggers[])
{
	enum ocfs2_journal_trigger_type type;

static struct ocfs2_triggers dl_triggers = {
	.ot_triggers = {
		.t_frozen = ocfs2_frozen_trigger,
		.t_abort = ocfs2_abort_trigger,
	},
	.ot_offset	= offsetof(struct ocfs2_dx_leaf, dl_check),
};
	for (type = OCFS2_JTR_DI; type < OCFS2_JOURNAL_TRIGGER_COUNT; type++)
		ocfs2_setup_csum_triggers(sb, type, &triggers[type]);
}

static int __ocfs2_journal_access(handle_t *handle,
				  struct ocfs2_caching_info *ci,
@@ -708,56 +693,91 @@ static int __ocfs2_journal_access(handle_t *handle,
int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &di_triggers, type);
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				      &osb->s_journal_triggers[OCFS2_JTR_DI],
				      type);
}

int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &eb_triggers, type);
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				      &osb->s_journal_triggers[OCFS2_JTR_EB],
				      type);
}

int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &rb_triggers,
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				      &osb->s_journal_triggers[OCFS2_JTR_RB],
				      type);
}

int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &gd_triggers, type);
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				     &osb->s_journal_triggers[OCFS2_JTR_GD],
				     type);
}

int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &db_triggers, type);
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				     &osb->s_journal_triggers[OCFS2_JTR_DB],
				     type);
}

int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &xb_triggers, type);
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				     &osb->s_journal_triggers[OCFS2_JTR_XB],
				     type);
}

int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &dq_triggers, type);
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				     &osb->s_journal_triggers[OCFS2_JTR_DQ],
				     type);
}

int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &dr_triggers, type);
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				     &osb->s_journal_triggers[OCFS2_JTR_DR],
				     type);
}

int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci,
			    struct buffer_head *bh, int type)
{
	return __ocfs2_journal_access(handle, ci, bh, &dl_triggers, type);
	struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci));

	return __ocfs2_journal_access(handle, ci, bh,
				     &osb->s_journal_triggers[OCFS2_JTR_DL],
				     type);
}

int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci,
+27 −0
Original line number Diff line number Diff line
@@ -284,6 +284,30 @@ enum ocfs2_mount_options
#define OCFS2_OSB_ERROR_FS	0x0004
#define OCFS2_DEFAULT_ATIME_QUANTUM	60

struct ocfs2_triggers {
	struct jbd2_buffer_trigger_type	ot_triggers;
	int				ot_offset;
	struct super_block		*sb;
};

enum ocfs2_journal_trigger_type {
	OCFS2_JTR_DI,
	OCFS2_JTR_EB,
	OCFS2_JTR_RB,
	OCFS2_JTR_GD,
	OCFS2_JTR_DB,
	OCFS2_JTR_XB,
	OCFS2_JTR_DQ,
	OCFS2_JTR_DR,
	OCFS2_JTR_DL,
	OCFS2_JTR_NONE  /* This must be the last entry */
};

#define OCFS2_JOURNAL_TRIGGER_COUNT OCFS2_JTR_NONE

void ocfs2_initialize_journal_triggers(struct super_block *sb,
				       struct ocfs2_triggers triggers[]);

struct ocfs2_journal;
struct ocfs2_slot_info;
struct ocfs2_recovery_map;
@@ -351,6 +375,9 @@ struct ocfs2_super
	struct ocfs2_journal *journal;
	unsigned long osb_commit_interval;

	/* Journal triggers for checksum */
	struct ocfs2_triggers s_journal_triggers[OCFS2_JOURNAL_TRIGGER_COUNT];

	struct delayed_work		la_enable_wq;

	/*
+3 −1
Original line number Diff line number Diff line
@@ -1075,9 +1075,11 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
	debugfs_create_file("fs_state", S_IFREG|S_IRUSR, osb->osb_debug_root,
			    osb, &ocfs2_osb_debug_fops);

	if (ocfs2_meta_ecc(osb))
	if (ocfs2_meta_ecc(osb)) {
		ocfs2_initialize_journal_triggers(sb, osb->s_journal_triggers);
		ocfs2_blockcheck_stats_debugfs_install( &osb->osb_ecc_stats,
							osb->osb_debug_root);
	}

	status = ocfs2_mount_volume(sb);
	if (status < 0)