📄 jbd-2.6.10-jcberr.patch
字号:
--- 1.46/include/linux/jbd.h 2004-10-19 03:40:17 -06:00+++ 1.47/include/linux/jbd.h 2004-11-07 19:13:24 -07:00@@ -352,6 +352,27 @@ bit_spin_unlock(BH_JournalHead, &bh->b_state); } +#define HAVE_JOURNAL_CALLBACK_STATUS+/**+ * struct journal_callback - Base structure for callback information.+ * @jcb_list: list information for other callbacks attached to the same handle.+ * @jcb_func: Function to call with this callback structure. + *+ * This struct is a 'seed' structure for a using with your own callback+ * structs. If you are using callbacks you must allocate one of these+ * or another struct of your own definition which has this struct + * as it's first element and pass it to journal_callback_set().+ *+ * This is used internally by jbd to maintain callback information.+ *+ * See journal_callback_set for more information.+ **/+struct journal_callback {+ struct list_head jcb_list; /* t_jcb_lock */+ void (*jcb_func)(struct journal_callback *jcb, int error);+ /* user data goes here */+};+ struct jbd_revoke_table_s; /**@@ -360,6 +381,7 @@ * @h_transaction: Which compound transaction is this update a part of? * @h_buffer_credits: Number of remaining buffers we are allowed to dirty. * @h_ref: Reference count on this handle+ * @h_jcb: List of application registered callbacks for this handle. * @h_err: Field for caller's use to track errors through large fs operations * @h_sync: flag for sync-on-close * @h_jdata: flag to force data journaling@@ -385,6 +407,13 @@ /* operations */ int h_err; + /*+ * List of application registered callbacks for this handle. The+ * function(s) will be called after the transaction that this handle is+ * part of has been committed to disk. [t_jcb_lock]+ */+ struct list_head h_jcb;+ /* Flags [no locking] */ unsigned int h_sync: 1; /* sync-on-close */ unsigned int h_jdata: 1; /* force data journaling */@@ -426,6 +455,8 @@ * j_state_lock * ->j_list_lock (journal_unmap_buffer) *+ * t_handle_lock+ * ->t_jcb_lock */ struct transaction_s @@ -549,6 +580,15 @@ */ int t_handle_count; + /*+ * Protects the callback list+ */+ spinlock_t t_jcb_lock;+ /*+ * List of registered callback functions for this transaction.+ * Called when the transaction is committed. [t_jcb_lock]+ */+ struct list_head t_jcb; }; /**@@ -881,6 +921,10 @@ extern int journal_try_to_free_buffers(journal_t *, struct page *, int); extern int journal_stop(handle_t *); extern int journal_flush (journal_t *);+extern void journal_callback_set(handle_t *handle,+ void (*fn)(struct journal_callback *,int),+ struct journal_callback *jcb);+ extern void journal_lock_updates (journal_t *); extern void journal_unlock_updates (journal_t *); --- 1.23/fs/jbd/checkpoint.c 2003-07-10 23:23:54 -06:00+++ 1.24/fs/jbd/checkpoint.c 2004-11-07 19:13:24 -07:00@@ -616,6 +616,7 @@ J_ASSERT(transaction->t_log_list == NULL); J_ASSERT(transaction->t_checkpoint_list == NULL); J_ASSERT(transaction->t_updates == 0);+ J_ASSERT(list_empty(&transaction->t_jcb)); J_ASSERT(journal->j_committing_transaction != transaction); J_ASSERT(journal->j_running_transaction != transaction); --- 1.53/fs/jbd/commit.c 2004-10-19 03:40:17 -06:00+++ 1.54/fs/jbd/commit.c 2004-11-07 19:13:24 -07:00@@ -686,6 +686,30 @@ if (err) __journal_abort_hard(journal); + /*+ * Call any callbacks that had been registered for handles in this+ * transaction. It is up to the callback to free any allocated+ * memory.+ *+ * The spinlocking (t_jcb_lock) here is surely unnecessary...+ */+ spin_lock(&commit_transaction->t_jcb_lock);+ if (!list_empty(&commit_transaction->t_jcb)) {+ struct list_head *p, *n;+ int error = is_journal_aborted(journal);++ list_for_each_safe(p, n, &commit_transaction->t_jcb) {+ struct journal_callback *jcb;++ jcb = list_entry(p, struct journal_callback, jcb_list);+ list_del(p);+ spin_unlock(&commit_transaction->t_jcb_lock);+ jcb->jcb_func(jcb, error);+ spin_lock(&commit_transaction->t_jcb_lock);+ }+ }+ spin_unlock(&commit_transaction->t_jcb_lock);+ jbd_debug(3, "JBD: commit phase 7\n"); J_ASSERT(commit_transaction->t_sync_datalist == NULL);--- 1.77/fs/jbd/journal.c 2004-09-21 20:58:08 -06:00+++ 1.78/fs/jbd/journal.c 2004-11-07 19:13:24 -07:00@@ -55,6 +55,7 @@ #endif EXPORT_SYMBOL(journal_flush); EXPORT_SYMBOL(journal_revoke);+EXPORT_SYMBOL(journal_callback_set); EXPORT_SYMBOL(journal_init_dev); EXPORT_SYMBOL(journal_init_inode);@@ -78,6 +79,7 @@ EXPORT_SYMBOL(journal_blocks_per_page); EXPORT_SYMBOL(journal_invalidatepage); EXPORT_SYMBOL(journal_try_to_free_buffers);+EXPORT_SYMBOL(journal_bmap); EXPORT_SYMBOL(journal_force_commit); static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);--- 1.89/fs/jbd/transaction.c 2004-10-19 03:40:17 -06:00+++ 1.90/fs/jbd/transaction.c 2004-11-07 19:13:24 -07:00@@ -50,7 +50,9 @@ transaction->t_state = T_RUNNING; transaction->t_tid = journal->j_transaction_sequence++; transaction->t_expires = jiffies + journal->j_commit_interval;+ INIT_LIST_HEAD(&transaction->t_jcb); spin_lock_init(&transaction->t_handle_lock);+ spin_lock_init(&transaction->t_jcb_lock); /* Set up the commit timer for the new transaction. */ journal->j_commit_timer->expires = transaction->t_expires;@@ -241,6 +243,7 @@ memset(handle, 0, sizeof(*handle)); handle->h_buffer_credits = nblocks; handle->h_ref = 1;+ INIT_LIST_HEAD(&handle->h_jcb); return handle; }@@ -1274,6 +1277,36 @@ } /**+ * void journal_callback_set() - Register a callback function for this handle.+ * @handle: handle to attach the callback to.+ * @func: function to callback.+ * @jcb: structure with additional information required by func() , and+ * some space for jbd internal information.+ * + * The function will be+ * called when the transaction that this handle is part of has been+ * committed to disk with the original callback data struct and the+ * error status of the journal as parameters. There is no guarantee of+ * ordering between handles within a single transaction, nor between+ * callbacks registered on the same handle.+ *+ * The caller is responsible for allocating the journal_callback struct.+ * This is to allow the caller to add as much extra data to the callback+ * as needed, but reduce the overhead of multiple allocations. The caller+ * allocated struct must start with a struct journal_callback at offset 0,+ * and has the caller-specific data afterwards.+ */+void journal_callback_set(handle_t *handle,+ void (*func)(struct journal_callback *jcb, int error),+ struct journal_callback *jcb)+{+ spin_lock(&handle->h_transaction->t_jcb_lock);+ list_add_tail(&jcb->jcb_list, &handle->h_jcb);+ spin_unlock(&handle->h_transaction->t_jcb_lock);+ jcb->jcb_func = func;+}++/** * int journal_stop() - complete a transaction * @handle: tranaction to complete. * @@ -1338,6 +1371,11 @@ if (journal->j_barrier_count) wake_up(&journal->j_wait_transaction_locked); }++ /* Move callbacks from the handle to the transaction. */+ spin_lock(&transaction->t_jcb_lock);+ list_splice(&handle->h_jcb, &transaction->t_jcb);+ spin_unlock(&transaction->t_jcb_lock); /* * If the handle is marked SYNC, we need to set another commit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -