| 352 | */ |
| 353 | |
| 354 | int jbd2_journal_write_metadata_buffer(transaction_t *transaction, |
| 355 | struct journal_head *jh_in, |
| 356 | struct buffer_head **bh_out, |
| 357 | sector_t blocknr) |
| 358 | { |
| 359 | int need_copy_out = 0; |
| 360 | int done_copy_out = 0; |
| 361 | int do_escape = 0; |
| 362 | char *mapped_data; |
| 363 | struct buffer_head *new_bh; |
| 364 | struct page *new_page; |
| 365 | unsigned int new_offset; |
| 366 | struct buffer_head *bh_in = jh2bh(jh_in); |
| 367 | journal_t *journal = transaction->t_journal; |
| 368 | |
| 369 | /* |
| 370 | * The buffer really shouldn't be locked: only the current committing |
| 371 | * transaction is allowed to write it, so nobody else is allowed |
| 372 | * to do any IO. |
| 373 | * |
| 374 | * akpm: except if we're journalling data, and write() output is |
| 375 | * also part of a shared mapping, and another thread has |
| 376 | * decided to launch a writepage() against this buffer. |
| 377 | */ |
| 378 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); |
| 379 | |
| 380 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); |
| 381 | |
| 382 | /* keep subsequent assertions sane */ |
| 383 | atomic_set(&new_bh->b_count, 1); |
| 384 | |
| 385 | jbd_lock_bh_state(bh_in); |
| 386 | repeat: |
| 387 | /* |
| 388 | * If a new transaction has already done a buffer copy-out, then |
| 389 | * we use that version of the data for the commit. |
| 390 | */ |
| 391 | if (jh_in->b_frozen_data) { |
| 392 | done_copy_out = 1; |
| 393 | new_page = virt_to_page(jh_in->b_frozen_data); |
| 394 | new_offset = offset_in_page(jh_in->b_frozen_data); |
| 395 | } else { |
| 396 | new_page = jh2bh(jh_in)->b_page; |
| 397 | new_offset = offset_in_page(jh2bh(jh_in)->b_data); |
| 398 | } |
| 399 | |
| 400 | mapped_data = kmap_atomic(new_page); |
| 401 | /* |
| 402 | * Fire data frozen trigger if data already wasn't frozen. Do this |
| 403 | * before checking for escaping, as the trigger may modify the magic |
| 404 | * offset. If a copy-out happens afterwards, it will have the correct |
| 405 | * data in the buffer. |
| 406 | */ |
| 407 | if (!done_copy_out) |
| 408 | jbd2_buffer_frozen_trigger(jh_in, mapped_data + new_offset, |
| 409 | jh_in->b_triggers); |
| 410 | |
| 411 | /* |
nothing calls this directly
no test coverage detected