Whamcloud - gitweb
file xnu_types.h was initially added on branch b_port_step.
[fs/lustre-release.git] / lustre / kernel_patches / patches / jbd-2.4.18-jcberr.patch
1 Index: linux-2.4.19.SuSE/include/linux/jbd.h
2 ===================================================================
3 --- linux-2.4.19.SuSE.orig/include/linux/jbd.h  Sun Nov 16 13:51:03 2003
4 +++ linux-2.4.19.SuSE/include/linux/jbd.h       Sun Nov 16 15:10:48 2003
5 @@ -283,6 +283,13 @@
6         return bh->b_private;
7  }
8  
9 +#define HAVE_JOURNAL_CALLBACK_STATUS
10 +struct journal_callback {
11 +       struct list_head jcb_list;
12 +       void (*jcb_func)(struct journal_callback *jcb, int error);
13 +       /* user data goes here */
14 +};
15 +
16  struct jbd_revoke_table_s;
17  
18  /* The handle_t type represents a single atomic update being performed
19 @@ -313,6 +320,12 @@
20            operations */
21         int                     h_err;
22  
23 +       /* List of application registered callbacks for this handle.
24 +        * The function(s) will be called after the transaction that
25 +        * this handle is part of has been committed to disk.
26 +        */
27 +       struct list_head        h_jcb;
28 +
29         /* Flags */
30         unsigned int    h_sync:         1;      /* sync-on-close */
31         unsigned int    h_jdata:        1;      /* force data journaling */
32 @@ -432,6 +445,10 @@
33  
34         /* How many handles used this transaction? */
35         int t_handle_count;
36 +
37 +       /* List of registered callback functions for this transaction.
38 +        * Called when the transaction is committed. */
39 +       struct list_head        t_jcb;
40  };
41  
42  
43 @@ -676,6 +693,9 @@
44  extern int      journal_try_to_free_buffers(journal_t *, struct page *, int);
45  extern int      journal_stop(handle_t *);
46  extern int      journal_flush (journal_t *);
47 +extern void     journal_callback_set(handle_t *handle,
48 +                                     void (*fn)(struct journal_callback *,int),
49 +                                     struct journal_callback *jcb);
50  
51  extern void     journal_lock_updates (journal_t *);
52  extern void     journal_unlock_updates (journal_t *);
53 Index: linux-2.4.19.SuSE/fs/jbd/checkpoint.c
54 ===================================================================
55 --- linux-2.4.19.SuSE.orig/fs/jbd/checkpoint.c  Mon Feb 25 11:38:08 2002
56 +++ linux-2.4.19.SuSE/fs/jbd/checkpoint.c       Sun Nov 16 15:10:48 2003
57 @@ -594,7 +594,8 @@
58         J_ASSERT (transaction->t_log_list == NULL);
59         J_ASSERT (transaction->t_checkpoint_list == NULL);
60         J_ASSERT (transaction->t_updates == 0);
61 -       
62 +       J_ASSERT (list_empty(&transaction->t_jcb));
63 +
64         J_ASSERT (transaction->t_journal->j_committing_transaction !=
65                                         transaction);
66         
67 Index: linux-2.4.19.SuSE/fs/jbd/commit.c
68 ===================================================================
69 --- linux-2.4.19.SuSE.orig/fs/jbd/commit.c      Mon Jan 27 05:08:04 2003
70 +++ linux-2.4.19.SuSE/fs/jbd/commit.c   Sun Nov 16 15:13:53 2003
71 @@ -485,7 +485,7 @@
72             transaction's t_log_list queue, and metadata buffers are on
73             the t_iobuf_list queue.
74  
75 -          Wait for the transactions in reverse order.  That way we are
76 +          Wait for the buffers in reverse order.  That way we are
77            less likely to be woken up until all IOs have completed, and
78            so we incur less scheduling load.
79         */
80 @@ -576,8 +576,10 @@
81  
82         jbd_debug(3, "JBD: commit phase 6\n");
83  
84 -       if (is_journal_aborted(journal))
85 +       if (is_journal_aborted(journal)) {
86 +               unlock_journal(journal);
87                 goto skip_commit;
88 +       }
89  
90         /* Done it all: now write the commit record.  We should have
91          * cleaned up our previous buffers by now, so if we are in abort
92 @@ -587,9 +589,10 @@
93         descriptor = journal_get_descriptor_buffer(journal);
94         if (!descriptor) {
95                 __journal_abort_hard(journal);
96 +               unlock_journal(journal);
97                 goto skip_commit;
98         }
99 -       
100 +
101         /* AKPM: buglet - add `i' to tmp! */
102         for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) {
103                 journal_header_t *tmp =
104 @@ -610,14 +614,32 @@
105                 put_bh(bh);             /* One for getblk() */
106                 journal_unlock_journal_head(descriptor);
107         }
108 -       lock_journal(journal);
109  
110         /* End of a transaction!  Finally, we can do checkpoint
111             processing: any buffers committed as a result of this
112             transaction can be removed from any checkpoint list it was on
113             before. */
114  
115 -skip_commit:
116 +skip_commit: /* The journal should be unlocked by now. */
117 +
118 +       /* Call any callbacks that had been registered for handles in this
119 +        * transaction.  It is up to the callback to free any allocated
120 +        * memory.
121 +        */
122 +       if (!list_empty(&commit_transaction->t_jcb)) {
123 +               struct list_head *p, *n;
124 +               int error = is_journal_aborted(journal);
125 +
126 +               list_for_each_safe(p, n, &commit_transaction->t_jcb) {
127 +                       struct journal_callback *jcb;
128 +
129 +                       jcb = list_entry(p, struct journal_callback, jcb_list);
130 +                       list_del(p);
131 +                       jcb->jcb_func(jcb, error);
132 +               }
133 +       }
134 +
135 +       lock_journal(journal);
136  
137         jbd_debug(3, "JBD: commit phase 7\n");
138  
139 Index: linux-2.4.19.SuSE/fs/jbd/journal.c
140 ===================================================================
141 --- linux-2.4.19.SuSE.orig/fs/jbd/journal.c     Mon Jan 27 05:08:00 2003
142 +++ linux-2.4.19.SuSE/fs/jbd/journal.c  Sun Nov 16 15:10:48 2003
143 @@ -59,6 +59,7 @@
144  #endif
145  EXPORT_SYMBOL(journal_flush);
146  EXPORT_SYMBOL(journal_revoke);
147 +EXPORT_SYMBOL(journal_callback_set);
148  
149  EXPORT_SYMBOL(journal_init_dev);
150  EXPORT_SYMBOL(journal_init_inode);
151 Index: linux-2.4.19.SuSE/fs/jbd/transaction.c
152 ===================================================================
153 --- linux-2.4.19.SuSE.orig/fs/jbd/transaction.c Sun Nov 16 01:45:26 2003
154 +++ linux-2.4.19.SuSE/fs/jbd/transaction.c      Sun Nov 16 15:15:34 2003
155 @@ -58,6 +58,7 @@
156         transaction->t_state = T_RUNNING;
157         transaction->t_tid = journal->j_transaction_sequence++;
158         transaction->t_expires = jiffies + bdflush_interval();
159 +       INIT_LIST_HEAD(&transaction->t_jcb);
160  
161         /* Set up the commit timer for the new transaction. */
162         J_ASSERT (!journal->j_commit_timer_active);
163 @@ -91,7 +92,14 @@
164         transaction_t *transaction;
165         int needed;
166         int nblocks = handle->h_buffer_credits;
167 -       
168 +
169 +       if (nblocks > journal->j_max_transaction_buffers) {
170 +               jbd_debug(1, "JBD: %s wants too many credits (%d > %d)\n",
171 +                         current->comm, nblocks,
172 +                         journal->j_max_transaction_buffers);
173 +               return -ENOSPC;
174 +       }
175 +
176         jbd_debug(3, "New handle %p going live.\n", handle);
177  
178  repeat:
179 @@ -202,6 +210,20 @@
180         return 0;
181  }
182  
183 +/* Allocate a new handle.  This should probably be in a slab... */
184 +static handle_t *new_handle(int nblocks)
185 +{
186 +       handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
187 +       if (!handle)
188 +               return NULL;
189 +       memset(handle, 0, sizeof (handle_t));
190 +       handle->h_buffer_credits = nblocks;
191 +       handle->h_ref = 1;
192 +       INIT_LIST_HEAD(&handle->h_jcb);
193 +
194 +       return handle;
195 +}
196 +
197  /*
198   * Obtain a new handle.  
199   *
200 @@ -228,14 +250,11 @@
201                 handle->h_ref++;
202                 return handle;
203         }
204 -       
205 -       handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
206 +
207 +       handle = new_handle(nblocks);
208         if (!handle)
209                 return ERR_PTR(-ENOMEM);
210 -       memset (handle, 0, sizeof (handle_t));
211  
212 -       handle->h_buffer_credits = nblocks;
213 -       handle->h_ref = 1;
214         current->journal_info = handle;
215  
216         err = start_this_handle(journal, handle);
217 @@ -334,14 +353,11 @@
218         
219         if (is_journal_aborted(journal))
220                 return ERR_PTR(-EIO);
221 -       
222 -       handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
223 +
224 +       handle = new_handle(nblocks);
225         if (!handle)
226                 return ERR_PTR(-ENOMEM);
227 -       memset (handle, 0, sizeof (handle_t));
228  
229 -       handle->h_buffer_credits = nblocks;
230 -       handle->h_ref = 1;
231         current->journal_info = handle;
232  
233         err = try_start_this_handle(journal, handle);
234 @@ -1321,6 +1337,28 @@
235  #endif
236  
237  /*
238 + * Register a callback function for this handle.  The function will be
239 + * called when the transaction that this handle is part of has been
240 + * committed to disk with the original callback data struct and the
241 + * error status of the journal as parameters.  There is no guarantee of
242 + * ordering between handles within a single transaction, nor between
243 + * callbacks registered on the same handle.
244 + *
245 + * The caller is responsible for allocating the journal_callback struct.
246 + * This is to allow the caller to add as much extra data to the callback
247 + * as needed, but reduce the overhead of multiple allocations.  The caller
248 + * allocated struct must start with a struct journal_callback at offset 0,
249 + * and has the caller-specific data afterwards.
250 + */
251 +void journal_callback_set(handle_t *handle,
252 +                         void (*func)(struct journal_callback *jcb, int error),
253 +                         struct journal_callback *jcb)
254 +{
255 +       list_add_tail(&jcb->jcb_list, &handle->h_jcb);
256 +       jcb->jcb_func = func;
257 +}
258 +
259 +/*
260   * All done for a particular handle.
261   *
262   * There is not much action needed here.  We just return any remaining
263 @@ -1385,7 +1423,10 @@
264                         wake_up(&journal->j_wait_transaction_locked);
265         }
266  
267 -       /* 
268 +       /* Move callbacks from the handle to the transaction. */
269 +       list_splice(&handle->h_jcb, &transaction->t_jcb);
270 +
271 +       /*
272          * If the handle is marked SYNC, we need to set another commit
273          * going!  We also want to force a commit if the current
274          * transaction is occupying too much of the log, or if the