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

Commit 83cef708 authored by Artem Bityutskiy's avatar Artem Bityutskiy Committed by Artem Bityutskiy
Browse files

UBIFS: introduce more I/O helpers



Introduce the following I/O helper functions: 'ubifs_leb_read()',
'ubifs_leb_write()', 'ubifs_leb_change()', 'ubifs_leb_unmap()',
'ubifs_leb_map()', 'ubifs_is_mapped().

The idea is to wrap all UBI I/O functions in order to encapsulate various
assertions and error path handling (error message, stack dump, switching to R/O
mode). And there are some other benefits of this which will be used in the
following patches.

This patch does not switch whole UBIFS to use these functions yet.

Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent d033c98b
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -244,6 +244,10 @@ static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
{
	return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry);
}
static inline int dbg_is_power_cut(const struct ubifs_info *c)
{
	return !!c->dbg->failure_mode;
}

int ubifs_debugging_init(struct ubifs_info *c);
void ubifs_debugging_exit(struct ubifs_info *c);
@@ -445,12 +449,24 @@ static inline int
dbg_check_nondata_nodes_order(struct ubifs_info *c,
			      struct list_head *head)             { return 0; }

static inline int dbg_leb_write(struct ubi_volume_desc *desc,
				int lnum, const void *buf,
				int offset, int len, int dtype)   { return 0; }
static inline int dbg_leb_change(struct ubi_volume_desc *desc,
				 int lnum, const void *buf,
				 int len, int dtype)              { return 0; }
static inline int dbg_leb_unmap(struct ubi_volume_desc *desc,
				int lnum)                         { return 0; }
static inline int dbg_leb_map(struct ubi_volume_desc *desc,
			      int lnum, int dtype)                { return 0; }

static inline int dbg_is_chk_gen(const struct ubifs_info *c)      { return 0; }
static inline int dbg_is_chk_index(const struct ubifs_info *c)    { return 0; }
static inline int dbg_is_chk_orph(const struct ubifs_info *c)     { return 0; }
static inline int dbg_is_chk_lprops(const struct ubifs_info *c)   { return 0; }
static inline int dbg_is_chk_fs(const struct ubifs_info *c)       { return 0; }
static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)    { return 0; }
static inline int dbg_is_power_cut(const struct ubifs_info *c)    { return 0; }

static inline int dbg_debugfs_init(void)                          { return 0; }
static inline void dbg_debugfs_exit(void)                         { return; }
+117 −0
Original line number Diff line number Diff line
@@ -90,6 +90,123 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
	}
}

/*
 * Below are simple wrappers over UBI I/O functions which include some
 * additional checks and UBIFS debugging stuff. See corresponding UBI function
 * for more information.
 */

int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
		   int len, int even_ebadmsg)
{
	int err;

	err = ubi_read(c->ubi, lnum, buf, offs, len);
	/*
	 * In case of %-EBADMSG print the error message only if the
	 * @even_ebadmsg is true.
	 */
	if (err && (err != -EBADMSG || even_ebadmsg)) {
		ubifs_err("reading %d bytes from LEB %d:%d failed, error %d",
			  len, lnum, offs, err);
		dbg_dump_stack();
	}
	return err;
}

int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
		    int len, int dtype)
{
	int err;

	ubifs_assert(!c->ro_media && !c->ro_mount);
	if (c->ro_error)
		return -EROFS;
	if (!dbg_is_tst_rcvry(c))
		err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
	else
		err = dbg_leb_write(c->ubi, lnum, buf, offs, len, dtype);
	if (err) {
		ubifs_err("writing %d bytes to LEB %d:%d failed, error %d",
			  len, lnum, offs, err);
		ubifs_ro_mode(c, err);
		dbg_dump_stack();
	}
	return err;
}

int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
		     int dtype)
{
	int err;

	ubifs_assert(!c->ro_media && !c->ro_mount);
	if (c->ro_error)
		return -EROFS;
	if (!dbg_is_tst_rcvry(c))
		err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
	else
		err = dbg_leb_change(c->ubi, lnum, buf, len, dtype);
	if (err) {
		ubifs_err("changing %d bytes in LEB %d failed, error %d",
			  len, lnum, err);
		ubifs_ro_mode(c, err);
		dbg_dump_stack();
	}
	return err;
}

int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
{
	int err;

	ubifs_assert(!c->ro_media && !c->ro_mount);
	if (c->ro_error)
		return -EROFS;
	if (!dbg_is_tst_rcvry(c))
		err = ubi_leb_unmap(c->ubi, lnum);
	else
		err = dbg_leb_unmap(c->ubi, lnum);
	if (err) {
		ubifs_err("unmap LEB %d failed, error %d", lnum, err);
		ubifs_ro_mode(c, err);
		dbg_dump_stack();
	}
	return err;
}

int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
{
	int err;

	ubifs_assert(!c->ro_media && !c->ro_mount);
	if (c->ro_error)
		return -EROFS;
	if (!dbg_is_tst_rcvry(c))
		err = ubi_leb_map(c->ubi, lnum, dtype);
	else
		err = dbg_leb_map(c->ubi, lnum, dtype);
	if (err) {
		ubifs_err("mapping LEB %d failed, error %d", lnum, err);
		ubifs_ro_mode(c, err);
		dbg_dump_stack();
	}
	return err;
}

int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
{
	int err;

	err = ubi_is_mapped(c->ubi, lnum);
	if (err < 0) {
		ubifs_err("ubi_is_mapped failed for LEB %d, error %d",
			  lnum, err);
		dbg_dump_stack();
	}
	return err;
}

/**
 * ubifs_check_node - check node.
 * @c: UBIFS file-system description object
+0 −80
Original line number Diff line number Diff line
@@ -144,86 +144,6 @@ static inline int ubifs_wbuf_sync(struct ubifs_wbuf *wbuf)
	return err;
}

/**
 * ubifs_leb_unmap - unmap an LEB.
 * @c: UBIFS file-system description object
 * @lnum: LEB number to unmap
 *
 * This function returns %0 on success and a negative error code on failure.
 */
static inline int ubifs_leb_unmap(const struct ubifs_info *c, int lnum)
{
	int err;

	ubifs_assert(!c->ro_media && !c->ro_mount);
	if (c->ro_error)
		return -EROFS;
	err = ubi_leb_unmap(c->ubi, lnum);
	if (err) {
		ubifs_err("unmap LEB %d failed, error %d", lnum, err);
		return err;
	}

	return 0;
}

/**
 * ubifs_leb_write - write to a LEB.
 * @c: UBIFS file-system description object
 * @lnum: LEB number to write
 * @buf: buffer to write from
 * @offs: offset within LEB to write to
 * @len: length to write
 * @dtype: data type
 *
 * This function returns %0 on success and a negative error code on failure.
 */
static inline int ubifs_leb_write(const struct ubifs_info *c, int lnum,
				  const void *buf, int offs, int len, int dtype)
{
	int err;

	ubifs_assert(!c->ro_media && !c->ro_mount);
	if (c->ro_error)
		return -EROFS;
	err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
	if (err) {
		ubifs_err("writing %d bytes at %d:%d, error %d",
			  len, lnum, offs, err);
		return err;
	}

	return 0;
}

/**
 * ubifs_leb_change - atomic LEB change.
 * @c: UBIFS file-system description object
 * @lnum: LEB number to write
 * @buf: buffer to write from
 * @len: length to write
 * @dtype: data type
 *
 * This function returns %0 on success and a negative error code on failure.
 */
static inline int ubifs_leb_change(const struct ubifs_info *c, int lnum,
				   const void *buf, int len, int dtype)
{
	int err;

	ubifs_assert(!c->ro_media && !c->ro_mount);
	if (c->ro_error)
		return -EROFS;
	err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
	if (err) {
		ubifs_err("changing %d bytes in LEB %d, error %d",
			  len, lnum, err);
		return err;
	}

	return 0;
}

/**
 * ubifs_encode_dev - encode device node IDs.
 * @dev: UBIFS device node information
+4 −5
Original line number Diff line number Diff line
@@ -919,8 +919,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
 *
 * This function returns %0 on success and a negative error code on failure.
 */
static int recover_head(const struct ubifs_info *c, int lnum, int offs,
			void *sbuf)
static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
{
	int len = c->max_write_size, err;

@@ -962,7 +961,7 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs,
 *
 * This function returns %0 on success and a negative error code on failure.
 */
int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf)
int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf)
{
	int err;

@@ -993,7 +992,7 @@ int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf)
 *
 * This function returns %0 on success and a negative error code on failure.
 */
static int clean_an_unclean_leb(const struct ubifs_info *c,
static int clean_an_unclean_leb(struct ubifs_info *c,
				struct ubifs_unclean_leb *ucleb, void *sbuf)
{
	int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1;
@@ -1089,7 +1088,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c,
 *
 * This function returns %0 on success and a negative error code on failure.
 */
int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf)
int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf)
{
	dbg_rcvry("recovery");
	while (!list_empty(&c->unclean_leb_list)) {
+11 −2
Original line number Diff line number Diff line
@@ -1468,6 +1468,15 @@ extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];

/* io.c */
void ubifs_ro_mode(struct ubifs_info *c, int err);
int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
		   int len, int even_ebadmsg);
int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
		    int len, int dtype);
int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
		     int dtype);
int ubifs_leb_unmap(struct ubifs_info *c, int lnum);
int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype);
int ubifs_is_mapped(const struct ubifs_info *c, int lnum);
int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
			   int dtype);
@@ -1747,8 +1756,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
					 int offs, void *sbuf, int jhead);
struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
					     int offs, void *sbuf);
int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf);
int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf);
int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf);
int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf);
int ubifs_rcvry_gc_commit(struct ubifs_info *c);
int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key,
			     int deletion, loff_t new_size);