It will be used by the following patch to check the validity of node in buf. And in order to disable node dumping during fs probing, an UBIFS_CHK_FORCE_DUMP_BAD_NODE flag is added to accomplish it. Signed-off-by: Hou Tao <houtao1@xxxxxxxxxx> --- fs/ubifs/io.c | 109 +++++++++++++++++++++++------------------------ fs/ubifs/ubifs.h | 5 +++ 2 files changed, 58 insertions(+), 56 deletions(-) diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 8ceb51478800..c174303274ae 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -946,6 +946,55 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, return ubifs_write_node_hmac(c, buf, len, lnum, offs, -1); } +/** + * ubifs_check_node_buf - check node buffer + * @c: UBIFS file-system description object + * @buf: the buffer saves the node + * @type: the expected type of node + * @len: the expected length of node + * @lnum: logical eraseblock number + * @offs: offset within the logical eraseblock + * @flags: flags for error message control + * + * returns 0 in case of success and %-EINVAL or %-EUCLEAN in case of failure. + */ +int ubifs_check_node_buf(const struct ubifs_info *c, void *buf, int type, + int len, int lnum, int offs, int flags) + +{ + const struct ubifs_ch *ch = buf; + int err; + int l; + + if (type != ch->node_type) { + ubifs_err(c, "bad node type (%d but expected %d)", + ch->node_type, type); + goto out; + } + + err = ubifs_check_node(c, buf, lnum, offs, 0, 0); + if (err) { + ubifs_err(c, "expected node type %d", type); + return err; + } + + l = le32_to_cpu(ch->len); + if (l != len) { + ubifs_err(c, "bad node length %d, expected %d", l, len); + goto out; + } + + return 0; +out: + ubifs_errc(c, "bad node at LEB %d:%d, LEB mapping status %d", lnum, + offs, ubi_is_mapped(c->ubi, lnum)); + if ((flags & UBIFS_CHK_FORCE_DUMP_BAD_NODE) || !c->probing) { + ubifs_dump_node(c, buf); + dump_stack(); + } + return -EINVAL; +} + /** * ubifs_read_node_wbuf - read node from the media or write-buffer. * @wbuf: wbuf to check for un-written data @@ -966,7 +1015,6 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, { const struct ubifs_info *c = wbuf->c; int err, rlen, overlap; - struct ubifs_ch *ch = buf; dbg_io("LEB %d:%d, %s, length %d, jhead %s", lnum, offs, dbg_ntype(type), len, dbg_jhead(wbuf->jhead)); @@ -998,31 +1046,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, return err; } - if (type != ch->node_type) { - ubifs_err(c, "bad node type (%d but expected %d)", - ch->node_type, type); - goto out; - } - - err = ubifs_check_node(c, buf, lnum, offs, 0, 0); - if (err) { - ubifs_err(c, "expected node type %d", type); - return err; - } - - rlen = le32_to_cpu(ch->len); - if (rlen != len) { - ubifs_err(c, "bad node length %d, expected %d", rlen, len); - goto out; - } - - return 0; - -out: - ubifs_err(c, "bad node at LEB %d:%d", lnum, offs); - ubifs_dump_node(c, buf); - dump_stack(); - return -EINVAL; + return ubifs_check_node_buf(c, buf, type, len, lnum, offs, + UBIFS_CHK_FORCE_DUMP_BAD_NODE); } /** @@ -1041,8 +1066,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, int lnum, int offs) { - int err, l; - struct ubifs_ch *ch = buf; + int err; dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0); @@ -1054,34 +1078,7 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, if (err && err != -EBADMSG) return err; - if (type != ch->node_type) { - ubifs_errc(c, "bad node type (%d but expected %d)", - ch->node_type, type); - goto out; - } - - err = ubifs_check_node(c, buf, lnum, offs, 0, 0); - if (err) { - ubifs_errc(c, "expected node type %d", type); - return err; - } - - l = le32_to_cpu(ch->len); - if (l != len) { - ubifs_errc(c, "bad node length %d, expected %d", l, len); - goto out; - } - - return 0; - -out: - ubifs_errc(c, "bad node at LEB %d:%d, LEB mapping status %d", lnum, - offs, ubi_is_mapped(c->ubi, lnum)); - if (!c->probing) { - ubifs_dump_node(c, buf); - dump_stack(); - } - return -EINVAL; + return ubifs_check_node_buf(c, buf, type, len, lnum, offs, 0); } /** diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index bff682309fbe..7b412494b3b6 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -155,6 +155,9 @@ #define UBIFS_HMAC_ARR_SZ 0 #endif +/* Dump bad node when node checking fails */ +#define UBIFS_CHK_FORCE_DUMP_BAD_NODE 1 + /* * Lockdep classes for UBIFS inode @ui_mutex. */ @@ -1710,6 +1713,8 @@ 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 ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf); +int ubifs_check_node_buf(const struct ubifs_info *c, void *buf, int type, + int len, int lnum, int offs, int flags); int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, int lnum, int offs); int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, -- 2.25.0.4.g0ad7144999 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/