[Ocfs2-commits] mfasheh commits r1211 - trunk/src
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Jun 25 13:50:06 CDT 2004
Author: mfasheh
Date: 2004-06-25 12:50:04 -0500 (Fri, 25 Jun 2004)
New Revision: 1211
Modified:
trunk/src/journal.c
Log:
* Commit the last of my 2.4 BKL fixes against our journalling stuff.
Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c 2004-06-24 23:22:45 UTC (rev 1210)
+++ trunk/src/journal.c 2004-06-25 17:50:04 UTC (rev 1211)
@@ -66,19 +66,120 @@
static int __ocfs_recovery_thread(void *arg);
static int ocfs_commit_cache (ocfs_super * osb, int data_flush);
static int ocfs_wait_on_mount(ocfs_super *osb);
+static int ocfs_journal_flush(ocfs_journal *journal);
+static int ocfs_journal_flush(ocfs_journal *journal)
+{
+ int retval;
+
+ down_write(&journal->trans_barrier);
+ journal_lock_updates(journal->k_journal);
+
+ retval = journal_flush(journal->k_journal);
+
+ journal_unlock_updates(journal->k_journal);
+ up_write(&journal->trans_barrier);
+
+ return(retval);
+}
+
/*
- * JBD in 2.4 kernels has a bug in that it doesn't do any locking of
- * the t_updates transaction variable. If we don't serialize calls to
- * journal_start/journal_stop, then it can get way out of whack,
- * resulting in either a crash or a lockup. As far as I can tell, they
- * never hit this bug in ext3 because those calls somehow manage to
- * get serialized. I wish I didn't have to use lock_kernel here, but
- * we actually want the "drop on sleep" behavior which we can't get
- * with any other lock.
- *
- * 2.6 does it the right way by spinlocking around it's structures.
+ * ocfs_commit_cache()
*
+ * This is in journal.c for lack of a better place.
+ *
+ */
+static int ocfs_commit_cache(ocfs_super *osb, int data_flush)
+{
+ int status = 0, tmpstat;
+ ocfs_journal * journal = NULL;
+ struct list_head *p, *n;
+ ocfs_journal_handle *handle = NULL;
+ ocfs_commit_task *commit = osb->commit;
+
+ LOG_ENTRY_ARGS("(data_flush = %u)\n", data_flush);
+
+ journal = osb->journal;
+
+ if (atomic_read(&journal->num_trans) == 0) {
+ LOG_TRACE_STR("No transactions for me to flush!");
+ goto flush_data;
+ }
+
+ /* flush all pending commits and checkpoint the journal. */
+ down_write(&journal->trans_barrier);
+
+ /* check again, this time locked :) */
+ if (atomic_read(&journal->num_trans) == 0) {
+ up_write(&journal->trans_barrier);
+ goto flush_data;
+ }
+
+ journal_lock_updates(journal->k_journal);
+ status = journal_flush(journal->k_journal);
+
+ up_write(&journal->trans_barrier);
+ if (status < 0) {
+ journal_unlock_updates(journal->k_journal);
+
+ LOG_ERROR_STATUS(status);
+ goto finally;
+ }
+
+ LOG_TRACE_ARGS("flushing %d transactions\n",
+ atomic_read(&journal->num_trans));
+
+ /* now we can run an unlock against any pending handles and
+ * release them. */
+ down(&journal->commit_sem);
+ down(&commit->c_lock);
+
+ /* Once we've got commit_sem, we can let transactions start
+ * again -- it should protect us against people mucking with
+ * the commited list... */
+ journal_unlock_updates(journal->k_journal);
+
+ /* we want to take everything off the commited list and
+ * process it independently, so we can drop the trans_lock
+ * earlier. */
+ if (!list_empty(&journal->commited)) {
+ list_splice(&journal->commited , &commit->c_list);
+ INIT_LIST_HEAD(&journal->commited);
+ }
+ up(&commit->c_lock);
+ up(&journal->commit_sem);
+
+ osb->needs_flush = 0;
+
+ down(&commit->c_lock);
+ list_for_each_safe(p, n, &commit->c_list) {
+ handle = list_entry(p, ocfs_journal_handle, h_list);
+ tmpstat = ocfs_handle_release_locks(handle, TRANS_CACHE);
+ if (tmpstat < 0)
+ LOG_ERROR_STATUS((status = tmpstat));
+ list_del(&(handle->h_list));
+ kfree(handle);
+
+ atomic_dec(&journal->num_trans);
+ }
+ up(&commit->c_lock);
+
+flush_data:
+ /* flush data buffers if asked. */
+ if (data_flush)
+ ocfs_sync_blockdev(osb->sb);
+
+finally:
+ LOG_EXIT_STATUS (status);
+ return status;
+} /* ocfs_commit_cache */
+
+/*
+ * JBD in 2.4 kernels uses lock_kernel pretty heavily. Most of the
+ * time we get that from the VFS, but we do transactions without BKL
+ * sometimes. 2.6 does things right and spinlocks around it's
+ * structures so at least this junk won't last too long...
+ *
* These aren't in ocfs_compat.h because they require wayyyy to much
* #included.
*/
@@ -118,14 +219,50 @@
/* these two gained another argument during 2.6 */
static inline int ocfs_journal_get_write_access(handle_t *handle, struct buffer_head *bh)
{
- return journal_get_write_access(handle, bh);
+ int ret;
+
+ lock_kernel();
+ ret = journal_get_write_access(handle, bh);
+ unlock_kernel();
+ return ret;
}
static inline int ocfs_journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
{
- return journal_get_undo_access(handle, bh);
+ int ret;
+
+ lock_kernel();
+ ret = journal_get_undo_access(handle, bh);
+ unlock_kernel();
+ return ret;
}
+static inline int ocfs_commit_cache24 (ocfs_super * osb, int data_flush)
+{
+ int ret;
+
+ lock_kernel();
+ ret = ocfs_commit_cache(osb, data_flush);
+ unlock_kernel();
+ return ret;
+}
+
+static inline int ocfs_journal_flush24(ocfs_journal *journal)
+{
+ int ret;
+
+ lock_kernel();
+ ret = ocfs_journal_flush(journal);
+ unlock_kernel();
+ return ret;
+}
+
+#undef ocfs_commit_cache
+#undef ocfs_journal_flush
+
+#define ocfs_commit_cache ocfs_commit_cache24
+#define ocfs_journal_flush ocfs_journal_flush24
+
#undef journal_get_write_access
#undef journal_get_undo_access
@@ -135,8 +272,6 @@
ocfs_journal_get_undo_access(handle, bh)
#endif
-
-/* DO NOT EVER CALL THIS FUNCTION WITH A LOCKED BUFFER HEAD! */
ocfs_journal_handle * ocfs_start_trans(ocfs_super *osb, int max_buffs)
{
ocfs_journal_handle * retval = NULL;
@@ -379,21 +514,6 @@
} \
} while (0)
-static inline int ocfs_journal_flush(ocfs_journal *journal)
-{
- int retval;
-
- down_write(&journal->trans_barrier);
- journal_lock_updates(journal->k_journal);
-
- retval = journal_flush(journal->k_journal);
-
- journal_unlock_updates(journal->k_journal);
- up_write(&journal->trans_barrier);
-
- return(retval);
-}
-
/*
* ocfs_commit_trans
*/
@@ -1636,97 +1756,3 @@
return 0;
}
-/*
- * ocfs_commit_cache()
- *
- * This is in journal.c for lack of a better place.
- *
- * This function must be called with the trans_lock held.
- * No, really this function MUST be called with the trans_lock held!
- *
- * In any case, it will release the trans lock for you.
- */
-static int ocfs_commit_cache(ocfs_super *osb, int data_flush)
-{
- int status = 0, tmpstat;
- ocfs_journal * journal = NULL;
- struct list_head *p, *n;
- ocfs_journal_handle *handle = NULL;
- ocfs_commit_task *commit = osb->commit;
-
- LOG_ENTRY_ARGS("(data_flush = %u)\n", data_flush);
-
- journal = osb->journal;
-
- if (atomic_read(&journal->num_trans) == 0) {
- LOG_TRACE_STR("No transactions for me to flush!");
- goto flush_data;
- }
-
- /* flush all pending commits and checkpoint the journal. */
- down_write(&journal->trans_barrier);
-
- /* check again, this time locked :) */
- if (atomic_read(&journal->num_trans) == 0) {
- up_write(&journal->trans_barrier);
- goto flush_data;
- }
-
- journal_lock_updates(journal->k_journal);
- status = journal_flush(journal->k_journal);
-
- up_write(&journal->trans_barrier);
- if (status < 0) {
- journal_unlock_updates(journal->k_journal);
-
- LOG_ERROR_STATUS(status);
- goto finally;
- }
-
- LOG_TRACE_ARGS("flushing %d transactions\n",
- atomic_read(&journal->num_trans));
-
- /* now we can run an unlock against any pending handles and
- * release them. */
- down(&journal->commit_sem);
- down(&commit->c_lock);
-
- /* Once we've got commit_sem, we can let transactions start
- * again -- it should protect us against people mucking with
- * the commited list... */
- journal_unlock_updates(journal->k_journal);
-
- /* we want to take everything off the commited list and
- * process it independently, so we can drop the trans_lock
- * earlier. */
- if (!list_empty(&journal->commited)) {
- list_splice(&journal->commited , &commit->c_list);
- INIT_LIST_HEAD(&journal->commited);
- }
- up(&commit->c_lock);
- up(&journal->commit_sem);
-
- osb->needs_flush = 0;
-
- down(&commit->c_lock);
- list_for_each_safe(p, n, &commit->c_list) {
- handle = list_entry(p, ocfs_journal_handle, h_list);
- tmpstat = ocfs_handle_release_locks(handle, TRANS_CACHE);
- if (tmpstat < 0)
- LOG_ERROR_STATUS((status = tmpstat));
- list_del(&(handle->h_list));
- kfree(handle);
-
- atomic_dec(&journal->num_trans);
- }
- up(&commit->c_lock);
-
-flush_data:
- /* flush data buffers if asked. */
- if (data_flush)
- ocfs_sync_blockdev(osb->sb);
-
-finally:
- LOG_EXIT_STATUS (status);
- return status;
-} /* ocfs_commit_cache */
More information about the Ocfs2-commits
mailing list