diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2018-09-07 08:36:37 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2018-10-23 07:48:40 -0400 |
commit | 6f06d96fdf624be3e1d65c6100704a1fd79a30b7 (patch) | |
tree | 9f73bc0c8b651130327943b8b198aa781513e50e | |
parent | 6a98bc4614de8fac8c6d520a6b20b194e23c9936 (diff) |
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 <s.hauer@pengutronix.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r-- | fs/ubifs/gc.c | 46 |
1 files 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) | |||
365 | 365 | ||
366 | /* Write nodes to their new location. Use the first-fit strategy */ | 366 | /* Write nodes to their new location. Use the first-fit strategy */ |
367 | while (1) { | 367 | while (1) { |
368 | int avail; | 368 | int avail, moved = 0; |
369 | struct ubifs_scan_node *snod, *tmp; | 369 | struct ubifs_scan_node *snod, *tmp; |
370 | 370 | ||
371 | /* Move data nodes */ | 371 | /* Move data nodes */ |
372 | list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { | 372 | list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { |
373 | avail = c->leb_size - wbuf->offs - wbuf->used; | 373 | avail = c->leb_size - wbuf->offs - wbuf->used - |
374 | ubifs_auth_node_sz(c); | ||
374 | if (snod->len > avail) | 375 | if (snod->len > avail) |
375 | /* | 376 | /* |
376 | * Do not skip data nodes in order to optimize | 377 | * 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) | |||
378 | */ | 379 | */ |
379 | break; | 380 | break; |
380 | 381 | ||
382 | err = ubifs_shash_update(c, c->jheads[GCHD].log_hash, | ||
383 | snod->node, snod->len); | ||
384 | if (err) | ||
385 | goto out; | ||
386 | |||
381 | err = move_node(c, sleb, snod, wbuf); | 387 | err = move_node(c, sleb, snod, wbuf); |
382 | if (err) | 388 | if (err) |
383 | goto out; | 389 | goto out; |
390 | moved = 1; | ||
384 | } | 391 | } |
385 | 392 | ||
386 | /* Move non-data nodes */ | 393 | /* Move non-data nodes */ |
387 | list_for_each_entry_safe(snod, tmp, &nondata, list) { | 394 | list_for_each_entry_safe(snod, tmp, &nondata, list) { |
388 | avail = c->leb_size - wbuf->offs - wbuf->used; | 395 | avail = c->leb_size - wbuf->offs - wbuf->used - |
396 | ubifs_auth_node_sz(c); | ||
389 | if (avail < min) | 397 | if (avail < min) |
390 | break; | 398 | break; |
391 | 399 | ||
@@ -403,9 +411,41 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | |||
403 | continue; | 411 | continue; |
404 | } | 412 | } |
405 | 413 | ||
414 | err = ubifs_shash_update(c, c->jheads[GCHD].log_hash, | ||
415 | snod->node, snod->len); | ||
416 | if (err) | ||
417 | goto out; | ||
418 | |||
406 | err = move_node(c, sleb, snod, wbuf); | 419 | err = move_node(c, sleb, snod, wbuf); |
407 | if (err) | 420 | if (err) |
408 | goto out; | 421 | goto out; |
422 | moved = 1; | ||
423 | } | ||
424 | |||
425 | if (ubifs_authenticated(c) && moved) { | ||
426 | struct ubifs_auth_node *auth; | ||
427 | |||
428 | auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); | ||
429 | if (!auth) { | ||
430 | err = -ENOMEM; | ||
431 | goto out; | ||
432 | } | ||
433 | |||
434 | err = ubifs_prepare_auth_node(c, auth, | ||
435 | c->jheads[GCHD].log_hash); | ||
436 | if (err) { | ||
437 | kfree(auth); | ||
438 | goto out; | ||
439 | } | ||
440 | |||
441 | err = ubifs_wbuf_write_nolock(wbuf, auth, | ||
442 | ubifs_auth_node_sz(c)); | ||
443 | if (err) { | ||
444 | kfree(auth); | ||
445 | goto out; | ||
446 | } | ||
447 | |||
448 | ubifs_add_dirt(c, wbuf->lnum, ubifs_auth_node_sz(c)); | ||
409 | } | 449 | } |
410 | 450 | ||
411 | if (list_empty(&sleb->nodes) && list_empty(&nondata)) | 451 | if (list_empty(&sleb->nodes) && list_empty(&nondata)) |