.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * This file is part of UBIFS. |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2006-2008 Nokia Corporation. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
8 | | - * the Free Software Foundation. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
---|
11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
13 | | - * more details. |
---|
14 | | - * |
---|
15 | | - * You should have received a copy of the GNU General Public License along with |
---|
16 | | - * this program; if not, write to the Free Software Foundation, Inc., 51 |
---|
17 | | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
---|
18 | 6 | * |
---|
19 | 7 | * Authors: Adrian Hunter |
---|
20 | 8 | * Artem Bityutskiy (Битюцкий Артём) |
---|
.. | .. |
---|
69 | 57 | /** |
---|
70 | 58 | * switch_gc_head - switch the garbage collection journal head. |
---|
71 | 59 | * @c: UBIFS file-system description object |
---|
72 | | - * @buf: buffer to write |
---|
73 | | - * @len: length of the buffer to write |
---|
74 | | - * @lnum: LEB number written is returned here |
---|
75 | | - * @offs: offset written is returned here |
---|
76 | 60 | * |
---|
77 | 61 | * This function switch the GC head to the next LEB which is reserved in |
---|
78 | 62 | * @c->gc_lnum. Returns %0 in case of success, %-EAGAIN if commit is required, |
---|
.. | .. |
---|
254 | 238 | snod->type == UBIFS_DATA_NODE || |
---|
255 | 239 | snod->type == UBIFS_DENT_NODE || |
---|
256 | 240 | snod->type == UBIFS_XENT_NODE || |
---|
257 | | - snod->type == UBIFS_TRUN_NODE); |
---|
| 241 | + snod->type == UBIFS_TRUN_NODE || |
---|
| 242 | + snod->type == UBIFS_AUTH_NODE); |
---|
258 | 243 | |
---|
259 | 244 | if (snod->type != UBIFS_INO_NODE && |
---|
260 | 245 | snod->type != UBIFS_DATA_NODE && |
---|
.. | .. |
---|
364 | 349 | |
---|
365 | 350 | /* Write nodes to their new location. Use the first-fit strategy */ |
---|
366 | 351 | while (1) { |
---|
367 | | - int avail; |
---|
| 352 | + int avail, moved = 0; |
---|
368 | 353 | struct ubifs_scan_node *snod, *tmp; |
---|
369 | 354 | |
---|
370 | 355 | /* Move data nodes */ |
---|
371 | 356 | list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { |
---|
372 | | - avail = c->leb_size - wbuf->offs - wbuf->used; |
---|
| 357 | + avail = c->leb_size - wbuf->offs - wbuf->used - |
---|
| 358 | + ubifs_auth_node_sz(c); |
---|
373 | 359 | if (snod->len > avail) |
---|
374 | 360 | /* |
---|
375 | 361 | * Do not skip data nodes in order to optimize |
---|
.. | .. |
---|
377 | 363 | */ |
---|
378 | 364 | break; |
---|
379 | 365 | |
---|
| 366 | + err = ubifs_shash_update(c, c->jheads[GCHD].log_hash, |
---|
| 367 | + snod->node, snod->len); |
---|
| 368 | + if (err) |
---|
| 369 | + goto out; |
---|
| 370 | + |
---|
380 | 371 | err = move_node(c, sleb, snod, wbuf); |
---|
381 | 372 | if (err) |
---|
382 | 373 | goto out; |
---|
| 374 | + moved = 1; |
---|
383 | 375 | } |
---|
384 | 376 | |
---|
385 | 377 | /* Move non-data nodes */ |
---|
386 | 378 | list_for_each_entry_safe(snod, tmp, &nondata, list) { |
---|
387 | | - avail = c->leb_size - wbuf->offs - wbuf->used; |
---|
| 379 | + avail = c->leb_size - wbuf->offs - wbuf->used - |
---|
| 380 | + ubifs_auth_node_sz(c); |
---|
388 | 381 | if (avail < min) |
---|
389 | 382 | break; |
---|
390 | 383 | |
---|
.. | .. |
---|
402 | 395 | continue; |
---|
403 | 396 | } |
---|
404 | 397 | |
---|
| 398 | + err = ubifs_shash_update(c, c->jheads[GCHD].log_hash, |
---|
| 399 | + snod->node, snod->len); |
---|
| 400 | + if (err) |
---|
| 401 | + goto out; |
---|
| 402 | + |
---|
405 | 403 | err = move_node(c, sleb, snod, wbuf); |
---|
406 | 404 | if (err) |
---|
407 | 405 | goto out; |
---|
| 406 | + moved = 1; |
---|
| 407 | + } |
---|
| 408 | + |
---|
| 409 | + if (ubifs_authenticated(c) && moved) { |
---|
| 410 | + struct ubifs_auth_node *auth; |
---|
| 411 | + |
---|
| 412 | + auth = kmalloc(ubifs_auth_node_sz(c), GFP_NOFS); |
---|
| 413 | + if (!auth) { |
---|
| 414 | + err = -ENOMEM; |
---|
| 415 | + goto out; |
---|
| 416 | + } |
---|
| 417 | + |
---|
| 418 | + err = ubifs_prepare_auth_node(c, auth, |
---|
| 419 | + c->jheads[GCHD].log_hash); |
---|
| 420 | + if (err) { |
---|
| 421 | + kfree(auth); |
---|
| 422 | + goto out; |
---|
| 423 | + } |
---|
| 424 | + |
---|
| 425 | + err = ubifs_wbuf_write_nolock(wbuf, auth, |
---|
| 426 | + ubifs_auth_node_sz(c)); |
---|
| 427 | + if (err) { |
---|
| 428 | + kfree(auth); |
---|
| 429 | + goto out; |
---|
| 430 | + } |
---|
| 431 | + |
---|
| 432 | + ubifs_add_dirt(c, wbuf->lnum, ubifs_auth_node_sz(c)); |
---|
408 | 433 | } |
---|
409 | 434 | |
---|
410 | 435 | if (list_empty(&sleb->nodes) && list_empty(&nondata)) |
---|