diff mbox series

[v3,1/2] ubifs: factor out helper ubifs_check_node_buf()

Message ID 20200305092205.127758-2-houtao1@huawei.com
State New
Delegated to: Richard Weinberger
Headers show
Series fix potential race between ubifs_tnc_locate() and GC | expand

Commit Message

Hou Tao March 5, 2020, 9:22 a.m. UTC
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@huawei.com>
---
 fs/ubifs/io.c    | 109 +++++++++++++++++++++++------------------------
 fs/ubifs/ubifs.h |   5 +++
 2 files changed, 58 insertions(+), 56 deletions(-)
diff mbox series

Patch

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,