Whamcloud - gitweb
Branch: HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / jbd-2.6.10-jcberr.patch
1 --- 1.46/include/linux/jbd.h    2004-10-19 03:40:17 -06:00
2 +++ 1.47/include/linux/jbd.h    2004-11-07 19:13:24 -07:00
3 @@ -352,6 +352,27 @@
4         bit_spin_unlock(BH_JournalHead, &bh->b_state);
5  }
6  
7 +#define HAVE_JOURNAL_CALLBACK_STATUS
8 +/**
9 + *   struct journal_callback - Base structure for callback information.
10 + *   @jcb_list: list information for other callbacks attached to the same handle.
11 + *   @jcb_func: Function to call with this callback structure. 
12 + *
13 + *   This struct is a 'seed' structure for a using with your own callback
14 + *   structs. If you are using callbacks you must allocate one of these
15 + *   or another struct of your own definition which has this struct 
16 + *   as it's first element and pass it to journal_callback_set().
17 + *
18 + *   This is used internally by jbd to maintain callback information.
19 + *
20 + *   See journal_callback_set for more information.
21 + **/
22 +struct journal_callback {
23 +       struct list_head jcb_list;              /* t_jcb_lock */
24 +       void (*jcb_func)(struct journal_callback *jcb, int error);
25 +       /* user data goes here */
26 +};
27 +
28  struct jbd_revoke_table_s;
29  
30  /**
31 @@ -360,6 +381,7 @@
32   * @h_transaction: Which compound transaction is this update a part of?
33   * @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
34   * @h_ref: Reference count on this handle
35 + * @h_jcb: List of application registered callbacks for this handle.
36   * @h_err: Field for caller's use to track errors through large fs operations
37   * @h_sync: flag for sync-on-close
38   * @h_jdata: flag to force data journaling
39 @@ -385,6 +407,13 @@
40         /* operations */
41         int                     h_err;
42  
43 +       /*
44 +        * List of application registered callbacks for this handle. The
45 +        * function(s) will be called after the transaction that this handle is
46 +        * part of has been committed to disk. [t_jcb_lock]
47 +        */
48 +       struct list_head        h_jcb;
49 +
50         /* Flags [no locking] */
51         unsigned int    h_sync:         1;      /* sync-on-close */
52         unsigned int    h_jdata:        1;      /* force data journaling */
53 @@ -426,6 +455,8 @@
54   *    j_state_lock
55   *    ->j_list_lock                    (journal_unmap_buffer)
56   *
57 + *    t_handle_lock
58 + *    ->t_jcb_lock
59   */
60  
61  struct transaction_s 
62 @@ -549,6 +580,15 @@
63          */
64         int t_handle_count;
65  
66 +       /*
67 +        * Protects the callback list
68 +        */
69 +       spinlock_t              t_jcb_lock;
70 +       /*
71 +        * List of registered callback functions for this transaction.
72 +        * Called when the transaction is committed. [t_jcb_lock]
73 +        */
74 +       struct list_head        t_jcb;
75  };
76  
77  /**
78 @@ -881,6 +921,10 @@
79  extern int      journal_try_to_free_buffers(journal_t *, struct page *, int);
80  extern int      journal_stop(handle_t *);
81  extern int      journal_flush (journal_t *);
82 +extern void     journal_callback_set(handle_t *handle,
83 +                                     void (*fn)(struct journal_callback *,int),
84 +                                     struct journal_callback *jcb);
85 +
86  extern void     journal_lock_updates (journal_t *);
87  extern void     journal_unlock_updates (journal_t *);
88  
89 --- 1.23/fs/jbd/checkpoint.c    2003-07-10 23:23:54 -06:00
90 +++ 1.24/fs/jbd/checkpoint.c    2004-11-07 19:13:24 -07:00
91 @@ -616,6 +616,7 @@
92         J_ASSERT(transaction->t_log_list == NULL);
93         J_ASSERT(transaction->t_checkpoint_list == NULL);
94         J_ASSERT(transaction->t_updates == 0);
95 +       J_ASSERT(list_empty(&transaction->t_jcb));
96         J_ASSERT(journal->j_committing_transaction != transaction);
97         J_ASSERT(journal->j_running_transaction != transaction);
98  
99
100 --- 1.53/fs/jbd/commit.c        2004-10-19 03:40:17 -06:00
101 +++ 1.54/fs/jbd/commit.c        2004-11-07 19:13:24 -07:00
102 @@ -686,6 +686,30 @@
103         if (err)
104                 __journal_abort_hard(journal);
105  
106 +       /*
107 +        * Call any callbacks that had been registered for handles in this
108 +        * transaction.  It is up to the callback to free any allocated
109 +        * memory.
110 +        *
111 +        * The spinlocking (t_jcb_lock) here is surely unnecessary...
112 +        */
113 +       spin_lock(&commit_transaction->t_jcb_lock);
114 +       if (!list_empty(&commit_transaction->t_jcb)) {
115 +               struct list_head *p, *n;
116 +               int error = is_journal_aborted(journal);
117 +
118 +               list_for_each_safe(p, n, &commit_transaction->t_jcb) {
119 +                       struct journal_callback *jcb;
120 +
121 +                       jcb = list_entry(p, struct journal_callback, jcb_list);
122 +                       list_del(p);
123 +                       spin_unlock(&commit_transaction->t_jcb_lock);
124 +                       jcb->jcb_func(jcb, error);
125 +                       spin_lock(&commit_transaction->t_jcb_lock);
126 +               }
127 +       }
128 +       spin_unlock(&commit_transaction->t_jcb_lock);
129 +
130         jbd_debug(3, "JBD: commit phase 7\n");
131  
132         J_ASSERT(commit_transaction->t_sync_datalist == NULL);
133
134 --- 1.77/fs/jbd/journal.c       2004-09-21 20:58:08 -06:00
135 +++ 1.78/fs/jbd/journal.c       2004-11-07 19:13:24 -07:00
136 @@ -55,6 +55,7 @@
137  #endif
138  EXPORT_SYMBOL(journal_flush);
139  EXPORT_SYMBOL(journal_revoke);
140 +EXPORT_SYMBOL(journal_callback_set);
141  
142  EXPORT_SYMBOL(journal_init_dev);
143  EXPORT_SYMBOL(journal_init_inode);
144 @@ -78,6 +79,7 @@
145  EXPORT_SYMBOL(journal_blocks_per_page);
146  EXPORT_SYMBOL(journal_invalidatepage);
147  EXPORT_SYMBOL(journal_try_to_free_buffers);
148 +EXPORT_SYMBOL(journal_bmap);
149  EXPORT_SYMBOL(journal_force_commit);
150  
151  static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
152
153 --- 1.89/fs/jbd/transaction.c   2004-10-19 03:40:17 -06:00
154 +++ 1.90/fs/jbd/transaction.c   2004-11-07 19:13:24 -07:00
155 @@ -50,7 +50,9 @@
156         transaction->t_state = T_RUNNING;
157         transaction->t_tid = journal->j_transaction_sequence++;
158         transaction->t_expires = jiffies + journal->j_commit_interval;
159 +       INIT_LIST_HEAD(&transaction->t_jcb);
160         spin_lock_init(&transaction->t_handle_lock);
161 +       spin_lock_init(&transaction->t_jcb_lock);
162  
163         /* Set up the commit timer for the new transaction. */
164         journal->j_commit_timer->expires = transaction->t_expires;
165 @@ -241,6 +243,7 @@
166         memset(handle, 0, sizeof(*handle));
167         handle->h_buffer_credits = nblocks;
168         handle->h_ref = 1;
169 +       INIT_LIST_HEAD(&handle->h_jcb);
170  
171         return handle;
172  }
173 @@ -1274,6 +1277,36 @@
174  }
175  
176  /**
177 + * void journal_callback_set() -  Register a callback function for this handle.
178 + * @handle: handle to attach the callback to.
179 + * @func: function to callback.
180 + * @jcb:  structure with additional information required by func() , and
181 + *        some space for jbd internal information.
182 + * 
183 + * The function will be
184 + * called when the transaction that this handle is part of has been
185 + * committed to disk with the original callback data struct and the
186 + * error status of the journal as parameters.  There is no guarantee of
187 + * ordering between handles within a single transaction, nor between
188 + * callbacks registered on the same handle.
189 + *
190 + * The caller is responsible for allocating the journal_callback struct.
191 + * This is to allow the caller to add as much extra data to the callback
192 + * as needed, but reduce the overhead of multiple allocations.  The caller
193 + * allocated struct must start with a struct journal_callback at offset 0,
194 + * and has the caller-specific data afterwards.
195 + */
196 +void journal_callback_set(handle_t *handle,
197 +                       void (*func)(struct journal_callback *jcb, int error),
198 +                       struct journal_callback *jcb)
199 +{
200 +       spin_lock(&handle->h_transaction->t_jcb_lock);
201 +       list_add_tail(&jcb->jcb_list, &handle->h_jcb);
202 +       spin_unlock(&handle->h_transaction->t_jcb_lock);
203 +       jcb->jcb_func = func;
204 +}
205 +
206 +/**
207   * int journal_stop() - complete a transaction
208   * @handle: tranaction to complete.
209   * 
210 @@ -1338,6 +1371,11 @@
211                 if (journal->j_barrier_count)
212                         wake_up(&journal->j_wait_transaction_locked);
213         }
214 +
215 +       /* Move callbacks from the handle to the transaction. */
216 +       spin_lock(&transaction->t_jcb_lock);
217 +       list_splice(&handle->h_jcb, &transaction->t_jcb);
218 +       spin_unlock(&transaction->t_jcb_lock);
219  
220         /*
221          * If the handle is marked SYNC, we need to set another commit
222