Skip to contentSkip to conversation

Patch "ubifs: Fix journal replay wrt. xattr nodes" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message Jan 23, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

ubifs: Fix journal replay wrt. xattr nodes

to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
ubifs-fix-journal-replay-wrt.-xattr-nodes.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 1cb51a15b576ee325d527726afff40947218fd5e Mon Sep 17 00:00:00 2001

From: Richard Weinberger <[email protected]>
Date: Tue, 10 Jan 2017 11:49:40 +0100
Subject: ubifs: Fix journal replay wrt. xattr nodes

From: Richard Weinberger <[email protected]>

commit 1cb51a15b576ee325d527726afff40947218fd5e upstream.

When replaying the journal it can happen that a journal entry points to a garbage collected node.
This is the case when a power-cut occurred between a garbage collect run and a commit. In such a case nodes have to be read using the failable read functions to detect whether the found node matches what we expect.

One corner case was forgotten, when the journal contains an entry to remove an inode all xattrs have to be removed too. UBIFS models xattr like directory entries, so the TNC code iterates over
all xattrs of the inode and removes them too. This code re-uses the functions for walking directories and calls ubifs_tnc_next_ent(). ubifs_tnc_next_ent() expects to be used only after the journal and aborts when a node does not match the expected result. This behavior can render an UBIFS volume unmountable after a power-cut when xattrs are used.

Fix this issue by using failable read functions in ubifs_tnc_next_ent() too when replaying the journal.

Fixes 1e51764a3c2ac05a ("UBIFS: add new flash file system")
---
 fs/ubifs/tnc.c |   25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)
fs/ubifs/tnc.c +23 -2
@@ -34,6 +34,11 @@
 #include <linux/slab.h>
 #include "ubifs.h"
 
+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);
+
 /*
  * Returned codes of 'matches_name()' and 'fallible_matches_name()' functions.
  * @NAME_LESS: name corresponding to the first argument is less than second
@@ -402,7 +407,19 @@ static int tnc_read_node_nm(struct ubifs
 		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;
 
@@ -2766,7 +2783,11 @@ struct ubifs_dent_node *ubifs_tnc_next_e
 	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))

Patches currently in stable-queue which might be from [email protected] are

queue-4.9/ubifs-fix-journal-replay-wrt.-xattr-nodes.patch