diff options
-rw-r--r-- | fs/jbd2/transaction.c | 130 |
1 files changed, 59 insertions, 71 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 3b2e617baab6..1bbcf86499c9 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -884,6 +884,20 @@ repeat: | |||
884 | jh->b_modified = 0; | 884 | jh->b_modified = 0; |
885 | 885 | ||
886 | /* | 886 | /* |
887 | * If the buffer is not journaled right now, we need to make sure it | ||
888 | * doesn't get written to disk before the caller actually commits the | ||
889 | * new data | ||
890 | */ | ||
891 | if (!jh->b_transaction) { | ||
892 | JBUFFER_TRACE(jh, "no transaction"); | ||
893 | J_ASSERT_JH(jh, !jh->b_next_transaction); | ||
894 | JBUFFER_TRACE(jh, "file as BJ_Reserved"); | ||
895 | spin_lock(&journal->j_list_lock); | ||
896 | __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); | ||
897 | spin_unlock(&journal->j_list_lock); | ||
898 | goto done; | ||
899 | } | ||
900 | /* | ||
887 | * If there is already a copy-out version of this buffer, then we don't | 901 | * If there is already a copy-out version of this buffer, then we don't |
888 | * need to make another one | 902 | * need to make another one |
889 | */ | 903 | */ |
@@ -894,84 +908,58 @@ repeat: | |||
894 | goto done; | 908 | goto done; |
895 | } | 909 | } |
896 | 910 | ||
897 | /* Is there data here we need to preserve? */ | 911 | JBUFFER_TRACE(jh, "owned by older transaction"); |
912 | J_ASSERT_JH(jh, jh->b_next_transaction == NULL); | ||
913 | J_ASSERT_JH(jh, jh->b_transaction == journal->j_committing_transaction); | ||
898 | 914 | ||
899 | if (jh->b_transaction && jh->b_transaction != transaction) { | 915 | /* |
900 | JBUFFER_TRACE(jh, "owned by older transaction"); | 916 | * There is one case we have to be very careful about. If the |
901 | J_ASSERT_JH(jh, jh->b_next_transaction == NULL); | 917 | * committing transaction is currently writing this buffer out to disk |
902 | J_ASSERT_JH(jh, jh->b_transaction == | 918 | * and has NOT made a copy-out, then we cannot modify the buffer |
903 | journal->j_committing_transaction); | 919 | * contents at all right now. The essence of copy-out is that it is |
920 | * the extra copy, not the primary copy, which gets journaled. If the | ||
921 | * primary copy is already going to disk then we cannot do copy-out | ||
922 | * here. | ||
923 | */ | ||
924 | if (buffer_shadow(bh)) { | ||
925 | JBUFFER_TRACE(jh, "on shadow: sleep"); | ||
926 | jbd_unlock_bh_state(bh); | ||
927 | wait_on_bit_io(&bh->b_state, BH_Shadow, TASK_UNINTERRUPTIBLE); | ||
928 | goto repeat; | ||
929 | } | ||
904 | 930 | ||
905 | /* There is one case we have to be very careful about. | 931 | /* |
906 | * If the committing transaction is currently writing | 932 | * Only do the copy if the currently-owning transaction still needs it. |
907 | * this buffer out to disk and has NOT made a copy-out, | 933 | * If buffer isn't on BJ_Metadata list, the committing transaction is |
908 | * then we cannot modify the buffer contents at all | 934 | * past that stage (here we use the fact that BH_Shadow is set under |
909 | * right now. The essence of copy-out is that it is the | 935 | * bh_state lock together with refiling to BJ_Shadow list and at this |
910 | * extra copy, not the primary copy, which gets | 936 | * point we know the buffer doesn't have BH_Shadow set). |
911 | * journaled. If the primary copy is already going to | 937 | * |
912 | * disk then we cannot do copy-out here. */ | 938 | * Subtle point, though: if this is a get_undo_access, then we will be |
913 | 939 | * relying on the frozen_data to contain the new value of the | |
914 | if (buffer_shadow(bh)) { | 940 | * committed_data record after the transaction, so we HAVE to force the |
915 | JBUFFER_TRACE(jh, "on shadow: sleep"); | 941 | * frozen_data copy in that case. |
942 | */ | ||
943 | if (jh->b_jlist == BJ_Metadata || force_copy) { | ||
944 | JBUFFER_TRACE(jh, "generate frozen data"); | ||
945 | if (!frozen_buffer) { | ||
946 | JBUFFER_TRACE(jh, "allocate memory for buffer"); | ||
916 | jbd_unlock_bh_state(bh); | 947 | jbd_unlock_bh_state(bh); |
917 | wait_on_bit_io(&bh->b_state, BH_Shadow, | 948 | frozen_buffer = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS); |
918 | TASK_UNINTERRUPTIBLE); | ||
919 | goto repeat; | ||
920 | } | ||
921 | |||
922 | /* | ||
923 | * Only do the copy if the currently-owning transaction still | ||
924 | * needs it. If buffer isn't on BJ_Metadata list, the | ||
925 | * committing transaction is past that stage (here we use the | ||
926 | * fact that BH_Shadow is set under bh_state lock together with | ||
927 | * refiling to BJ_Shadow list and at this point we know the | ||
928 | * buffer doesn't have BH_Shadow set). | ||
929 | * | ||
930 | * Subtle point, though: if this is a get_undo_access, | ||
931 | * then we will be relying on the frozen_data to contain | ||
932 | * the new value of the committed_data record after the | ||
933 | * transaction, so we HAVE to force the frozen_data copy | ||
934 | * in that case. | ||
935 | */ | ||
936 | if (jh->b_jlist == BJ_Metadata || force_copy) { | ||
937 | JBUFFER_TRACE(jh, "generate frozen data"); | ||
938 | if (!frozen_buffer) { | 949 | if (!frozen_buffer) { |
939 | JBUFFER_TRACE(jh, "allocate memory for buffer"); | 950 | printk(KERN_ERR "%s: OOM for frozen_buffer\n", |
940 | jbd_unlock_bh_state(bh); | 951 | __func__); |
941 | frozen_buffer = | 952 | JBUFFER_TRACE(jh, "oom!"); |
942 | jbd2_alloc(jh2bh(jh)->b_size, | 953 | error = -ENOMEM; |
943 | GFP_NOFS); | 954 | goto out; |
944 | if (!frozen_buffer) { | ||
945 | printk(KERN_ERR | ||
946 | "%s: OOM for frozen_buffer\n", | ||
947 | __func__); | ||
948 | JBUFFER_TRACE(jh, "oom!"); | ||
949 | error = -ENOMEM; | ||
950 | goto out; | ||
951 | } | ||
952 | goto repeat; | ||
953 | } | 955 | } |
954 | jh->b_frozen_data = frozen_buffer; | 956 | goto repeat; |
955 | frozen_buffer = NULL; | ||
956 | jbd2_freeze_jh_data(jh); | ||
957 | } | 957 | } |
958 | jh->b_next_transaction = transaction; | 958 | jh->b_frozen_data = frozen_buffer; |
959 | } | 959 | frozen_buffer = NULL; |
960 | 960 | jbd2_freeze_jh_data(jh); | |
961 | |||
962 | /* | ||
963 | * Finally, if the buffer is not journaled right now, we need to make | ||
964 | * sure it doesn't get written to disk before the caller actually | ||
965 | * commits the new data | ||
966 | */ | ||
967 | if (!jh->b_transaction) { | ||
968 | JBUFFER_TRACE(jh, "no transaction"); | ||
969 | J_ASSERT_JH(jh, !jh->b_next_transaction); | ||
970 | JBUFFER_TRACE(jh, "file as BJ_Reserved"); | ||
971 | spin_lock(&journal->j_list_lock); | ||
972 | __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); | ||
973 | spin_unlock(&journal->j_list_lock); | ||
974 | } | 961 | } |
962 | jh->b_next_transaction = transaction; | ||
975 | 963 | ||
976 | done: | 964 | done: |
977 | jbd_unlock_bh_state(bh); | 965 | jbd_unlock_bh_state(bh); |