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
4 bit_spin_unlock(BH_JournalHead, &bh->b_state);
7 +#define HAVE_JOURNAL_CALLBACK_STATUS
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.
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().
18 + * This is used internally by jbd to maintain callback information.
20 + * See journal_callback_set for more information.
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 */
28 struct jbd_revoke_table_s;
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
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]
48 + struct list_head h_jcb;
50 /* Flags [no locking] */
51 unsigned int h_sync: 1; /* sync-on-close */
52 unsigned int h_jdata: 1; /* force data journaling */
55 * ->j_list_lock (journal_unmap_buffer)
67 + * Protects the callback list
69 + spinlock_t t_jcb_lock;
71 + * List of registered callback functions for this transaction.
72 + * Called when the transaction is committed. [t_jcb_lock]
74 + struct list_head t_jcb;
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);
86 extern void journal_lock_updates (journal_t *);
87 extern void journal_unlock_updates (journal_t *);
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
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);
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
104 __journal_abort_hard(journal);
107 + * Call any callbacks that had been registered for handles in this
108 + * transaction. It is up to the callback to free any allocated
111 + * The spinlocking (t_jcb_lock) here is surely unnecessary...
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);
118 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
119 + struct journal_callback *jcb;
121 + jcb = list_entry(p, struct journal_callback, jcb_list);
123 + spin_unlock(&commit_transaction->t_jcb_lock);
124 + jcb->jcb_func(jcb, error);
125 + spin_lock(&commit_transaction->t_jcb_lock);
128 + spin_unlock(&commit_transaction->t_jcb_lock);
130 jbd_debug(3, "JBD: commit phase 7\n");
132 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
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
138 EXPORT_SYMBOL(journal_flush);
139 EXPORT_SYMBOL(journal_revoke);
140 +EXPORT_SYMBOL(journal_callback_set);
142 EXPORT_SYMBOL(journal_init_dev);
143 EXPORT_SYMBOL(journal_init_inode);
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);
151 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
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
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);
163 /* Set up the commit timer for the new transaction. */
164 journal->j_commit_timer->expires = transaction->t_expires;
166 memset(handle, 0, sizeof(*handle));
167 handle->h_buffer_credits = nblocks;
169 + INIT_LIST_HEAD(&handle->h_jcb);
173 @@ -1274,6 +1277,36 @@
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.
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.
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.
196 +void journal_callback_set(handle_t *handle,
197 + void (*func)(struct journal_callback *jcb, int error),
198 + struct journal_callback *jcb)
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;
207 * int journal_stop() - complete a transaction
208 * @handle: tranaction to complete.
210 @@ -1338,6 +1371,11 @@
211 if (journal->j_barrier_count)
212 wake_up(&journal->j_wait_transaction_locked);
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);
221 * If the handle is marked SYNC, we need to set another commit