1 jbd2: more simplifications in do_get_write_access()
3 From: Jan Kara <jack@suse.cz>
5 Check for the simple case of unjournaled buffer first, handle it and
6 bail out. This allows us to remove one if and unindent the difficult case
7 by one tab. The result is easier to read.
9 Signed-off-by: Jan Kara <jack@suse.cz>
10 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
12 fs/jbd2/transaction.c | 130 +++++++++++++++++++++++---------------------------
13 1 file changed, 59 insertions(+), 71 deletions(-)
15 diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
16 index 1995ea539e96..5207825d1038 100644
17 --- a/fs/jbd2/transaction.c
18 +++ b/fs/jbd2/transaction.c
19 @@ -893,6 +893,20 @@ repeat:
23 + * If the buffer is not journaled right now, we need to make sure it
24 + * doesn't get written to disk before the caller actually commits the
27 + if (!jh->b_transaction) {
28 + JBUFFER_TRACE(jh, "no transaction");
29 + J_ASSERT_JH(jh, !jh->b_next_transaction);
30 + JBUFFER_TRACE(jh, "file as BJ_Reserved");
31 + spin_lock(&journal->j_list_lock);
32 + __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
33 + spin_unlock(&journal->j_list_lock);
37 * If there is already a copy-out version of this buffer, then we don't
38 * need to make another one
40 @@ -903,84 +917,58 @@ repeat:
44 - /* Is there data here we need to preserve? */
45 + JBUFFER_TRACE(jh, "owned by older transaction");
46 + J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
47 + J_ASSERT_JH(jh, jh->b_transaction == journal->j_committing_transaction);
49 - if (jh->b_transaction && jh->b_transaction != transaction) {
50 - JBUFFER_TRACE(jh, "owned by older transaction");
51 - J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
52 - J_ASSERT_JH(jh, jh->b_transaction ==
53 - journal->j_committing_transaction);
55 + * There is one case we have to be very careful about. If the
56 + * committing transaction is currently writing this buffer out to disk
57 + * and has NOT made a copy-out, then we cannot modify the buffer
58 + * contents at all right now. The essence of copy-out is that it is
59 + * the extra copy, not the primary copy, which gets journaled. If the
60 + * primary copy is already going to disk then we cannot do copy-out
63 + if (buffer_shadow(bh)) {
64 + JBUFFER_TRACE(jh, "on shadow: sleep");
65 + jbd_unlock_bh_state(bh);
66 + wait_on_bit_io(&bh->b_state, BH_Shadow, TASK_UNINTERRUPTIBLE);
70 - /* There is one case we have to be very careful about.
71 - * If the committing transaction is currently writing
72 - * this buffer out to disk and has NOT made a copy-out,
73 - * then we cannot modify the buffer contents at all
74 - * right now. The essence of copy-out is that it is the
75 - * extra copy, not the primary copy, which gets
76 - * journaled. If the primary copy is already going to
77 - * disk then we cannot do copy-out here. */
79 - if (buffer_shadow(bh)) {
80 - JBUFFER_TRACE(jh, "on shadow: sleep");
82 + * Only do the copy if the currently-owning transaction still needs it.
83 + * If buffer isn't on BJ_Metadata list, the committing transaction is
84 + * past that stage (here we use the fact that BH_Shadow is set under
85 + * bh_state lock together with refiling to BJ_Shadow list and at this
86 + * point we know the buffer doesn't have BH_Shadow set).
88 + * Subtle point, though: if this is a get_undo_access, then we will be
89 + * relying on the frozen_data to contain the new value of the
90 + * committed_data record after the transaction, so we HAVE to force the
91 + * frozen_data copy in that case.
93 + if (jh->b_jlist == BJ_Metadata || force_copy) {
94 + JBUFFER_TRACE(jh, "generate frozen data");
95 + if (!frozen_buffer) {
96 + JBUFFER_TRACE(jh, "allocate memory for buffer");
97 jbd_unlock_bh_state(bh);
98 - wait_on_bit_io(&bh->b_state, BH_Shadow,
99 - TASK_UNINTERRUPTIBLE);
104 - * Only do the copy if the currently-owning transaction still
105 - * needs it. If buffer isn't on BJ_Metadata list, the
106 - * committing transaction is past that stage (here we use the
107 - * fact that BH_Shadow is set under bh_state lock together with
108 - * refiling to BJ_Shadow list and at this point we know the
109 - * buffer doesn't have BH_Shadow set).
111 - * Subtle point, though: if this is a get_undo_access,
112 - * then we will be relying on the frozen_data to contain
113 - * the new value of the committed_data record after the
114 - * transaction, so we HAVE to force the frozen_data copy
117 - if (jh->b_jlist == BJ_Metadata || force_copy) {
118 - JBUFFER_TRACE(jh, "generate frozen data");
119 + frozen_buffer = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS);
120 if (!frozen_buffer) {
121 - JBUFFER_TRACE(jh, "allocate memory for buffer");
122 - jbd_unlock_bh_state(bh);
124 - jbd2_alloc(jh2bh(jh)->b_size,
126 - if (!frozen_buffer) {
128 - "%s: OOM for frozen_buffer\n",
130 - JBUFFER_TRACE(jh, "oom!");
135 + printk(KERN_ERR "%s: OOM for frozen_buffer\n",
137 + JBUFFER_TRACE(jh, "oom!");
141 - jh->b_frozen_data = frozen_buffer;
142 - frozen_buffer = NULL;
143 - jbd2_freeze_jh_data(jh);
146 - jh->b_next_transaction = transaction;
151 - * Finally, if the buffer is not journaled right now, we need to make
152 - * sure it doesn't get written to disk before the caller actually
153 - * commits the new data
155 - if (!jh->b_transaction) {
156 - JBUFFER_TRACE(jh, "no transaction");
157 - J_ASSERT_JH(jh, !jh->b_next_transaction);
158 - JBUFFER_TRACE(jh, "file as BJ_Reserved");
159 - spin_lock(&journal->j_list_lock);
160 - __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
161 - spin_unlock(&journal->j_list_lock);
162 + jh->b_frozen_data = frozen_buffer;
163 + frozen_buffer = NULL;
164 + jbd2_freeze_jh_data(jh);
166 + jh->b_next_transaction = transaction;
169 jbd_unlock_bh_state(bh);