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: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
parent
d033c98b17
commit
83cef708c6
|
@ -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);
|
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);
|
int ubifs_debugging_init(struct ubifs_info *c);
|
||||||
void ubifs_debugging_exit(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,
|
dbg_check_nondata_nodes_order(struct ubifs_info *c,
|
||||||
struct list_head *head) { return 0; }
|
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_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_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_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_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_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_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 int dbg_debugfs_init(void) { return 0; }
|
||||||
static inline void dbg_debugfs_exit(void) { return; }
|
static inline void dbg_debugfs_exit(void) { return; }
|
||||||
|
|
117
fs/ubifs/io.c
117
fs/ubifs/io.c
|
@ -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.
|
* ubifs_check_node - check node.
|
||||||
* @c: UBIFS file-system description object
|
* @c: UBIFS file-system description object
|
||||||
|
|
|
@ -144,86 +144,6 @@ static inline int ubifs_wbuf_sync(struct ubifs_wbuf *wbuf)
|
||||||
return err;
|
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.
|
* ubifs_encode_dev - encode device node IDs.
|
||||||
* @dev: UBIFS device node information
|
* @dev: UBIFS device node information
|
||||||
|
|
|
@ -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.
|
* 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,
|
static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
|
||||||
void *sbuf)
|
|
||||||
{
|
{
|
||||||
int len = c->max_write_size, err;
|
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.
|
* 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;
|
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.
|
* 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)
|
struct ubifs_unclean_leb *ucleb, void *sbuf)
|
||||||
{
|
{
|
||||||
int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1;
|
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.
|
* 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");
|
dbg_rcvry("recovery");
|
||||||
while (!list_empty(&c->unclean_leb_list)) {
|
while (!list_empty(&c->unclean_leb_list)) {
|
||||||
|
|
|
@ -1468,6 +1468,15 @@ extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
|
||||||
|
|
||||||
/* io.c */
|
/* io.c */
|
||||||
void ubifs_ro_mode(struct ubifs_info *c, int err);
|
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_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);
|
||||||
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
|
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
|
||||||
int dtype);
|
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);
|
int offs, void *sbuf, int jhead);
|
||||||
struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
|
struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
|
||||||
int offs, void *sbuf);
|
int offs, void *sbuf);
|
||||||
int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf);
|
int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf);
|
||||||
int ubifs_clean_lebs(const 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_rcvry_gc_commit(struct ubifs_info *c);
|
||||||
int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key,
|
int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key,
|
||||||
int deletion, loff_t new_size);
|
int deletion, loff_t new_size);
|
||||||
|
|
Reference in New Issue