ubifs: Add auth nodes to garbage collector journal head
authorSascha Hauer <s.hauer@pengutronix.de>
Fri, 7 Sep 2018 12:36:37 +0000 (14:36 +0200)
committerRichard Weinberger <richard@nod.at>
Tue, 23 Oct 2018 11:48:40 +0000 (13:48 +0200)
To be able to authenticate the garbage collector journal head add
authentication nodes to the buds the garbage collector creates.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
fs/ubifs/gc.c

index 399d764..bf75fdc 100644 (file)
@@ -365,12 +365,13 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
 
        /* Write nodes to their new location. Use the first-fit strategy */
        while (1) {
-               int avail;
+               int avail, moved = 0;
                struct ubifs_scan_node *snod, *tmp;
 
                /* Move data nodes */
                list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
-                       avail = c->leb_size - wbuf->offs - wbuf->used;
+                       avail = c->leb_size - wbuf->offs - wbuf->used -
+                                       ubifs_auth_node_sz(c);
                        if  (snod->len > avail)
                                /*
                                 * Do not skip data nodes in order to optimize
@@ -378,14 +379,21 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
                                 */
                                break;
 
+                       err = ubifs_shash_update(c, c->jheads[GCHD].log_hash,
+                                                snod->node, snod->len);
+                       if (err)
+                               goto out;
+
                        err = move_node(c, sleb, snod, wbuf);
                        if (err)
                                goto out;
+                       moved = 1;
                }
 
                /* Move non-data nodes */
                list_for_each_entry_safe(snod, tmp, &nondata, list) {
-                       avail = c->leb_size - wbuf->offs - wbuf->used;
+                       avail = c->leb_size - wbuf->offs - wbuf->used -
+                                       ubifs_auth_node_sz(c);
                        if (avail < min)
                                break;
 
@@ -403,9 +411,41 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
                                continue;
                        }
 
+                       err = ubifs_shash_update(c, c->jheads[GCHD].log_hash,
+                                                snod->node, snod->len);
+                       if (err)
+                               goto out;
+
                        err = move_node(c, sleb, snod, wbuf);
                        if (err)
                                goto out;
+                       moved = 1;
+               }
+
+               if (ubifs_authenticated(c) && moved) {
+                       struct ubifs_auth_node *auth;
+
+                       auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS);
+                       if (!auth) {
+                               err = -ENOMEM;
+                               goto out;
+                       }
+
+                       err = ubifs_prepare_auth_node(c, auth,
+                                               c->jheads[GCHD].log_hash);
+                       if (err) {
+                               kfree(auth);
+                               goto out;
+                       }
+
+                       err = ubifs_wbuf_write_nolock(wbuf, auth,
+                                                     ubifs_auth_node_sz(c));
+                       if (err) {
+                               kfree(auth);
+                               goto out;
+                       }
+
+                       ubifs_add_dirt(c, wbuf->lnum, ubifs_auth_node_sz(c));
                }
 
                if (list_empty(&sleb->nodes) && list_empty(&nondata))