Whamcloud - gitweb
Merge b_md into HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / jbd-transno-cb.patch
1
2
3
4  fs/jbd/commit.c      |   27 +++++++++++++++++++++---
5  fs/jbd/journal.c     |    1 
6  fs/jbd/transaction.c |   56 ++++++++++++++++++++++++++++++++++++++++-----------
7  include/linux/jbd.h  |   20 ++++++++++++++++++
8  4 files changed, 90 insertions(+), 14 deletions(-)
9
10 --- linux-2.4.19/fs/jbd/commit.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003
11 +++ linux-2.4.19-root/fs/jbd/commit.c   Sun Jan 19 19:46:42 2003
12 @@ -475,7 +475,7 @@ start_journal_io:
13             transaction's t_log_list queue, and metadata buffers are on
14             the t_iobuf_list queue.
15  
16 -          Wait for the transactions in reverse order.  That way we are
17 +          Wait for the buffers in reverse order.  That way we are
18            less likely to be woken up until all IOs have completed, and
19            so we incur less scheduling load.
20         */
21 @@ -566,8 +566,10 @@ start_journal_io:
22  
23         jbd_debug(3, "JBD: commit phase 6\n");
24  
25 -       if (is_journal_aborted(journal))
26 +       if (is_journal_aborted(journal)) {
27 +               unlock_journal(journal);
28                 goto skip_commit;
29 +       }
30  
31         /* Done it all: now write the commit record.  We should have
32          * cleaned up our previous buffers by now, so if we are in abort
33 @@ -577,6 +579,7 @@ start_journal_io:
34         descriptor = journal_get_descriptor_buffer(journal);
35         if (!descriptor) {
36                 __journal_abort_hard(journal);
37 +               unlock_journal(journal);
38                 goto skip_commit;
39         }
40         
41 @@ -600,7 +603,6 @@ start_journal_io:
42                 put_bh(bh);             /* One for getblk() */
43                 journal_unlock_journal_head(descriptor);
44         }
45 -       lock_journal(journal);
46  
47         /* End of a transaction!  Finally, we can do checkpoint
48             processing: any buffers committed as a result of this
49 @@ -609,6 +611,25 @@ start_journal_io:
50  
51  skip_commit:
52  
53 +       /* Call any callbacks that had been registered for handles in this
54 +        * transaction.  It is up to the callback to free any allocated
55 +        * memory.
56 +        */
57 +       if (!list_empty(&commit_transaction->t_jcb)) {
58 +               struct list_head *p, *n;
59 +               int error = is_journal_aborted(journal);
60 +
61 +               list_for_each_safe(p, n, &commit_transaction->t_jcb) {
62 +                       struct journal_callback *jcb;
63 +
64 +                       jcb = list_entry(p, struct journal_callback, jcb_list);
65 +                       list_del(p);
66 +                       jcb->jcb_func(jcb, error);
67 +               }
68 +       }
69 +
70 +       lock_journal(journal);
71 +
72         jbd_debug(3, "JBD: commit phase 7\n");
73  
74         J_ASSERT(commit_transaction->t_sync_datalist == NULL);
75 --- linux-2.4.19/fs/jbd/journal.c~vanilla-2.4.19        Sun Jan 19 19:46:42 2003
76 +++ linux-2.4.19-root/fs/jbd/journal.c  Sun Jan 19 19:46:42 2003
77 @@ -58,6 +58,7 @@ EXPORT_SYMBOL(journal_sync_buffer);
78  #endif
79  EXPORT_SYMBOL(journal_flush);
80  EXPORT_SYMBOL(journal_revoke);
81 +EXPORT_SYMBOL(journal_callback_set);
82  
83  EXPORT_SYMBOL(journal_init_dev);
84  EXPORT_SYMBOL(journal_init_inode);
85 --- linux-2.4.19/fs/jbd/transaction.c~vanilla-2.4.19    Sun Jan 19 19:46:42 2003
86 +++ linux-2.4.19-root/fs/jbd/transaction.c      Sun Jan 19 19:46:42 2003
87 @@ -57,6 +57,7 @@ static transaction_t * get_transaction (
88         transaction->t_state = T_RUNNING;
89         transaction->t_tid = journal->j_transaction_sequence++;
90         transaction->t_expires = jiffies + journal->j_commit_interval;
91 +       INIT_LIST_HEAD(&transaction->t_jcb);
92  
93         /* Set up the commit timer for the new transaction. */
94         J_ASSERT (!journal->j_commit_timer_active);
95 @@ -201,6 +202,20 @@ repeat_locked:
96         return 0;
97  }
98  
99 +/* Allocate a new handle.  This should probably be in a slab... */
100 +static handle_t *new_handle(int nblocks)
101 +{
102 +       handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
103 +       if (!handle)
104 +               return NULL;
105 +       memset(handle, 0, sizeof (handle_t));
106 +       handle->h_buffer_credits = nblocks;
107 +       handle->h_ref = 1;
108 +       INIT_LIST_HEAD(&handle->h_jcb);
109 +
110 +       return handle;
111 +}
112 +
113  /*
114   * Obtain a new handle.  
115   *
116 @@ -227,14 +242,11 @@ handle_t *journal_start(journal_t *journ
117                 handle->h_ref++;
118                 return handle;
119         }
120 -       
121 -       handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
122 +
123 +       handle = new_handle(nblocks);
124         if (!handle)
125                 return ERR_PTR(-ENOMEM);
126 -       memset (handle, 0, sizeof (handle_t));
127  
128 -       handle->h_buffer_credits = nblocks;
129 -       handle->h_ref = 1;
130         current->journal_info = handle;
131  
132         err = start_this_handle(journal, handle);
133 @@ -333,14 +345,11 @@ handle_t *journal_try_start(journal_t *j
134         
135         if (is_journal_aborted(journal))
136                 return ERR_PTR(-EIO);
137 -       
138 -       handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
139 +
140 +       handle = new_handle(nblocks);
141         if (!handle)
142                 return ERR_PTR(-ENOMEM);
143 -       memset (handle, 0, sizeof (handle_t));
144  
145 -       handle->h_buffer_credits = nblocks;
146 -       handle->h_ref = 1;
147         current->journal_info = handle;
148  
149         err = try_start_this_handle(journal, handle);
150 @@ -1328,6 +1337,28 @@ out:
151  #endif
152  
153  /*
154 + * Register a callback function for this handle.  The function will be
155 + * called when the transaction that this handle is part of has been
156 + * committed to disk with the original callback data struct and the
157 + * error status of the journal as parameters.  There is no guarantee of
158 + * ordering between handles within a single transaction, nor between
159 + * callbacks registered on the same handle.
160 + *
161 + * The caller is responsible for allocating the journal_callback struct.
162 + * This is to allow the caller to add as much extra data to the callback
163 + * as needed, but reduce the overhead of multiple allocations.  The caller
164 + * allocated struct must start with a struct journal_callback at offset 0,
165 + * and has the caller-specific data afterwards.
166 + */
167 +void journal_callback_set(handle_t *handle,
168 +                         void (*func)(struct journal_callback *jcb, int error),
169 +                         struct journal_callback *jcb)
170 +{
171 +       list_add(&jcb->jcb_list, &handle->h_jcb);
172 +       jcb->jcb_func = func;
173 +}
174 +
175 +/*
176   * All done for a particular handle.
177   *
178   * There is not much action needed here.  We just return any remaining
179 @@ -1393,7 +1424,10 @@ int journal_stop(handle_t *handle)
180                         wake_up(&journal->j_wait_transaction_locked);
181         }
182  
183 -       /* 
184 +       /* Move callbacks from the handle to the transaction. */
185 +       list_splice(&handle->h_jcb, &transaction->t_jcb);
186 +
187 +       /*
188          * If the handle is marked SYNC, we need to set another commit
189          * going!  We also want to force a commit if the current
190          * transaction is occupying too much of the log, or if the
191 --- linux-2.4.19/include/linux/jbd.h~vanilla-2.4.19     Sun Jan 19 19:46:42 2003
192 +++ linux-2.4.19-root/include/linux/jbd.h       Sun Jan 19 19:46:42 2003
193 @@ -249,6 +249,13 @@ static inline struct journal_head *bh2jh
194         return bh->b_private;
195  }
196  
197 +#define HAVE_JOURNAL_CALLBACK_STATUS
198 +struct journal_callback {
199 +       struct list_head jcb_list;
200 +       void (*jcb_func)(struct journal_callback *jcb, int error);
201 +       /* user data goes here */
202 +};
203 +
204  struct jbd_revoke_table_s;
205  
206  /* The handle_t type represents a single atomic update being performed
207 @@ -279,6 +286,12 @@ struct handle_s 
208            operations */
209         int                     h_err;
210  
211 +       /* List of application registered callbacks for this handle.
212 +        * The function(s) will be called after the transaction that
213 +        * this handle is part of has been committed to disk.
214 +        */
215 +       struct list_head        h_jcb;
216 +
217         /* Flags */
218         unsigned int    h_sync:         1;      /* sync-on-close */
219         unsigned int    h_jdata:        1;      /* force data journaling */
220 @@ -398,6 +411,10 @@ struct transaction_s 
221  
222         /* How many handles used this transaction? */
223         int t_handle_count;
224 +
225 +       /* List of registered callback functions for this transaction.
226 +        * Called when the transaction is committed. */
227 +       struct list_head        t_jcb;
228  };
229  
230  
231 @@ -646,6 +663,9 @@ extern int   journal_flushpage(journal_t 
232  extern int      journal_try_to_free_buffers(journal_t *, struct page *, int);
233  extern int      journal_stop(handle_t *);
234  extern int      journal_flush (journal_t *);
235 +extern void     journal_callback_set(handle_t *handle,
236 +                                     void (*fn)(struct journal_callback *,int),
237 +                                     struct journal_callback *jcb);
238  
239  extern void     journal_lock_updates (journal_t *);
240  extern void     journal_unlock_updates (journal_t *);