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

Commit 2e52eb74 authored by Richard Weinberger's avatar Richard Weinberger
Browse files

ubifs: Rework ubifs_assert()



With having access to struct ubifs_info in ubifs_assert() we can
give more information when an assert is failing.
By using ubifs_err() we can tell which UBIFS instance failed.

Also multiple actions can be taken now.
We support:
 - report: This is what UBIFS did so far, just report the failure and go
   on.
 - read-only: Switch to read-only mode.
 - panic: shoot the kernel in the head.

Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent 6eb61d58
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -3081,6 +3081,28 @@ void dbg_debugfs_exit(void)
		debugfs_remove_recursive(dfs_rootdir);
}

void ubifs_assert_failed(struct ubifs_info *c, const char *expr,
			 const char *file, int line)
{
	ubifs_err(c, "UBIFS assert failed: %s, in %s:%u", expr, file, line);

	switch (c->assert_action) {
		case ASSACT_PANIC:
		BUG();
		break;

		case ASSACT_RO:
		ubifs_ro_mode(c, -EINVAL);
		break;

		case ASSACT_REPORT:
		default:
		dump_stack();
		break;

	}
}

/**
 * ubifs_debugging_init - initialize UBIFS debugging.
 * @c: UBIFS file-system description object
+6 −4
Original line number Diff line number Diff line
@@ -148,18 +148,20 @@ struct ubifs_global_debug_info {
	unsigned int tst_rcvry:1;
};

void ubifs_assert_failed(struct ubifs_info *c, const char *expr,
	const char *file, int line);

#define ubifs_assert(c, expr) do {                                             \
	if (unlikely(!(expr))) {                                               \
		pr_crit("UBIFS assert failed in %s at %u (pid %d)\n",          \
		       __func__, __LINE__, current->pid);                      \
		dump_stack();                                                  \
		ubifs_assert_failed((struct ubifs_info *)c, #expr, __FILE__,   \
		 __LINE__);                                                    \
	}                                                                      \
} while (0)

#define ubifs_assert_cmt_locked(c) do {                                        \
	if (unlikely(down_write_trylock(&(c)->commit_sem))) {                  \
		up_write(&(c)->commit_sem);                                    \
		pr_crit("commit lock is not locked!\n");                       \
		ubifs_err(c, "commit lock is not locked!\n");                  \
		ubifs_assert(c, 0);                                            \
	}                                                                      \
} while (0)
+14 −0
Original line number Diff line number Diff line
@@ -258,6 +258,18 @@ enum {
	LEB_RETAINED,
};

/*
 * Action taken upon a failed ubifs_assert().
 * @ASSACT_REPORT: just report the failed assertion
 * @ASSACT_RO: switch to read-only mode
 * @ASSACT_PANIC: call BUG() and possible panic the kernel
 */
enum {
	ASSACT_REPORT = 0,
	ASSACT_RO,
	ASSACT_PANIC,
};

/**
 * struct ubifs_old_idx - index node obsoleted since last commit start.
 * @rb: rb-tree node
@@ -1015,6 +1027,7 @@ struct ubifs_debug_info;
 * @bulk_read: enable bulk-reads
 * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
 * @rw_incompat: the media is not R/W compatible
 * @assert_action: action to take when a ubifs_assert() fails
 *
 * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
 *             @calc_idx_sz
@@ -1256,6 +1269,7 @@ struct ubifs_info {
	unsigned int bulk_read:1;
	unsigned int default_compr:2;
	unsigned int rw_incompat:1;
	unsigned int assert_action:2;

	struct mutex tnc_mutex;
	struct ubifs_zbranch zroot;