.. | .. |
---|
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 | |
---|