diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-11-04 14:46:04 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-11-04 14:46:04 -0800 |
commit | 42bd06e93d108a3ee5b8b4eaa350ec81853cb217 (patch) | |
tree | 857034936a2c29c79c5cfde47c660225007b060f /fs/ubifs/gc.c | |
parent | 4710e78940d8d957f24b8f085f961f1279f8fbff (diff) | |
parent | 84db119f5a83e1bf9cffbc6d9cf16487eda1c056 (diff) |
Merge tag 'tags/upstream-4.20-rc1' of git://git.infradead.org/linux-ubifs
Pull UBIFS updates from Richard Weinberger:
- Full filesystem authentication feature, UBIFS is now able to have the
whole filesystem structure authenticated plus user data encrypted and
authenticated.
- Minor cleanups
* tag 'tags/upstream-4.20-rc1' of git://git.infradead.org/linux-ubifs: (26 commits)
ubifs: Remove unneeded semicolon
Documentation: ubifs: Add authentication whitepaper
ubifs: Enable authentication support
ubifs: Do not update inode size in-place in authenticated mode
ubifs: Add hashes and HMACs to default filesystem
ubifs: authentication: Authenticate super block node
ubifs: Create hash for default LPT
ubfis: authentication: Authenticate master node
ubifs: authentication: Authenticate LPT
ubifs: Authenticate replayed journal
ubifs: Add auth nodes to garbage collector journal head
ubifs: Add authentication nodes to journal
ubifs: authentication: Add hashes to index nodes
ubifs: Add hashes to the tree node cache
ubifs: Create functions to embed a HMAC in a node
ubifs: Add helper functions for authentication support
ubifs: Add separate functions to init/crc a node
ubifs: Format changes for authentication support
ubifs: Store read superblock node
ubifs: Drop write_node
...
Diffstat (limited to 'fs/ubifs/gc.c')
-rw-r--r-- | fs/ubifs/gc.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index d2680e0b4a36..bf75fdc76fc3 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c @@ -254,7 +254,8 @@ static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb, snod->type == UBIFS_DATA_NODE || snod->type == UBIFS_DENT_NODE || snod->type == UBIFS_XENT_NODE || - snod->type == UBIFS_TRUN_NODE); + snod->type == UBIFS_TRUN_NODE || + snod->type == UBIFS_AUTH_NODE); if (snod->type != UBIFS_INO_NODE && snod->type != UBIFS_DATA_NODE && @@ -364,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 @@ -377,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; @@ -402,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)) |