ubifs: Fix journal replay wrt. xattr nodes
authorVille Baillie <villeb@bytesnap.co.uk>
Mon, 28 Mar 2022 09:13:43 +0000 (09:13 +0000)
committerTom Rini <trini@konsulko.com>
Mon, 11 Apr 2022 19:03:28 +0000 (15:03 -0400)
Backport commit 1cb51a15b576 ("ubifs: Fix journal replay wrt. xattr
nodes") from the Linux Kernel, which has the following Signed-off-by
line:
Signed-off-by: Richard Weinberger <richard@nod.at>
For U-Boot, after comapring with the upstream commit:
Signed-off-by: Tom Rini <trini@konsulko.com>
fs/ubifs/tnc.c

index e8b8f16..4fb1004 100644 (file)
@@ -50,6 +50,11 @@ enum {
        NOT_ON_MEDIA = 3,
 };
 
+static int try_read_node(const struct ubifs_info *c, void *buf, int type,
+                        int len, int lnum, int offs);
+static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key,
+                             struct ubifs_zbranch *zbr, void *node);
+
 /**
  * insert_old_idx - record an index node obsoleted since the last commit start.
  * @c: UBIFS file-system description object
@@ -402,7 +407,19 @@ static int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr,
                return 0;
        }
 
-       err = ubifs_tnc_read_node(c, zbr, node);
+       if (c->replaying) {
+               err = fallible_read_node(c, &zbr->key, zbr, node);
+               /*
+                * When the node was not found, return -ENOENT, 0 otherwise.
+                * Negative return codes stay as-is.
+                */
+               if (err == 0)
+                       err = -ENOENT;
+               else if (err == 1)
+                       err = 0;
+       } else {
+               err = ubifs_tnc_read_node(c, zbr, node);
+       }
        if (err)
                return err;
 
@@ -2770,7 +2787,11 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,
        if (nm->name) {
                if (err) {
                        /* Handle collisions */
-                       err = resolve_collision(c, key, &znode, &n, nm);
+                       if (c->replaying)
+                               err = fallible_resolve_collision(c, key, &znode, &n,
+                                                                nm, 0);
+                       else
+                               err = resolve_collision(c, key, &znode, &n, nm);
                        dbg_tnc("rc returned %d, znode %p, n %d",
                                err, znode, n);
                        if (unlikely(err < 0))