| .. | .. |
|---|
| 66 | 66 | EXPORT_SYMBOL(jbd2_journal_set_triggers); |
|---|
| 67 | 67 | EXPORT_SYMBOL(jbd2_journal_dirty_metadata); |
|---|
| 68 | 68 | EXPORT_SYMBOL(jbd2_journal_forget); |
|---|
| 69 | | -#if 0 |
|---|
| 70 | | -EXPORT_SYMBOL(journal_sync_buffer); |
|---|
| 71 | | -#endif |
|---|
| 72 | 69 | EXPORT_SYMBOL(jbd2_journal_flush); |
|---|
| 73 | 70 | EXPORT_SYMBOL(jbd2_journal_revoke); |
|---|
| 74 | 71 | |
|---|
| .. | .. |
|---|
| 92 | 89 | EXPORT_SYMBOL(jbd2_journal_invalidatepage); |
|---|
| 93 | 90 | EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); |
|---|
| 94 | 91 | EXPORT_SYMBOL(jbd2_journal_force_commit); |
|---|
| 95 | | -EXPORT_SYMBOL(jbd2_journal_inode_add_write); |
|---|
| 96 | | -EXPORT_SYMBOL(jbd2_journal_inode_add_wait); |
|---|
| 97 | 92 | EXPORT_SYMBOL(jbd2_journal_inode_ranged_write); |
|---|
| 98 | 93 | EXPORT_SYMBOL(jbd2_journal_inode_ranged_wait); |
|---|
| 94 | +EXPORT_SYMBOL(jbd2_journal_submit_inode_data_buffers); |
|---|
| 95 | +EXPORT_SYMBOL(jbd2_journal_finish_inode_data_buffers); |
|---|
| 99 | 96 | EXPORT_SYMBOL(jbd2_journal_init_jbd_inode); |
|---|
| 100 | 97 | EXPORT_SYMBOL(jbd2_journal_release_jbd_inode); |
|---|
| 101 | 98 | EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate); |
|---|
| 102 | 99 | EXPORT_SYMBOL(jbd2_inode_cache); |
|---|
| 103 | 100 | |
|---|
| 104 | | -static void __journal_abort_soft (journal_t *journal, int errno); |
|---|
| 105 | 101 | static int jbd2_journal_create_slab(size_t slab_size); |
|---|
| 106 | 102 | |
|---|
| 107 | 103 | #ifdef CONFIG_JBD2_DEBUG |
|---|
| .. | .. |
|---|
| 144 | 140 | return cpu_to_be32(csum); |
|---|
| 145 | 141 | } |
|---|
| 146 | 142 | |
|---|
| 147 | | -static int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb) |
|---|
| 148 | | -{ |
|---|
| 149 | | - if (!jbd2_journal_has_csum_v2or3(j)) |
|---|
| 150 | | - return 1; |
|---|
| 151 | | - |
|---|
| 152 | | - return sb->s_checksum == jbd2_superblock_csum(j, sb); |
|---|
| 153 | | -} |
|---|
| 154 | | - |
|---|
| 155 | | -static void jbd2_superblock_csum_set(journal_t *j, journal_superblock_t *sb) |
|---|
| 156 | | -{ |
|---|
| 157 | | - if (!jbd2_journal_has_csum_v2or3(j)) |
|---|
| 158 | | - return; |
|---|
| 159 | | - |
|---|
| 160 | | - sb->s_checksum = jbd2_superblock_csum(j, sb); |
|---|
| 161 | | -} |
|---|
| 162 | | - |
|---|
| 163 | 143 | /* |
|---|
| 164 | 144 | * Helper function used to manage commit timeouts |
|---|
| 165 | 145 | */ |
|---|
| .. | .. |
|---|
| 179 | 159 | * |
|---|
| 180 | 160 | * 1) COMMIT: Every so often we need to commit the current state of the |
|---|
| 181 | 161 | * filesystem to disk. The journal thread is responsible for writing |
|---|
| 182 | | - * all of the metadata buffers to disk. |
|---|
| 162 | + * all of the metadata buffers to disk. If a fast commit is ongoing |
|---|
| 163 | + * journal thread waits until it's done and then continues from |
|---|
| 164 | + * there on. |
|---|
| 183 | 165 | * |
|---|
| 184 | 166 | * 2) CHECKPOINT: We cannot reuse a used section of the log file until all |
|---|
| 185 | 167 | * of the data in that part of the log has been rewritten elsewhere on |
|---|
| .. | .. |
|---|
| 221 | 203 | if (journal->j_flags & JBD2_UNMOUNT) |
|---|
| 222 | 204 | goto end_loop; |
|---|
| 223 | 205 | |
|---|
| 224 | | - jbd_debug(1, "commit_sequence=%d, commit_request=%d\n", |
|---|
| 206 | + jbd_debug(1, "commit_sequence=%u, commit_request=%u\n", |
|---|
| 225 | 207 | journal->j_commit_sequence, journal->j_commit_request); |
|---|
| 226 | 208 | |
|---|
| 227 | 209 | if (journal->j_commit_sequence != journal->j_commit_request) { |
|---|
| .. | .. |
|---|
| 342 | 324 | * IO is in progress. do_get_write_access() handles this. |
|---|
| 343 | 325 | * |
|---|
| 344 | 326 | * The function returns a pointer to the buffer_head to be used for IO. |
|---|
| 345 | | - * |
|---|
| 327 | + * |
|---|
| 346 | 328 | * |
|---|
| 347 | 329 | * Return value: |
|---|
| 348 | 330 | * <0: Error |
|---|
| .. | .. |
|---|
| 384 | 366 | /* keep subsequent assertions sane */ |
|---|
| 385 | 367 | atomic_set(&new_bh->b_count, 1); |
|---|
| 386 | 368 | |
|---|
| 387 | | - jbd_lock_bh_state(bh_in); |
|---|
| 369 | + spin_lock(&jh_in->b_state_lock); |
|---|
| 388 | 370 | repeat: |
|---|
| 389 | 371 | /* |
|---|
| 390 | 372 | * If a new transaction has already done a buffer copy-out, then |
|---|
| .. | .. |
|---|
| 426 | 408 | if (need_copy_out && !done_copy_out) { |
|---|
| 427 | 409 | char *tmp; |
|---|
| 428 | 410 | |
|---|
| 429 | | - jbd_unlock_bh_state(bh_in); |
|---|
| 411 | + spin_unlock(&jh_in->b_state_lock); |
|---|
| 430 | 412 | tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); |
|---|
| 431 | 413 | if (!tmp) { |
|---|
| 432 | 414 | brelse(new_bh); |
|---|
| 433 | 415 | return -ENOMEM; |
|---|
| 434 | 416 | } |
|---|
| 435 | | - jbd_lock_bh_state(bh_in); |
|---|
| 417 | + spin_lock(&jh_in->b_state_lock); |
|---|
| 436 | 418 | if (jh_in->b_frozen_data) { |
|---|
| 437 | 419 | jbd2_free(tmp, bh_in->b_size); |
|---|
| 438 | 420 | goto repeat; |
|---|
| .. | .. |
|---|
| 485 | 467 | __jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); |
|---|
| 486 | 468 | spin_unlock(&journal->j_list_lock); |
|---|
| 487 | 469 | set_buffer_shadow(bh_in); |
|---|
| 488 | | - jbd_unlock_bh_state(bh_in); |
|---|
| 470 | + spin_unlock(&jh_in->b_state_lock); |
|---|
| 489 | 471 | |
|---|
| 490 | 472 | return do_escape | (done_copy_out << 1); |
|---|
| 491 | 473 | } |
|---|
| .. | .. |
|---|
| 518 | 500 | */ |
|---|
| 519 | 501 | |
|---|
| 520 | 502 | journal->j_commit_request = target; |
|---|
| 521 | | - jbd_debug(1, "JBD2: requesting commit %d/%d\n", |
|---|
| 503 | + jbd_debug(1, "JBD2: requesting commit %u/%u\n", |
|---|
| 522 | 504 | journal->j_commit_request, |
|---|
| 523 | 505 | journal->j_commit_sequence); |
|---|
| 524 | 506 | journal->j_running_transaction->t_requested = jiffies; |
|---|
| .. | .. |
|---|
| 531 | 513 | WARN_ONCE(1, "JBD2: bad log_start_commit: %u %u %u %u\n", |
|---|
| 532 | 514 | journal->j_commit_request, |
|---|
| 533 | 515 | journal->j_commit_sequence, |
|---|
| 534 | | - target, journal->j_running_transaction ? |
|---|
| 516 | + target, journal->j_running_transaction ? |
|---|
| 535 | 517 | journal->j_running_transaction->t_tid : 0); |
|---|
| 536 | 518 | return 0; |
|---|
| 537 | 519 | } |
|---|
| .. | .. |
|---|
| 584 | 566 | } |
|---|
| 585 | 567 | |
|---|
| 586 | 568 | /** |
|---|
| 587 | | - * Force and wait upon a commit if the calling process is not within |
|---|
| 588 | | - * transaction. This is used for forcing out undo-protected data which contains |
|---|
| 589 | | - * bitmaps, when the fs is running out of space. |
|---|
| 569 | + * jbd2_journal_force_commit_nested - Force and wait upon a commit if the |
|---|
| 570 | + * calling process is not within transaction. |
|---|
| 590 | 571 | * |
|---|
| 591 | 572 | * @journal: journal to force |
|---|
| 592 | 573 | * Returns true if progress was made. |
|---|
| 574 | + * |
|---|
| 575 | + * This is used for forcing out undo-protected data which contains |
|---|
| 576 | + * bitmaps, when the fs is running out of space. |
|---|
| 593 | 577 | */ |
|---|
| 594 | 578 | int jbd2_journal_force_commit_nested(journal_t *journal) |
|---|
| 595 | 579 | { |
|---|
| .. | .. |
|---|
| 600 | 584 | } |
|---|
| 601 | 585 | |
|---|
| 602 | 586 | /** |
|---|
| 603 | | - * int journal_force_commit() - force any uncommitted transactions |
|---|
| 587 | + * jbd2_journal_force_commit() - force any uncommitted transactions |
|---|
| 604 | 588 | * @journal: journal to force |
|---|
| 605 | 589 | * |
|---|
| 606 | 590 | * Caller want unconditional commit. We can only force the running transaction |
|---|
| .. | .. |
|---|
| 716 | 700 | #ifdef CONFIG_JBD2_DEBUG |
|---|
| 717 | 701 | if (!tid_geq(journal->j_commit_request, tid)) { |
|---|
| 718 | 702 | printk(KERN_ERR |
|---|
| 719 | | - "%s: error: j_commit_request=%d, tid=%d\n", |
|---|
| 703 | + "%s: error: j_commit_request=%u, tid=%u\n", |
|---|
| 720 | 704 | __func__, journal->j_commit_request, tid); |
|---|
| 721 | 705 | } |
|---|
| 722 | 706 | #endif |
|---|
| 723 | 707 | while (tid_gt(tid, journal->j_commit_sequence)) { |
|---|
| 724 | | - jbd_debug(1, "JBD2: want %d, j_commit_sequence=%d\n", |
|---|
| 708 | + jbd_debug(1, "JBD2: want %u, j_commit_sequence=%u\n", |
|---|
| 725 | 709 | tid, journal->j_commit_sequence); |
|---|
| 726 | 710 | read_unlock(&journal->j_state_lock); |
|---|
| 727 | 711 | wake_up(&journal->j_wait_commit); |
|---|
| .. | .. |
|---|
| 735 | 719 | err = -EIO; |
|---|
| 736 | 720 | return err; |
|---|
| 737 | 721 | } |
|---|
| 722 | + |
|---|
| 723 | +/* |
|---|
| 724 | + * Start a fast commit. If there's an ongoing fast or full commit wait for |
|---|
| 725 | + * it to complete. Returns 0 if a new fast commit was started. Returns -EALREADY |
|---|
| 726 | + * if a fast commit is not needed, either because there's an already a commit |
|---|
| 727 | + * going on or this tid has already been committed. Returns -EINVAL if no jbd2 |
|---|
| 728 | + * commit has yet been performed. |
|---|
| 729 | + */ |
|---|
| 730 | +int jbd2_fc_begin_commit(journal_t *journal, tid_t tid) |
|---|
| 731 | +{ |
|---|
| 732 | + if (unlikely(is_journal_aborted(journal))) |
|---|
| 733 | + return -EIO; |
|---|
| 734 | + /* |
|---|
| 735 | + * Fast commits only allowed if at least one full commit has |
|---|
| 736 | + * been processed. |
|---|
| 737 | + */ |
|---|
| 738 | + if (!journal->j_stats.ts_tid) |
|---|
| 739 | + return -EINVAL; |
|---|
| 740 | + |
|---|
| 741 | + write_lock(&journal->j_state_lock); |
|---|
| 742 | + if (tid <= journal->j_commit_sequence) { |
|---|
| 743 | + write_unlock(&journal->j_state_lock); |
|---|
| 744 | + return -EALREADY; |
|---|
| 745 | + } |
|---|
| 746 | + |
|---|
| 747 | + if (journal->j_flags & JBD2_FULL_COMMIT_ONGOING || |
|---|
| 748 | + (journal->j_flags & JBD2_FAST_COMMIT_ONGOING)) { |
|---|
| 749 | + DEFINE_WAIT(wait); |
|---|
| 750 | + |
|---|
| 751 | + prepare_to_wait(&journal->j_fc_wait, &wait, |
|---|
| 752 | + TASK_UNINTERRUPTIBLE); |
|---|
| 753 | + write_unlock(&journal->j_state_lock); |
|---|
| 754 | + schedule(); |
|---|
| 755 | + finish_wait(&journal->j_fc_wait, &wait); |
|---|
| 756 | + return -EALREADY; |
|---|
| 757 | + } |
|---|
| 758 | + journal->j_flags |= JBD2_FAST_COMMIT_ONGOING; |
|---|
| 759 | + write_unlock(&journal->j_state_lock); |
|---|
| 760 | + jbd2_journal_lock_updates(journal); |
|---|
| 761 | + |
|---|
| 762 | + return 0; |
|---|
| 763 | +} |
|---|
| 764 | +EXPORT_SYMBOL(jbd2_fc_begin_commit); |
|---|
| 765 | + |
|---|
| 766 | +/* |
|---|
| 767 | + * Stop a fast commit. If fallback is set, this function starts commit of |
|---|
| 768 | + * TID tid before any other fast commit can start. |
|---|
| 769 | + */ |
|---|
| 770 | +static int __jbd2_fc_end_commit(journal_t *journal, tid_t tid, bool fallback) |
|---|
| 771 | +{ |
|---|
| 772 | + jbd2_journal_unlock_updates(journal); |
|---|
| 773 | + if (journal->j_fc_cleanup_callback) |
|---|
| 774 | + journal->j_fc_cleanup_callback(journal, 0); |
|---|
| 775 | + write_lock(&journal->j_state_lock); |
|---|
| 776 | + journal->j_flags &= ~JBD2_FAST_COMMIT_ONGOING; |
|---|
| 777 | + if (fallback) |
|---|
| 778 | + journal->j_flags |= JBD2_FULL_COMMIT_ONGOING; |
|---|
| 779 | + write_unlock(&journal->j_state_lock); |
|---|
| 780 | + wake_up(&journal->j_fc_wait); |
|---|
| 781 | + if (fallback) |
|---|
| 782 | + return jbd2_complete_transaction(journal, tid); |
|---|
| 783 | + return 0; |
|---|
| 784 | +} |
|---|
| 785 | + |
|---|
| 786 | +int jbd2_fc_end_commit(journal_t *journal) |
|---|
| 787 | +{ |
|---|
| 788 | + return __jbd2_fc_end_commit(journal, 0, false); |
|---|
| 789 | +} |
|---|
| 790 | +EXPORT_SYMBOL(jbd2_fc_end_commit); |
|---|
| 791 | + |
|---|
| 792 | +int jbd2_fc_end_commit_fallback(journal_t *journal) |
|---|
| 793 | +{ |
|---|
| 794 | + tid_t tid; |
|---|
| 795 | + |
|---|
| 796 | + read_lock(&journal->j_state_lock); |
|---|
| 797 | + tid = journal->j_running_transaction ? |
|---|
| 798 | + journal->j_running_transaction->t_tid : 0; |
|---|
| 799 | + read_unlock(&journal->j_state_lock); |
|---|
| 800 | + return __jbd2_fc_end_commit(journal, tid, true); |
|---|
| 801 | +} |
|---|
| 802 | +EXPORT_SYMBOL(jbd2_fc_end_commit_fallback); |
|---|
| 738 | 803 | |
|---|
| 739 | 804 | /* Return 1 when transaction with given tid has already committed. */ |
|---|
| 740 | 805 | int jbd2_transaction_committed(journal_t *journal, tid_t tid) |
|---|
| .. | .. |
|---|
| 804 | 869 | return jbd2_journal_bmap(journal, blocknr, retp); |
|---|
| 805 | 870 | } |
|---|
| 806 | 871 | |
|---|
| 872 | +/* Map one fast commit buffer for use by the file system */ |
|---|
| 873 | +int jbd2_fc_get_buf(journal_t *journal, struct buffer_head **bh_out) |
|---|
| 874 | +{ |
|---|
| 875 | + unsigned long long pblock; |
|---|
| 876 | + unsigned long blocknr; |
|---|
| 877 | + int ret = 0; |
|---|
| 878 | + struct buffer_head *bh; |
|---|
| 879 | + int fc_off; |
|---|
| 880 | + |
|---|
| 881 | + *bh_out = NULL; |
|---|
| 882 | + |
|---|
| 883 | + if (journal->j_fc_off + journal->j_fc_first < journal->j_fc_last) { |
|---|
| 884 | + fc_off = journal->j_fc_off; |
|---|
| 885 | + blocknr = journal->j_fc_first + fc_off; |
|---|
| 886 | + journal->j_fc_off++; |
|---|
| 887 | + } else { |
|---|
| 888 | + ret = -EINVAL; |
|---|
| 889 | + } |
|---|
| 890 | + |
|---|
| 891 | + if (ret) |
|---|
| 892 | + return ret; |
|---|
| 893 | + |
|---|
| 894 | + ret = jbd2_journal_bmap(journal, blocknr, &pblock); |
|---|
| 895 | + if (ret) |
|---|
| 896 | + return ret; |
|---|
| 897 | + |
|---|
| 898 | + bh = __getblk(journal->j_dev, pblock, journal->j_blocksize); |
|---|
| 899 | + if (!bh) |
|---|
| 900 | + return -ENOMEM; |
|---|
| 901 | + |
|---|
| 902 | + |
|---|
| 903 | + journal->j_fc_wbuf[fc_off] = bh; |
|---|
| 904 | + |
|---|
| 905 | + *bh_out = bh; |
|---|
| 906 | + |
|---|
| 907 | + return 0; |
|---|
| 908 | +} |
|---|
| 909 | +EXPORT_SYMBOL(jbd2_fc_get_buf); |
|---|
| 910 | + |
|---|
| 911 | +/* |
|---|
| 912 | + * Wait on fast commit buffers that were allocated by jbd2_fc_get_buf |
|---|
| 913 | + * for completion. |
|---|
| 914 | + */ |
|---|
| 915 | +int jbd2_fc_wait_bufs(journal_t *journal, int num_blks) |
|---|
| 916 | +{ |
|---|
| 917 | + struct buffer_head *bh; |
|---|
| 918 | + int i, j_fc_off; |
|---|
| 919 | + |
|---|
| 920 | + j_fc_off = journal->j_fc_off; |
|---|
| 921 | + |
|---|
| 922 | + /* |
|---|
| 923 | + * Wait in reverse order to minimize chances of us being woken up before |
|---|
| 924 | + * all IOs have completed |
|---|
| 925 | + */ |
|---|
| 926 | + for (i = j_fc_off - 1; i >= j_fc_off - num_blks; i--) { |
|---|
| 927 | + bh = journal->j_fc_wbuf[i]; |
|---|
| 928 | + wait_on_buffer(bh); |
|---|
| 929 | + /* |
|---|
| 930 | + * Update j_fc_off so jbd2_fc_release_bufs can release remain |
|---|
| 931 | + * buffer head. |
|---|
| 932 | + */ |
|---|
| 933 | + if (unlikely(!buffer_uptodate(bh))) { |
|---|
| 934 | + journal->j_fc_off = i + 1; |
|---|
| 935 | + return -EIO; |
|---|
| 936 | + } |
|---|
| 937 | + put_bh(bh); |
|---|
| 938 | + journal->j_fc_wbuf[i] = NULL; |
|---|
| 939 | + } |
|---|
| 940 | + |
|---|
| 941 | + return 0; |
|---|
| 942 | +} |
|---|
| 943 | +EXPORT_SYMBOL(jbd2_fc_wait_bufs); |
|---|
| 944 | + |
|---|
| 945 | +/* |
|---|
| 946 | + * Wait on fast commit buffers that were allocated by jbd2_fc_get_buf |
|---|
| 947 | + * for completion. |
|---|
| 948 | + */ |
|---|
| 949 | +int jbd2_fc_release_bufs(journal_t *journal) |
|---|
| 950 | +{ |
|---|
| 951 | + struct buffer_head *bh; |
|---|
| 952 | + int i, j_fc_off; |
|---|
| 953 | + |
|---|
| 954 | + j_fc_off = journal->j_fc_off; |
|---|
| 955 | + |
|---|
| 956 | + /* |
|---|
| 957 | + * Wait in reverse order to minimize chances of us being woken up before |
|---|
| 958 | + * all IOs have completed |
|---|
| 959 | + */ |
|---|
| 960 | + for (i = j_fc_off - 1; i >= 0; i--) { |
|---|
| 961 | + bh = journal->j_fc_wbuf[i]; |
|---|
| 962 | + if (!bh) |
|---|
| 963 | + break; |
|---|
| 964 | + put_bh(bh); |
|---|
| 965 | + journal->j_fc_wbuf[i] = NULL; |
|---|
| 966 | + } |
|---|
| 967 | + |
|---|
| 968 | + return 0; |
|---|
| 969 | +} |
|---|
| 970 | +EXPORT_SYMBOL(jbd2_fc_release_bufs); |
|---|
| 971 | + |
|---|
| 807 | 972 | /* |
|---|
| 808 | 973 | * Conversion of logical to physical block numbers for the journal |
|---|
| 809 | 974 | * |
|---|
| .. | .. |
|---|
| 816 | 981 | { |
|---|
| 817 | 982 | int err = 0; |
|---|
| 818 | 983 | unsigned long long ret; |
|---|
| 984 | + sector_t block = 0; |
|---|
| 819 | 985 | |
|---|
| 820 | 986 | if (journal->j_inode) { |
|---|
| 821 | | - ret = bmap(journal->j_inode, blocknr); |
|---|
| 822 | | - if (ret) |
|---|
| 823 | | - *retp = ret; |
|---|
| 824 | | - else { |
|---|
| 987 | + block = blocknr; |
|---|
| 988 | + ret = bmap(journal->j_inode, &block); |
|---|
| 989 | + |
|---|
| 990 | + if (ret || !block) { |
|---|
| 825 | 991 | printk(KERN_ALERT "%s: journal block not found " |
|---|
| 826 | 992 | "at offset %lu on %s\n", |
|---|
| 827 | 993 | __func__, blocknr, journal->j_devname); |
|---|
| 828 | 994 | err = -EIO; |
|---|
| 829 | | - __journal_abort_soft(journal, err); |
|---|
| 995 | + jbd2_journal_abort(journal, err); |
|---|
| 996 | + } else { |
|---|
| 997 | + *retp = block; |
|---|
| 830 | 998 | } |
|---|
| 999 | + |
|---|
| 831 | 1000 | } else { |
|---|
| 832 | 1001 | *retp = blocknr; /* +journal->j_blk_offset */ |
|---|
| 833 | 1002 | } |
|---|
| .. | .. |
|---|
| 861 | 1030 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); |
|---|
| 862 | 1031 | if (!bh) |
|---|
| 863 | 1032 | return NULL; |
|---|
| 1033 | + atomic_dec(&transaction->t_outstanding_credits); |
|---|
| 864 | 1034 | lock_buffer(bh); |
|---|
| 865 | 1035 | memset(bh->b_data, 0, journal->j_blocksize); |
|---|
| 866 | 1036 | header = (journal_header_t *)bh->b_data; |
|---|
| .. | .. |
|---|
| 962 | 1132 | |
|---|
| 963 | 1133 | trace_jbd2_update_log_tail(journal, tid, block, freed); |
|---|
| 964 | 1134 | jbd_debug(1, |
|---|
| 965 | | - "Cleaning journal tail from %d to %d (offset %lu), " |
|---|
| 1135 | + "Cleaning journal tail from %u to %u (offset %lu), " |
|---|
| 966 | 1136 | "freeing %lu\n", |
|---|
| 967 | 1137 | journal->j_tail_sequence, tid, block, freed); |
|---|
| 968 | 1138 | |
|---|
| .. | .. |
|---|
| 1095 | 1265 | return seq_release(inode, file); |
|---|
| 1096 | 1266 | } |
|---|
| 1097 | 1267 | |
|---|
| 1098 | | -static const struct file_operations jbd2_seq_info_fops = { |
|---|
| 1099 | | - .owner = THIS_MODULE, |
|---|
| 1100 | | - .open = jbd2_seq_info_open, |
|---|
| 1101 | | - .read = seq_read, |
|---|
| 1102 | | - .llseek = seq_lseek, |
|---|
| 1103 | | - .release = jbd2_seq_info_release, |
|---|
| 1268 | +static const struct proc_ops jbd2_info_proc_ops = { |
|---|
| 1269 | + .proc_open = jbd2_seq_info_open, |
|---|
| 1270 | + .proc_read = seq_read, |
|---|
| 1271 | + .proc_lseek = seq_lseek, |
|---|
| 1272 | + .proc_release = jbd2_seq_info_release, |
|---|
| 1104 | 1273 | }; |
|---|
| 1105 | 1274 | |
|---|
| 1106 | 1275 | static struct proc_dir_entry *proc_jbd2_stats; |
|---|
| .. | .. |
|---|
| 1110 | 1279 | journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats); |
|---|
| 1111 | 1280 | if (journal->j_proc_entry) { |
|---|
| 1112 | 1281 | proc_create_data("info", S_IRUGO, journal->j_proc_entry, |
|---|
| 1113 | | - &jbd2_seq_info_fops, journal); |
|---|
| 1282 | + &jbd2_info_proc_ops, journal); |
|---|
| 1114 | 1283 | } |
|---|
| 1115 | 1284 | } |
|---|
| 1116 | 1285 | |
|---|
| .. | .. |
|---|
| 1118 | 1287 | { |
|---|
| 1119 | 1288 | remove_proc_entry("info", journal->j_proc_entry); |
|---|
| 1120 | 1289 | remove_proc_entry(journal->j_devname, proc_jbd2_stats); |
|---|
| 1290 | +} |
|---|
| 1291 | + |
|---|
| 1292 | +/* Minimum size of descriptor tag */ |
|---|
| 1293 | +static int jbd2_min_tag_size(void) |
|---|
| 1294 | +{ |
|---|
| 1295 | + /* |
|---|
| 1296 | + * Tag with 32-bit block numbers does not use last four bytes of the |
|---|
| 1297 | + * structure |
|---|
| 1298 | + */ |
|---|
| 1299 | + return sizeof(journal_block_tag_t) - 4; |
|---|
| 1121 | 1300 | } |
|---|
| 1122 | 1301 | |
|---|
| 1123 | 1302 | /* |
|---|
| .. | .. |
|---|
| 1148 | 1327 | init_waitqueue_head(&journal->j_wait_commit); |
|---|
| 1149 | 1328 | init_waitqueue_head(&journal->j_wait_updates); |
|---|
| 1150 | 1329 | init_waitqueue_head(&journal->j_wait_reserved); |
|---|
| 1330 | + init_waitqueue_head(&journal->j_fc_wait); |
|---|
| 1331 | + mutex_init(&journal->j_abort_mutex); |
|---|
| 1151 | 1332 | mutex_init(&journal->j_barrier); |
|---|
| 1152 | 1333 | mutex_init(&journal->j_checkpoint_mutex); |
|---|
| 1153 | 1334 | spin_lock_init(&journal->j_revoke_lock); |
|---|
| .. | .. |
|---|
| 1177 | 1358 | journal->j_dev = bdev; |
|---|
| 1178 | 1359 | journal->j_fs_dev = fs_dev; |
|---|
| 1179 | 1360 | journal->j_blk_offset = start; |
|---|
| 1180 | | - journal->j_maxlen = len; |
|---|
| 1181 | | - n = journal->j_blocksize / sizeof(journal_block_tag_t); |
|---|
| 1361 | + journal->j_total_len = len; |
|---|
| 1362 | + /* We need enough buffers to write out full descriptor block. */ |
|---|
| 1363 | + n = journal->j_blocksize / jbd2_min_tag_size(); |
|---|
| 1182 | 1364 | journal->j_wbufsize = n; |
|---|
| 1365 | + journal->j_fc_wbuf = NULL; |
|---|
| 1183 | 1366 | journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *), |
|---|
| 1184 | 1367 | GFP_KERNEL); |
|---|
| 1185 | 1368 | if (!journal->j_wbuf) |
|---|
| .. | .. |
|---|
| 1254 | 1437 | journal_t *jbd2_journal_init_inode(struct inode *inode) |
|---|
| 1255 | 1438 | { |
|---|
| 1256 | 1439 | journal_t *journal; |
|---|
| 1440 | + sector_t blocknr; |
|---|
| 1257 | 1441 | char *p; |
|---|
| 1258 | | - unsigned long long blocknr; |
|---|
| 1442 | + int err = 0; |
|---|
| 1259 | 1443 | |
|---|
| 1260 | | - blocknr = bmap(inode, 0); |
|---|
| 1261 | | - if (!blocknr) { |
|---|
| 1444 | + blocknr = 0; |
|---|
| 1445 | + err = bmap(inode, &blocknr); |
|---|
| 1446 | + |
|---|
| 1447 | + if (err || !blocknr) { |
|---|
| 1262 | 1448 | pr_err("%s: Cannot locate journal superblock\n", |
|---|
| 1263 | 1449 | __func__); |
|---|
| 1264 | 1450 | return NULL; |
|---|
| .. | .. |
|---|
| 1288 | 1474 | * superblock as being NULL to prevent the journal destroy from writing |
|---|
| 1289 | 1475 | * back a bogus superblock. |
|---|
| 1290 | 1476 | */ |
|---|
| 1291 | | -static void journal_fail_superblock (journal_t *journal) |
|---|
| 1477 | +static void journal_fail_superblock(journal_t *journal) |
|---|
| 1292 | 1478 | { |
|---|
| 1293 | 1479 | struct buffer_head *bh = journal->j_sb_buffer; |
|---|
| 1294 | 1480 | brelse(bh); |
|---|
| .. | .. |
|---|
| 1319 | 1505 | journal->j_first = first; |
|---|
| 1320 | 1506 | journal->j_last = last; |
|---|
| 1321 | 1507 | |
|---|
| 1322 | | - journal->j_head = first; |
|---|
| 1323 | | - journal->j_tail = first; |
|---|
| 1324 | | - journal->j_free = last - first; |
|---|
| 1508 | + journal->j_head = journal->j_first; |
|---|
| 1509 | + journal->j_tail = journal->j_first; |
|---|
| 1510 | + journal->j_free = journal->j_last - journal->j_first; |
|---|
| 1325 | 1511 | |
|---|
| 1326 | 1512 | journal->j_tail_sequence = journal->j_transaction_sequence; |
|---|
| 1327 | 1513 | journal->j_commit_sequence = journal->j_transaction_sequence - 1; |
|---|
| 1328 | 1514 | journal->j_commit_request = journal->j_commit_sequence; |
|---|
| 1329 | 1515 | |
|---|
| 1330 | | - journal->j_max_transaction_buffers = journal->j_maxlen / 4; |
|---|
| 1516 | + journal->j_max_transaction_buffers = jbd2_journal_get_max_txn_bufs(journal); |
|---|
| 1517 | + |
|---|
| 1518 | + /* |
|---|
| 1519 | + * Now that journal recovery is done, turn fast commits off here. This |
|---|
| 1520 | + * way, if fast commit was enabled before the crash but if now FS has |
|---|
| 1521 | + * disabled it, we don't enable fast commits. |
|---|
| 1522 | + */ |
|---|
| 1523 | + jbd2_clear_feature_fast_commit(journal); |
|---|
| 1331 | 1524 | |
|---|
| 1332 | 1525 | /* |
|---|
| 1333 | 1526 | * As a special case, if the on-disk copy is already marked as needing |
|---|
| .. | .. |
|---|
| 1337 | 1530 | */ |
|---|
| 1338 | 1531 | if (sb->s_start == 0) { |
|---|
| 1339 | 1532 | jbd_debug(1, "JBD2: Skipping superblock update on recovered sb " |
|---|
| 1340 | | - "(start %ld, seq %d, errno %d)\n", |
|---|
| 1533 | + "(start %ld, seq %u, errno %d)\n", |
|---|
| 1341 | 1534 | journal->j_tail, journal->j_tail_sequence, |
|---|
| 1342 | 1535 | journal->j_errno); |
|---|
| 1343 | 1536 | journal->j_flags |= JBD2_FLUSHED; |
|---|
| .. | .. |
|---|
| 1393 | 1586 | clear_buffer_write_io_error(bh); |
|---|
| 1394 | 1587 | set_buffer_uptodate(bh); |
|---|
| 1395 | 1588 | } |
|---|
| 1396 | | - jbd2_superblock_csum_set(journal, sb); |
|---|
| 1589 | + if (jbd2_journal_has_csum_v2or3(journal)) |
|---|
| 1590 | + sb->s_checksum = jbd2_superblock_csum(journal, sb); |
|---|
| 1397 | 1591 | get_bh(bh); |
|---|
| 1398 | 1592 | bh->b_end_io = end_buffer_write_sync; |
|---|
| 1399 | 1593 | ret = submit_bh(REQ_OP_WRITE, write_flags, bh); |
|---|
| .. | .. |
|---|
| 1407 | 1601 | printk(KERN_ERR "JBD2: Error %d detected when updating " |
|---|
| 1408 | 1602 | "journal superblock for %s.\n", ret, |
|---|
| 1409 | 1603 | journal->j_devname); |
|---|
| 1410 | | - jbd2_journal_abort(journal, ret); |
|---|
| 1604 | + if (!is_journal_aborted(journal)) |
|---|
| 1605 | + jbd2_journal_abort(journal, ret); |
|---|
| 1411 | 1606 | } |
|---|
| 1412 | 1607 | |
|---|
| 1413 | 1608 | return ret; |
|---|
| .. | .. |
|---|
| 1465 | 1660 | static void jbd2_mark_journal_empty(journal_t *journal, int write_op) |
|---|
| 1466 | 1661 | { |
|---|
| 1467 | 1662 | journal_superblock_t *sb = journal->j_superblock; |
|---|
| 1663 | + bool had_fast_commit = false; |
|---|
| 1468 | 1664 | |
|---|
| 1469 | 1665 | BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); |
|---|
| 1470 | 1666 | lock_buffer(journal->j_sb_buffer); |
|---|
| .. | .. |
|---|
| 1473 | 1669 | return; |
|---|
| 1474 | 1670 | } |
|---|
| 1475 | 1671 | |
|---|
| 1476 | | - jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n", |
|---|
| 1672 | + jbd_debug(1, "JBD2: Marking journal as empty (seq %u)\n", |
|---|
| 1477 | 1673 | journal->j_tail_sequence); |
|---|
| 1478 | 1674 | |
|---|
| 1479 | 1675 | sb->s_sequence = cpu_to_be32(journal->j_tail_sequence); |
|---|
| 1480 | 1676 | sb->s_start = cpu_to_be32(0); |
|---|
| 1677 | + if (jbd2_has_feature_fast_commit(journal)) { |
|---|
| 1678 | + /* |
|---|
| 1679 | + * When journal is clean, no need to commit fast commit flag and |
|---|
| 1680 | + * make file system incompatible with older kernels. |
|---|
| 1681 | + */ |
|---|
| 1682 | + jbd2_clear_feature_fast_commit(journal); |
|---|
| 1683 | + had_fast_commit = true; |
|---|
| 1684 | + } |
|---|
| 1481 | 1685 | |
|---|
| 1482 | 1686 | jbd2_write_superblock(journal, write_op); |
|---|
| 1687 | + |
|---|
| 1688 | + if (had_fast_commit) |
|---|
| 1689 | + jbd2_set_feature_fast_commit(journal); |
|---|
| 1483 | 1690 | |
|---|
| 1484 | 1691 | /* Log is no longer empty */ |
|---|
| 1485 | 1692 | write_lock(&journal->j_state_lock); |
|---|
| .. | .. |
|---|
| 1510 | 1717 | jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA); |
|---|
| 1511 | 1718 | } |
|---|
| 1512 | 1719 | EXPORT_SYMBOL(jbd2_journal_update_sb_errno); |
|---|
| 1720 | + |
|---|
| 1721 | +static int journal_revoke_records_per_block(journal_t *journal) |
|---|
| 1722 | +{ |
|---|
| 1723 | + int record_size; |
|---|
| 1724 | + int space = journal->j_blocksize - sizeof(jbd2_journal_revoke_header_t); |
|---|
| 1725 | + |
|---|
| 1726 | + if (jbd2_has_feature_64bit(journal)) |
|---|
| 1727 | + record_size = 8; |
|---|
| 1728 | + else |
|---|
| 1729 | + record_size = 4; |
|---|
| 1730 | + |
|---|
| 1731 | + if (jbd2_journal_has_csum_v2or3(journal)) |
|---|
| 1732 | + space -= sizeof(struct jbd2_journal_block_tail); |
|---|
| 1733 | + return space / record_size; |
|---|
| 1734 | +} |
|---|
| 1513 | 1735 | |
|---|
| 1514 | 1736 | /* |
|---|
| 1515 | 1737 | * Read the superblock for a given journal, performing initial |
|---|
| .. | .. |
|---|
| 1559 | 1781 | goto out; |
|---|
| 1560 | 1782 | } |
|---|
| 1561 | 1783 | |
|---|
| 1562 | | - if (be32_to_cpu(sb->s_maxlen) < journal->j_maxlen) |
|---|
| 1563 | | - journal->j_maxlen = be32_to_cpu(sb->s_maxlen); |
|---|
| 1564 | | - else if (be32_to_cpu(sb->s_maxlen) > journal->j_maxlen) { |
|---|
| 1784 | + if (be32_to_cpu(sb->s_maxlen) < journal->j_total_len) |
|---|
| 1785 | + journal->j_total_len = be32_to_cpu(sb->s_maxlen); |
|---|
| 1786 | + else if (be32_to_cpu(sb->s_maxlen) > journal->j_total_len) { |
|---|
| 1565 | 1787 | printk(KERN_WARNING "JBD2: journal file too short\n"); |
|---|
| 1566 | 1788 | goto out; |
|---|
| 1567 | 1789 | } |
|---|
| 1568 | 1790 | |
|---|
| 1569 | 1791 | if (be32_to_cpu(sb->s_first) == 0 || |
|---|
| 1570 | | - be32_to_cpu(sb->s_first) >= journal->j_maxlen) { |
|---|
| 1792 | + be32_to_cpu(sb->s_first) >= journal->j_total_len) { |
|---|
| 1571 | 1793 | printk(KERN_WARNING |
|---|
| 1572 | 1794 | "JBD2: Invalid start block of journal: %u\n", |
|---|
| 1573 | 1795 | be32_to_cpu(sb->s_first)); |
|---|
| .. | .. |
|---|
| 1606 | 1828 | } |
|---|
| 1607 | 1829 | } |
|---|
| 1608 | 1830 | |
|---|
| 1609 | | - /* Check superblock checksum */ |
|---|
| 1610 | | - if (!jbd2_superblock_csum_verify(journal, sb)) { |
|---|
| 1611 | | - printk(KERN_ERR "JBD2: journal checksum error\n"); |
|---|
| 1612 | | - err = -EFSBADCRC; |
|---|
| 1613 | | - goto out; |
|---|
| 1614 | | - } |
|---|
| 1831 | + if (jbd2_journal_has_csum_v2or3(journal)) { |
|---|
| 1832 | + /* Check superblock checksum */ |
|---|
| 1833 | + if (sb->s_checksum != jbd2_superblock_csum(journal, sb)) { |
|---|
| 1834 | + printk(KERN_ERR "JBD2: journal checksum error\n"); |
|---|
| 1835 | + err = -EFSBADCRC; |
|---|
| 1836 | + goto out; |
|---|
| 1837 | + } |
|---|
| 1615 | 1838 | |
|---|
| 1616 | | - /* Precompute checksum seed for all metadata */ |
|---|
| 1617 | | - if (jbd2_journal_has_csum_v2or3(journal)) |
|---|
| 1839 | + /* Precompute checksum seed for all metadata */ |
|---|
| 1618 | 1840 | journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, |
|---|
| 1619 | 1841 | sizeof(sb->s_uuid)); |
|---|
| 1842 | + } |
|---|
| 1620 | 1843 | |
|---|
| 1844 | + journal->j_revoke_records_per_block = |
|---|
| 1845 | + journal_revoke_records_per_block(journal); |
|---|
| 1621 | 1846 | set_buffer_verified(bh); |
|---|
| 1622 | 1847 | |
|---|
| 1623 | 1848 | return 0; |
|---|
| .. | .. |
|---|
| 1636 | 1861 | { |
|---|
| 1637 | 1862 | int err; |
|---|
| 1638 | 1863 | journal_superblock_t *sb; |
|---|
| 1864 | + int num_fc_blocks; |
|---|
| 1639 | 1865 | |
|---|
| 1640 | 1866 | err = journal_get_superblock(journal); |
|---|
| 1641 | 1867 | if (err) |
|---|
| .. | .. |
|---|
| 1646 | 1872 | journal->j_tail_sequence = be32_to_cpu(sb->s_sequence); |
|---|
| 1647 | 1873 | journal->j_tail = be32_to_cpu(sb->s_start); |
|---|
| 1648 | 1874 | journal->j_first = be32_to_cpu(sb->s_first); |
|---|
| 1649 | | - journal->j_last = be32_to_cpu(sb->s_maxlen); |
|---|
| 1650 | 1875 | journal->j_errno = be32_to_cpu(sb->s_errno); |
|---|
| 1876 | + journal->j_last = be32_to_cpu(sb->s_maxlen); |
|---|
| 1877 | + |
|---|
| 1878 | + if (jbd2_has_feature_fast_commit(journal)) { |
|---|
| 1879 | + journal->j_fc_last = be32_to_cpu(sb->s_maxlen); |
|---|
| 1880 | + num_fc_blocks = be32_to_cpu(sb->s_num_fc_blks); |
|---|
| 1881 | + if (!num_fc_blocks) |
|---|
| 1882 | + num_fc_blocks = JBD2_MIN_FC_BLOCKS; |
|---|
| 1883 | + if (journal->j_last - num_fc_blocks >= JBD2_MIN_JOURNAL_BLOCKS) |
|---|
| 1884 | + journal->j_last = journal->j_fc_last - num_fc_blocks; |
|---|
| 1885 | + journal->j_fc_first = journal->j_last + 1; |
|---|
| 1886 | + journal->j_fc_off = 0; |
|---|
| 1887 | + } |
|---|
| 1651 | 1888 | |
|---|
| 1652 | 1889 | return 0; |
|---|
| 1653 | 1890 | } |
|---|
| 1654 | 1891 | |
|---|
| 1655 | 1892 | |
|---|
| 1656 | 1893 | /** |
|---|
| 1657 | | - * int jbd2_journal_load() - Read journal from disk. |
|---|
| 1894 | + * jbd2_journal_load() - Read journal from disk. |
|---|
| 1658 | 1895 | * @journal: Journal to act on. |
|---|
| 1659 | 1896 | * |
|---|
| 1660 | 1897 | * Given a journal_t structure which tells us which disk blocks contain |
|---|
| .. | .. |
|---|
| 1724 | 1961 | } |
|---|
| 1725 | 1962 | |
|---|
| 1726 | 1963 | /** |
|---|
| 1727 | | - * void jbd2_journal_destroy() - Release a journal_t structure. |
|---|
| 1964 | + * jbd2_journal_destroy() - Release a journal_t structure. |
|---|
| 1728 | 1965 | * @journal: Journal to act on. |
|---|
| 1729 | 1966 | * |
|---|
| 1730 | 1967 | * Release a journal_t structure once it is no longer in use by the |
|---|
| .. | .. |
|---|
| 1792 | 2029 | jbd2_journal_destroy_revoke(journal); |
|---|
| 1793 | 2030 | if (journal->j_chksum_driver) |
|---|
| 1794 | 2031 | crypto_free_shash(journal->j_chksum_driver); |
|---|
| 2032 | + kfree(journal->j_fc_wbuf); |
|---|
| 1795 | 2033 | kfree(journal->j_wbuf); |
|---|
| 1796 | 2034 | kfree(journal); |
|---|
| 1797 | 2035 | |
|---|
| .. | .. |
|---|
| 1800 | 2038 | |
|---|
| 1801 | 2039 | |
|---|
| 1802 | 2040 | /** |
|---|
| 1803 | | - *int jbd2_journal_check_used_features () - Check if features specified are used. |
|---|
| 2041 | + * jbd2_journal_check_used_features() - Check if features specified are used. |
|---|
| 1804 | 2042 | * @journal: Journal to check. |
|---|
| 1805 | 2043 | * @compat: bitmask of compatible features |
|---|
| 1806 | 2044 | * @ro: bitmask of features that force read-only mount |
|---|
| .. | .. |
|---|
| 1810 | 2048 | * features. Return true (non-zero) if it does. |
|---|
| 1811 | 2049 | **/ |
|---|
| 1812 | 2050 | |
|---|
| 1813 | | -int jbd2_journal_check_used_features (journal_t *journal, unsigned long compat, |
|---|
| 2051 | +int jbd2_journal_check_used_features(journal_t *journal, unsigned long compat, |
|---|
| 1814 | 2052 | unsigned long ro, unsigned long incompat) |
|---|
| 1815 | 2053 | { |
|---|
| 1816 | 2054 | journal_superblock_t *sb; |
|---|
| .. | .. |
|---|
| 1835 | 2073 | } |
|---|
| 1836 | 2074 | |
|---|
| 1837 | 2075 | /** |
|---|
| 1838 | | - * int jbd2_journal_check_available_features() - Check feature set in journalling layer |
|---|
| 2076 | + * jbd2_journal_check_available_features() - Check feature set in journalling layer |
|---|
| 1839 | 2077 | * @journal: Journal to check. |
|---|
| 1840 | 2078 | * @compat: bitmask of compatible features |
|---|
| 1841 | 2079 | * @ro: bitmask of features that force read-only mount |
|---|
| .. | .. |
|---|
| 1845 | 2083 | * all of a given set of features on this journal. Return true |
|---|
| 1846 | 2084 | * (non-zero) if it can. */ |
|---|
| 1847 | 2085 | |
|---|
| 1848 | | -int jbd2_journal_check_available_features (journal_t *journal, unsigned long compat, |
|---|
| 2086 | +int jbd2_journal_check_available_features(journal_t *journal, unsigned long compat, |
|---|
| 1849 | 2087 | unsigned long ro, unsigned long incompat) |
|---|
| 1850 | 2088 | { |
|---|
| 1851 | 2089 | if (!compat && !ro && !incompat) |
|---|
| .. | .. |
|---|
| 1866 | 2104 | return 0; |
|---|
| 1867 | 2105 | } |
|---|
| 1868 | 2106 | |
|---|
| 2107 | +static int |
|---|
| 2108 | +jbd2_journal_initialize_fast_commit(journal_t *journal) |
|---|
| 2109 | +{ |
|---|
| 2110 | + journal_superblock_t *sb = journal->j_superblock; |
|---|
| 2111 | + unsigned long long num_fc_blks; |
|---|
| 2112 | + |
|---|
| 2113 | + num_fc_blks = be32_to_cpu(sb->s_num_fc_blks); |
|---|
| 2114 | + if (num_fc_blks == 0) |
|---|
| 2115 | + num_fc_blks = JBD2_MIN_FC_BLOCKS; |
|---|
| 2116 | + if (journal->j_last - num_fc_blks < JBD2_MIN_JOURNAL_BLOCKS) |
|---|
| 2117 | + return -ENOSPC; |
|---|
| 2118 | + |
|---|
| 2119 | + /* Are we called twice? */ |
|---|
| 2120 | + WARN_ON(journal->j_fc_wbuf != NULL); |
|---|
| 2121 | + journal->j_fc_wbuf = kmalloc_array(num_fc_blks, |
|---|
| 2122 | + sizeof(struct buffer_head *), GFP_KERNEL); |
|---|
| 2123 | + if (!journal->j_fc_wbuf) |
|---|
| 2124 | + return -ENOMEM; |
|---|
| 2125 | + |
|---|
| 2126 | + journal->j_fc_wbufsize = num_fc_blks; |
|---|
| 2127 | + journal->j_fc_last = journal->j_last; |
|---|
| 2128 | + journal->j_last = journal->j_fc_last - num_fc_blks; |
|---|
| 2129 | + journal->j_fc_first = journal->j_last + 1; |
|---|
| 2130 | + journal->j_fc_off = 0; |
|---|
| 2131 | + journal->j_free = journal->j_last - journal->j_first; |
|---|
| 2132 | + journal->j_max_transaction_buffers = |
|---|
| 2133 | + jbd2_journal_get_max_txn_bufs(journal); |
|---|
| 2134 | + |
|---|
| 2135 | + return 0; |
|---|
| 2136 | +} |
|---|
| 2137 | + |
|---|
| 1869 | 2138 | /** |
|---|
| 1870 | | - * int jbd2_journal_set_features () - Mark a given journal feature in the superblock |
|---|
| 2139 | + * jbd2_journal_set_features() - Mark a given journal feature in the superblock |
|---|
| 1871 | 2140 | * @journal: Journal to act on. |
|---|
| 1872 | 2141 | * @compat: bitmask of compatible features |
|---|
| 1873 | 2142 | * @ro: bitmask of features that force read-only mount |
|---|
| .. | .. |
|---|
| 1878 | 2147 | * |
|---|
| 1879 | 2148 | */ |
|---|
| 1880 | 2149 | |
|---|
| 1881 | | -int jbd2_journal_set_features (journal_t *journal, unsigned long compat, |
|---|
| 2150 | +int jbd2_journal_set_features(journal_t *journal, unsigned long compat, |
|---|
| 1882 | 2151 | unsigned long ro, unsigned long incompat) |
|---|
| 1883 | 2152 | { |
|---|
| 1884 | 2153 | #define INCOMPAT_FEATURE_ON(f) \ |
|---|
| .. | .. |
|---|
| 1908 | 2177 | compat, ro, incompat); |
|---|
| 1909 | 2178 | |
|---|
| 1910 | 2179 | sb = journal->j_superblock; |
|---|
| 2180 | + |
|---|
| 2181 | + if (incompat & JBD2_FEATURE_INCOMPAT_FAST_COMMIT) { |
|---|
| 2182 | + if (jbd2_journal_initialize_fast_commit(journal)) { |
|---|
| 2183 | + pr_err("JBD2: Cannot enable fast commits.\n"); |
|---|
| 2184 | + return 0; |
|---|
| 2185 | + } |
|---|
| 2186 | + } |
|---|
| 1911 | 2187 | |
|---|
| 1912 | 2188 | /* Load the checksum driver if necessary */ |
|---|
| 1913 | 2189 | if ((journal->j_chksum_driver == NULL) && |
|---|
| .. | .. |
|---|
| 1942 | 2218 | sb->s_feature_ro_compat |= cpu_to_be32(ro); |
|---|
| 1943 | 2219 | sb->s_feature_incompat |= cpu_to_be32(incompat); |
|---|
| 1944 | 2220 | unlock_buffer(journal->j_sb_buffer); |
|---|
| 2221 | + journal->j_revoke_records_per_block = |
|---|
| 2222 | + journal_revoke_records_per_block(journal); |
|---|
| 1945 | 2223 | |
|---|
| 1946 | 2224 | return 1; |
|---|
| 1947 | 2225 | #undef COMPAT_FEATURE_ON |
|---|
| .. | .. |
|---|
| 1949 | 2227 | } |
|---|
| 1950 | 2228 | |
|---|
| 1951 | 2229 | /* |
|---|
| 1952 | | - * jbd2_journal_clear_features () - Clear a given journal feature in the |
|---|
| 2230 | + * jbd2_journal_clear_features() - Clear a given journal feature in the |
|---|
| 1953 | 2231 | * superblock |
|---|
| 1954 | 2232 | * @journal: Journal to act on. |
|---|
| 1955 | 2233 | * @compat: bitmask of compatible features |
|---|
| .. | .. |
|---|
| 1972 | 2250 | sb->s_feature_compat &= ~cpu_to_be32(compat); |
|---|
| 1973 | 2251 | sb->s_feature_ro_compat &= ~cpu_to_be32(ro); |
|---|
| 1974 | 2252 | sb->s_feature_incompat &= ~cpu_to_be32(incompat); |
|---|
| 2253 | + journal->j_revoke_records_per_block = |
|---|
| 2254 | + journal_revoke_records_per_block(journal); |
|---|
| 1975 | 2255 | } |
|---|
| 1976 | 2256 | EXPORT_SYMBOL(jbd2_journal_clear_features); |
|---|
| 1977 | 2257 | |
|---|
| 1978 | 2258 | /** |
|---|
| 1979 | | - * int jbd2_journal_flush () - Flush journal |
|---|
| 2259 | + * jbd2_journal_flush() - Flush journal |
|---|
| 1980 | 2260 | * @journal: Journal to act on. |
|---|
| 1981 | 2261 | * |
|---|
| 1982 | 2262 | * Flush all data for a given journal to disk and empty the journal. |
|---|
| .. | .. |
|---|
| 2051 | 2331 | } |
|---|
| 2052 | 2332 | |
|---|
| 2053 | 2333 | /** |
|---|
| 2054 | | - * int jbd2_journal_wipe() - Wipe journal contents |
|---|
| 2334 | + * jbd2_journal_wipe() - Wipe journal contents |
|---|
| 2055 | 2335 | * @journal: Journal to act on. |
|---|
| 2056 | 2336 | * @write: flag (see below) |
|---|
| 2057 | 2337 | * |
|---|
| .. | .. |
|---|
| 2082 | 2362 | err = jbd2_journal_skip_recovery(journal); |
|---|
| 2083 | 2363 | if (write) { |
|---|
| 2084 | 2364 | /* Lock to make assertions happy... */ |
|---|
| 2085 | | - mutex_lock(&journal->j_checkpoint_mutex); |
|---|
| 2365 | + mutex_lock_io(&journal->j_checkpoint_mutex); |
|---|
| 2086 | 2366 | jbd2_mark_journal_empty(journal, REQ_SYNC | REQ_FUA); |
|---|
| 2087 | 2367 | mutex_unlock(&journal->j_checkpoint_mutex); |
|---|
| 2088 | 2368 | } |
|---|
| .. | .. |
|---|
| 2091 | 2371 | return err; |
|---|
| 2092 | 2372 | } |
|---|
| 2093 | 2373 | |
|---|
| 2094 | | -/* |
|---|
| 2095 | | - * Journal abort has very specific semantics, which we describe |
|---|
| 2096 | | - * for journal abort. |
|---|
| 2097 | | - * |
|---|
| 2098 | | - * Two internal functions, which provide abort to the jbd layer |
|---|
| 2099 | | - * itself are here. |
|---|
| 2100 | | - */ |
|---|
| 2101 | | - |
|---|
| 2102 | | -/* |
|---|
| 2103 | | - * Quick version for internal journal use (doesn't lock the journal). |
|---|
| 2104 | | - * Aborts hard --- we mark the abort as occurred, but do _nothing_ else, |
|---|
| 2105 | | - * and don't attempt to make any other journal updates. |
|---|
| 2106 | | - */ |
|---|
| 2107 | | -void __jbd2_journal_abort_hard(journal_t *journal) |
|---|
| 2108 | | -{ |
|---|
| 2109 | | - transaction_t *transaction; |
|---|
| 2110 | | - |
|---|
| 2111 | | - if (journal->j_flags & JBD2_ABORT) |
|---|
| 2112 | | - return; |
|---|
| 2113 | | - |
|---|
| 2114 | | - printk(KERN_ERR "Aborting journal on device %s.\n", |
|---|
| 2115 | | - journal->j_devname); |
|---|
| 2116 | | - |
|---|
| 2117 | | - write_lock(&journal->j_state_lock); |
|---|
| 2118 | | - journal->j_flags |= JBD2_ABORT; |
|---|
| 2119 | | - transaction = journal->j_running_transaction; |
|---|
| 2120 | | - if (transaction) |
|---|
| 2121 | | - __jbd2_log_start_commit(journal, transaction->t_tid); |
|---|
| 2122 | | - write_unlock(&journal->j_state_lock); |
|---|
| 2123 | | -} |
|---|
| 2124 | | - |
|---|
| 2125 | | -/* Soft abort: record the abort error status in the journal superblock, |
|---|
| 2126 | | - * but don't do any other IO. */ |
|---|
| 2127 | | -static void __journal_abort_soft (journal_t *journal, int errno) |
|---|
| 2128 | | -{ |
|---|
| 2129 | | - int old_errno; |
|---|
| 2130 | | - |
|---|
| 2131 | | - write_lock(&journal->j_state_lock); |
|---|
| 2132 | | - old_errno = journal->j_errno; |
|---|
| 2133 | | - if (!journal->j_errno || errno == -ESHUTDOWN) |
|---|
| 2134 | | - journal->j_errno = errno; |
|---|
| 2135 | | - |
|---|
| 2136 | | - if (journal->j_flags & JBD2_ABORT) { |
|---|
| 2137 | | - write_unlock(&journal->j_state_lock); |
|---|
| 2138 | | - if (old_errno != -ESHUTDOWN && errno == -ESHUTDOWN) |
|---|
| 2139 | | - jbd2_journal_update_sb_errno(journal); |
|---|
| 2140 | | - return; |
|---|
| 2141 | | - } |
|---|
| 2142 | | - write_unlock(&journal->j_state_lock); |
|---|
| 2143 | | - |
|---|
| 2144 | | - __jbd2_journal_abort_hard(journal); |
|---|
| 2145 | | - |
|---|
| 2146 | | - jbd2_journal_update_sb_errno(journal); |
|---|
| 2147 | | - write_lock(&journal->j_state_lock); |
|---|
| 2148 | | - journal->j_flags |= JBD2_REC_ERR; |
|---|
| 2149 | | - write_unlock(&journal->j_state_lock); |
|---|
| 2150 | | -} |
|---|
| 2151 | | - |
|---|
| 2152 | 2374 | /** |
|---|
| 2153 | | - * void jbd2_journal_abort () - Shutdown the journal immediately. |
|---|
| 2375 | + * jbd2_journal_abort () - Shutdown the journal immediately. |
|---|
| 2154 | 2376 | * @journal: the journal to shutdown. |
|---|
| 2155 | 2377 | * @errno: an error number to record in the journal indicating |
|---|
| 2156 | 2378 | * the reason for the shutdown. |
|---|
| .. | .. |
|---|
| 2192 | 2414 | |
|---|
| 2193 | 2415 | void jbd2_journal_abort(journal_t *journal, int errno) |
|---|
| 2194 | 2416 | { |
|---|
| 2195 | | - __journal_abort_soft(journal, errno); |
|---|
| 2417 | + transaction_t *transaction; |
|---|
| 2418 | + |
|---|
| 2419 | + /* |
|---|
| 2420 | + * Lock the aborting procedure until everything is done, this avoid |
|---|
| 2421 | + * races between filesystem's error handling flow (e.g. ext4_abort()), |
|---|
| 2422 | + * ensure panic after the error info is written into journal's |
|---|
| 2423 | + * superblock. |
|---|
| 2424 | + */ |
|---|
| 2425 | + mutex_lock(&journal->j_abort_mutex); |
|---|
| 2426 | + /* |
|---|
| 2427 | + * ESHUTDOWN always takes precedence because a file system check |
|---|
| 2428 | + * caused by any other journal abort error is not required after |
|---|
| 2429 | + * a shutdown triggered. |
|---|
| 2430 | + */ |
|---|
| 2431 | + write_lock(&journal->j_state_lock); |
|---|
| 2432 | + if (journal->j_flags & JBD2_ABORT) { |
|---|
| 2433 | + int old_errno = journal->j_errno; |
|---|
| 2434 | + |
|---|
| 2435 | + write_unlock(&journal->j_state_lock); |
|---|
| 2436 | + if (old_errno != -ESHUTDOWN && errno == -ESHUTDOWN) { |
|---|
| 2437 | + journal->j_errno = errno; |
|---|
| 2438 | + jbd2_journal_update_sb_errno(journal); |
|---|
| 2439 | + } |
|---|
| 2440 | + mutex_unlock(&journal->j_abort_mutex); |
|---|
| 2441 | + return; |
|---|
| 2442 | + } |
|---|
| 2443 | + |
|---|
| 2444 | + /* |
|---|
| 2445 | + * Mark the abort as occurred and start current running transaction |
|---|
| 2446 | + * to release all journaled buffer. |
|---|
| 2447 | + */ |
|---|
| 2448 | + pr_err("Aborting journal on device %s.\n", journal->j_devname); |
|---|
| 2449 | + |
|---|
| 2450 | + journal->j_flags |= JBD2_ABORT; |
|---|
| 2451 | + journal->j_errno = errno; |
|---|
| 2452 | + transaction = journal->j_running_transaction; |
|---|
| 2453 | + if (transaction) |
|---|
| 2454 | + __jbd2_log_start_commit(journal, transaction->t_tid); |
|---|
| 2455 | + write_unlock(&journal->j_state_lock); |
|---|
| 2456 | + |
|---|
| 2457 | + /* |
|---|
| 2458 | + * Record errno to the journal super block, so that fsck and jbd2 |
|---|
| 2459 | + * layer could realise that a filesystem check is needed. |
|---|
| 2460 | + */ |
|---|
| 2461 | + jbd2_journal_update_sb_errno(journal); |
|---|
| 2462 | + mutex_unlock(&journal->j_abort_mutex); |
|---|
| 2196 | 2463 | } |
|---|
| 2197 | 2464 | |
|---|
| 2198 | 2465 | /** |
|---|
| 2199 | | - * int jbd2_journal_errno () - returns the journal's error state. |
|---|
| 2466 | + * jbd2_journal_errno() - returns the journal's error state. |
|---|
| 2200 | 2467 | * @journal: journal to examine. |
|---|
| 2201 | 2468 | * |
|---|
| 2202 | 2469 | * This is the errno number set with jbd2_journal_abort(), the last |
|---|
| .. | .. |
|---|
| 2220 | 2487 | } |
|---|
| 2221 | 2488 | |
|---|
| 2222 | 2489 | /** |
|---|
| 2223 | | - * int jbd2_journal_clear_err () - clears the journal's error state |
|---|
| 2490 | + * jbd2_journal_clear_err() - clears the journal's error state |
|---|
| 2224 | 2491 | * @journal: journal to act on. |
|---|
| 2225 | 2492 | * |
|---|
| 2226 | 2493 | * An error must be cleared or acked to take a FS out of readonly |
|---|
| .. | .. |
|---|
| 2240 | 2507 | } |
|---|
| 2241 | 2508 | |
|---|
| 2242 | 2509 | /** |
|---|
| 2243 | | - * void jbd2_journal_ack_err() - Ack journal err. |
|---|
| 2510 | + * jbd2_journal_ack_err() - Ack journal err. |
|---|
| 2244 | 2511 | * @journal: journal to act on. |
|---|
| 2245 | 2512 | * |
|---|
| 2246 | 2513 | * An error must be cleared or acked to take a FS out of readonly |
|---|
| .. | .. |
|---|
| 2428 | 2695 | ret = kmem_cache_zalloc(jbd2_journal_head_cache, |
|---|
| 2429 | 2696 | GFP_NOFS | __GFP_NOFAIL); |
|---|
| 2430 | 2697 | } |
|---|
| 2698 | + if (ret) |
|---|
| 2699 | + spin_lock_init(&ret->b_state_lock); |
|---|
| 2431 | 2700 | return ret; |
|---|
| 2432 | 2701 | } |
|---|
| 2433 | 2702 | |
|---|
| .. | .. |
|---|
| 2534 | 2803 | jbd_unlock_bh_journal_head(bh); |
|---|
| 2535 | 2804 | return jh; |
|---|
| 2536 | 2805 | } |
|---|
| 2806 | +EXPORT_SYMBOL(jbd2_journal_grab_journal_head); |
|---|
| 2537 | 2807 | |
|---|
| 2538 | 2808 | static void __journal_remove_journal_head(struct buffer_head *bh) |
|---|
| 2539 | 2809 | { |
|---|
| 2540 | 2810 | struct journal_head *jh = bh2jh(bh); |
|---|
| 2541 | 2811 | |
|---|
| 2542 | | - J_ASSERT_JH(jh, jh->b_jcount >= 0); |
|---|
| 2543 | 2812 | J_ASSERT_JH(jh, jh->b_transaction == NULL); |
|---|
| 2544 | 2813 | J_ASSERT_JH(jh, jh->b_next_transaction == NULL); |
|---|
| 2545 | 2814 | J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); |
|---|
| .. | .. |
|---|
| 2547 | 2816 | J_ASSERT_BH(bh, buffer_jbd(bh)); |
|---|
| 2548 | 2817 | J_ASSERT_BH(bh, jh2bh(jh) == bh); |
|---|
| 2549 | 2818 | BUFFER_TRACE(bh, "remove journal_head"); |
|---|
| 2550 | | - if (jh->b_frozen_data) { |
|---|
| 2551 | | - printk(KERN_WARNING "%s: freeing b_frozen_data\n", __func__); |
|---|
| 2552 | | - jbd2_free(jh->b_frozen_data, bh->b_size); |
|---|
| 2553 | | - } |
|---|
| 2554 | | - if (jh->b_committed_data) { |
|---|
| 2555 | | - printk(KERN_WARNING "%s: freeing b_committed_data\n", __func__); |
|---|
| 2556 | | - jbd2_free(jh->b_committed_data, bh->b_size); |
|---|
| 2557 | | - } |
|---|
| 2819 | + |
|---|
| 2820 | + /* Unlink before dropping the lock */ |
|---|
| 2558 | 2821 | bh->b_private = NULL; |
|---|
| 2559 | 2822 | jh->b_bh = NULL; /* debug, really */ |
|---|
| 2560 | 2823 | clear_buffer_jbd(bh); |
|---|
| 2824 | +} |
|---|
| 2825 | + |
|---|
| 2826 | +static void journal_release_journal_head(struct journal_head *jh, size_t b_size) |
|---|
| 2827 | +{ |
|---|
| 2828 | + if (jh->b_frozen_data) { |
|---|
| 2829 | + printk(KERN_WARNING "%s: freeing b_frozen_data\n", __func__); |
|---|
| 2830 | + jbd2_free(jh->b_frozen_data, b_size); |
|---|
| 2831 | + } |
|---|
| 2832 | + if (jh->b_committed_data) { |
|---|
| 2833 | + printk(KERN_WARNING "%s: freeing b_committed_data\n", __func__); |
|---|
| 2834 | + jbd2_free(jh->b_committed_data, b_size); |
|---|
| 2835 | + } |
|---|
| 2561 | 2836 | journal_free_journal_head(jh); |
|---|
| 2562 | 2837 | } |
|---|
| 2563 | 2838 | |
|---|
| .. | .. |
|---|
| 2575 | 2850 | if (!jh->b_jcount) { |
|---|
| 2576 | 2851 | __journal_remove_journal_head(bh); |
|---|
| 2577 | 2852 | jbd_unlock_bh_journal_head(bh); |
|---|
| 2853 | + journal_release_journal_head(jh, bh->b_size); |
|---|
| 2578 | 2854 | __brelse(bh); |
|---|
| 2579 | | - } else |
|---|
| 2855 | + } else { |
|---|
| 2580 | 2856 | jbd_unlock_bh_journal_head(bh); |
|---|
| 2857 | + } |
|---|
| 2581 | 2858 | } |
|---|
| 2859 | +EXPORT_SYMBOL(jbd2_journal_put_journal_head); |
|---|
| 2582 | 2860 | |
|---|
| 2583 | 2861 | /* |
|---|
| 2584 | 2862 | * Initialize jbd inode head |
|---|
| .. | .. |
|---|
| 2744 | 3022 | } |
|---|
| 2745 | 3023 | |
|---|
| 2746 | 3024 | MODULE_LICENSE("GPL"); |
|---|
| 3025 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 2747 | 3026 | module_init(journal_init); |
|---|
| 2748 | 3027 | module_exit(journal_exit); |
|---|
| 2749 | 3028 | |
|---|