add patch fix-ocfs2-corrupt-when-updating-journal-superblock-fails
[ext4-patch-queue.git] / more-simplifications-in-do_get_write_access
blobf7754fe5562b563cd2e2fea6b6f8eab13f40fb11
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>
11 ---
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:
20         jh->b_modified = 0;
22         /*
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
25 +        * new data
26 +        */
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);
34 +               goto done;
35 +       }
36 +       /*
37          * If there is already a copy-out version of this buffer, then we don't
38          * need to make another one
39          */
40 @@ -903,84 +917,58 @@ repeat:
41                 goto done;
42         }
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);
54 +       /*
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
61 +        * here.
62 +        */
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);
67 +               goto repeat;
68 +       }
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");
81 +       /*
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).
87 +        *
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.
92 +        */
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);
100 -                       goto repeat;
101 -               }
103 -               /*
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).
110 -                *
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
115 -                * in that case.
116 -                */
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);
123 -                               frozen_buffer =
124 -                                       jbd2_alloc(jh2bh(jh)->b_size,
125 -                                                        GFP_NOFS);
126 -                               if (!frozen_buffer) {
127 -                                       printk(KERN_ERR
128 -                                              "%s: OOM for frozen_buffer\n",
129 -                                              __func__);
130 -                                       JBUFFER_TRACE(jh, "oom!");
131 -                                       error = -ENOMEM;
132 -                                       goto out;
133 -                               }
134 -                               goto repeat;
135 +                               printk(KERN_ERR "%s: OOM for frozen_buffer\n",
136 +                                      __func__);
137 +                               JBUFFER_TRACE(jh, "oom!");
138 +                               error = -ENOMEM;
139 +                               goto out;
140                         }
141 -                       jh->b_frozen_data = frozen_buffer;
142 -                       frozen_buffer = NULL;
143 -                       jbd2_freeze_jh_data(jh);
144 +                       goto repeat;
145                 }
146 -               jh->b_next_transaction = transaction;
147 -       }
150 -       /*
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
154 -        */
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);
165         }
166 +       jh->b_next_transaction = transaction;
168  done:
169         jbd_unlock_bh_state(bh);
170 -- 
171 2.1.4