From 6f06d96fdf624be3e1d65c6100704a1fd79a30b7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 7 Sep 2018 14:36:37 +0200 Subject: [PATCH] ubifs: Add auth nodes to garbage collector journal head 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 Signed-off-by: Richard Weinberger --- fs/ubifs/gc.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index 399d764f83cb..bf75fdc76fc3 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c @@ -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))