[Ocfs2-commits] rev 23 - in trunk/src: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu Feb 5 15:23:47 CST 2004
Author: manish
Date: 2004-02-05 15:23:45 -0600 (Thu, 05 Feb 2004)
New Revision: 23
Modified:
trunk/src/Makefile
trunk/src/alloc.c
trunk/src/file.c
trunk/src/inc/ocfs.h
trunk/src/inc/proto.h
trunk/src/journal.c
trunk/src/namei.c
trunk/src/nm.c
trunk/src/super.c
Log:
* added a whole new thread for committing the cache
* add a missing 'free' in free_bitmap_free_head
* make the bitmap_free_head alloc/free macros into real life static inline functions!
Modified: trunk/src/Makefile
===================================================================
--- trunk/src/Makefile 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/Makefile 2004-02-05 21:23:45 UTC (rev 23)
@@ -39,10 +39,11 @@
DEFINES += -DUSE_JOURNAL_CREATE_REPLACEMENT
endif
-DEFINES += -DVERBOSE_BH_SEM
+#DEFINES += -DVERBOSE_BH_SEM
DEFINES += -DDEBUG_LOCK_BUFFER
DEFINES += -DVERBOSE_BH_JBD_TRACE
DEFINES += -DVERBOSE_LOCKING_TRACE
+DEFINES += -DVERBOSE_BH_SEQNUM_TRACE
ifneq ($(OCFS_PROCESSOR),ia64)
#DEFINES += -DOCFS_DBG_TIMING
Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/alloc.c 2004-02-05 21:23:45 UTC (rev 23)
@@ -3411,7 +3411,7 @@
}
if (!(*f)) {
- *f = alloc_bitmap_free_head();
+ *f = ocfs_alloc_bitmap_free_head();
if (*f == NULL) {
LOG_ERROR_STATUS(-ENOMEM);
goto bail;
@@ -3441,7 +3441,7 @@
bit_off + alloc->bitmap_start,
-1, DISK_ALLOC_VOLUME);
if (status < 0) {
- free_bitmap_free_head(*f);
+ ocfs_free_bitmap_free_head(*f);
*f = NULL;
}
bit_off++;
@@ -3526,7 +3526,7 @@
LOG_ERROR_STR("Multiple window allocations in a transaction "
"-- this is illegal!");
else
- handle->abort_bits = alloc_bitmap_free_head();
+ handle->abort_bits = ocfs_alloc_bitmap_free_head();
status = ocfs_add_to_bitmap_free_head(osb, handle->abort_bits,
cluster_count,
@@ -3538,7 +3538,7 @@
/* In case of this error, we want to shutdown the
* local alloc bitmap. We'll let shutdown handling
* deal with freeing newly allocated bits. */
- free_bitmap_free_head(handle->abort_bits);
+ ocfs_free_bitmap_free_head(handle->abort_bits);
handle->abort_bits = NULL;
}
bail:
@@ -3977,7 +3977,7 @@
ocfs_process_bitmap_free_head(osb, f);
if (f) {
- free_bitmap_free_head(f);
+ ocfs_free_bitmap_free_head(f);
f = NULL;
}
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/file.c 2004-02-05 21:23:45 UTC (rev 23)
@@ -873,7 +873,7 @@
/* we keep our bitmap updates in this structure and process
* them later. */
- free_head = alloc_bitmap_free_head();
+ free_head = ocfs_alloc_bitmap_free_head();
if (free_head == NULL) {
LOG_ERROR_STATUS (status = -ENOMEM);
goto leave;
@@ -1005,7 +1005,7 @@
ocfs_abort_trans(handle);
if (free_head)
- free_bitmap_free_head(free_head);
+ ocfs_free_bitmap_free_head(free_head);
if (bAcquiredLock) {
if (bFileLockAcquired)
Modified: trunk/src/inc/ocfs.h
===================================================================
--- trunk/src/inc/ocfs.h 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/inc/ocfs.h 2004-02-05 21:23:45 UTC (rev 23)
@@ -1933,6 +1933,14 @@
struct inode *i_inode; /* may be null! */
} ocfs_inode_num;
+typedef struct _ocfs_commit_task
+{
+ struct completion c_complete;
+ struct task_struct *c_task;
+ struct semaphore c_lock;
+ struct list_head c_list;
+} ocfs_commit_task;
+
/*
* ocfs_super
*
@@ -1944,8 +1952,9 @@
ocfs_sem osb_res; /* resource to protect the ocfs_super */
struct list_head osb_next; /* list of ocfs_super(s) */
__u32 osb_id; /* id used by the proc interface */
- struct completion complete;
+ struct completion dlm_complete;
struct task_struct *dlm_task;
+ ocfs_commit_task *commit;
__u32 osb_flags;
__s64 file_open_cnt; /* num of open files/dirs. vol cannot be dismounted if > 0 */
__u64 publ_map; /* each bit represents state of node */
@@ -2439,33 +2448,36 @@
}
ocfs_bitmap_free_head;
-#define alloc_bitmap_free_head() \
- ({ \
- struct _ocfs_bitmap_free_head *f; \
- f = ocfs_malloc(sizeof(ocfs_bitmap_free_head)); \
- if (f) { \
- f->num_logs = 0; \
- f->tail = NULL; \
- INIT_LIST_HEAD(&(f->free_logs)); \
- } \
- f; \
- })
+static inline ocfs_bitmap_free_head * ocfs_alloc_bitmap_free_head(void)
+{
+ struct _ocfs_bitmap_free_head *f;
-#define free_bitmap_free_head(f) \
- do { \
- ocfs_free_rec *log; \
- struct list_head *p, *n; \
- \
- if ((f) && ((f)->num_logs)) { \
- list_for_each_safe(p, n, &((f)->free_logs)) { \
- log = list_entry(p, ocfs_free_rec, log_list); \
- list_del(&(log->log_list)); \
- } \
- } \
- ocfs_safefree((f)); \
- } while(0)
+ f = ocfs_malloc(sizeof(ocfs_bitmap_free_head));
+ if (f) {
+ f->num_logs = 0;
+ f->tail = NULL;
+ INIT_LIST_HEAD(&(f->free_logs));
+ }
+ return(f);
+}
+static inline void ocfs_free_bitmap_free_head(ocfs_bitmap_free_head *f)
+{
+ ocfs_free_rec *log;
+ struct list_head *p, *n;
+ if ((f) && ((f)->num_logs)) {
+ list_for_each_safe(p, n, &((f)->free_logs)) {
+ log = list_entry(p, ocfs_free_rec, log_list);
+ list_del(&(log->log_list));
+ ocfs_free(log);
+ }
+ }
+ ocfs_safefree((f));
+ return;
+}
+
+
struct ocfs_ioc
{
char name[255]; /* "OCFS" */
Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/inc/proto.h 2004-02-05 21:23:45 UTC (rev 23)
@@ -69,6 +69,7 @@
int ocfs_submit_vol_metadata(ocfs_super *osb, ocfs_offset_map *map_buf, __u32 num);
int ocfs_commit_cache (ocfs_super * osb, bool data_flush);
+int ocfs_commit_thread(void *arg);
void ocfs_init_sem (ocfs_sem * res);
bool ocfs_down_sem (ocfs_sem * res, bool wait);
Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/journal.c 2004-02-05 21:23:45 UTC (rev 23)
@@ -314,6 +314,7 @@
int retval, i;
bool checkpoint, sync;
ocfs_journal *journal;
+ ocfs_bitmap_free_head *commit_head, *abort_head;
LOG_ENTRY();
@@ -416,16 +417,21 @@
handle->buffs = NULL;
}
+ /* save off while we still have trans lock */
+ commit_head = handle->commit_bits;
+ abort_head = handle->abort_bits;
+ handle->commit_bits = handle->abort_bits = NULL;
+
/* This has to happen after we release the other locks. */
ocfs_release_trans_lock(osb);
- if (handle->commit_bits && (retval == 0)) {
+ if (commit_head && (retval == 0)) {
if (!sync)
BUG();
- ocfs_process_bitmap_free_head(osb, handle->commit_bits);
+ ocfs_process_bitmap_free_head(osb, commit_head);
}
- free_bitmap_free_head(handle->commit_bits);
- free_bitmap_free_head(handle->abort_bits);
+ ocfs_free_bitmap_free_head(handle->commit_bits);
+ ocfs_free_bitmap_free_head(handle->abort_bits);
if (checkpoint)
ocfs_free(handle);
@@ -575,11 +581,12 @@
/* This has to happen after we release the other locks. */
ocfs_release_trans_lock(osb);
+ /* no need to save off commit or abort heads here; not on any lists */
if (handle->abort_bits && (retval == 0))
ocfs_process_bitmap_free_head(osb, handle->abort_bits);
- free_bitmap_free_head(handle->commit_bits);
- free_bitmap_free_head(handle->abort_bits);
+ ocfs_free_bitmap_free_head(handle->commit_bits);
+ ocfs_free_bitmap_free_head(handle->abort_bits);
if (handle->buffs)
ocfs_free(handle->buffs);
@@ -1003,10 +1010,18 @@
* completely destroy the journal. */
journal->state = OCFS_JOURNAL_IN_SHUTDOWN;
- status = ocfs_commit_cache(osb, false);
- if (status < 0)
- LOG_ERROR_STATUS(status);
+ atomic_set (&osb->flush_event_woken, 1);
+ wake_up (&osb->flush_event);
+ /* Wait for the commit thread */
+ if (osb->commit && osb->commit->c_task) {
+ LOG_TRACE_STR ("Waiting for ocfs2commit to exit....");
+ send_sig (SIGINT, osb->commit->c_task, 0);
+ wait_for_completion(&osb->commit->c_complete);
+ osb->commit->c_task = NULL;
+ ocfs_free(osb->commit);
+ }
+
/* Shutdown the kernel journal system */
journal_destroy(journal->k_journal);
@@ -1681,6 +1696,86 @@
return (status);
} /* ocfs_reset_publish */
+
+#define OCFS_COMMIT_MISS_MAX 5
+#define OCFS_COMMIT_INTERVAL 2000 // in ms
+int ocfs_commit_thread(void *arg)
+{
+ int status = 0, misses = 0, finish = 0;
+ ocfs_super *osb = (ocfs_super *)arg;
+ ocfs_commit_task *commit = osb->commit;
+ struct list_head *head = &commit->c_list;
+ char name[16];
+
+ sprintf (name, "ocfs2cmt-%d", osb->osb_id);
+ ocfs_daemonize (name, strlen(name));
+
+ commit->c_task = current;
+
+ misses = 0;
+ while (!(OcfsGlobalCtxt.flags & OCFS_FLAG_SHUTDOWN_VOL_THREAD) &&
+ !(osb->osb_flags & OCFS_OSB_FLAGS_BEING_DISMOUNTED)) {
+
+ status = ocfs_wait (osb->flush_event,
+ atomic_read (&osb->flush_event_woken), OCFS_COMMIT_INTERVAL);
+
+ atomic_set (&osb->flush_event_woken, 0);
+
+ switch (status) {
+ case -ETIMEDOUT:
+ LOG_TRACE_STR("FLUSH_EVENT: timed out");
+ break;
+ case -EINTR:
+ finish = 1;
+ LOG_TRACE_STR("FLUSH_EVENT: interrupted");
+ break;
+ case 0:
+ LOG_TRACE_STR("FLUSH_EVENT: woken!!!");
+ break;
+ default:
+ LOG_TRACE_STR("FLUSH_EVENT: ??????");
+ break;
+ }
+
+ if ((OcfsGlobalCtxt.flags & OCFS_FLAG_SHUTDOWN_VOL_THREAD) ||
+ (osb->osb_flags & OCFS_OSB_FLAGS_BEING_DISMOUNTED))
+ break;
+
+ //if (!osb->needs_flush && status != 0)
+ // continue;
+
+ // if (osb->trans_in_progress)
+ // continue;
+
+ if (down_trylock(&osb->trans_lock) != 0) {
+ LOG_TRACE_ARGS("commit thread: trylock failed, miss=%d\n", misses);
+ if (++misses < OCFS_COMMIT_MISS_MAX)
+ continue;
+ LOG_TRACE_ARGS("commit thread: about to down\n");
+ down(&osb->trans_lock);
+ misses = 0;
+ }
+
+ status = ocfs_commit_cache (osb, false);
+ if (status < 0)
+ LOG_ERROR_STATUS(status);
+
+ if (finish)
+ break;
+ }
+
+
+
+ /* Flush all scheduled tasks */
+#ifdef LINUX_2_5
+ flush_scheduled_work ();
+#else
+ flush_scheduled_tasks ();
+#endif
+ complete (&(commit->c_complete));
+ return 0;
+}
+
/*
* ocfs_commit_cache()
*
@@ -1696,8 +1791,8 @@
int status = 0, tmpstat;
ocfs_journal * journal = NULL;
struct list_head *p, *n;
- struct list_head tmplist;
ocfs_journal_handle *handle = NULL;
+ ocfs_commit_task *commit = osb->commit;
LOG_ENTRY_ARGS("(data_flush = %u)\n", data_flush);
@@ -1731,16 +1826,17 @@
/* now we can run an unlock against any pending handles and
* release them. */
- INIT_LIST_HEAD(&tmplist);
+ down(&journal->commit_sem);
+ down(&commit->c_lock);
- down(&journal->commit_sem);
/* 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 , (&tmplist));
+ list_splice(&journal->commited , &commit->c_list);
INIT_LIST_HEAD(&journal->commited);
}
+ up(&commit->c_lock);
up(&journal->commit_sem);
osb->needs_flush = false;
@@ -1748,7 +1844,8 @@
if (journal->state != OCFS_JOURNAL_IN_SHUTDOWN)
up(&osb->trans_lock);
- list_for_each_safe(p, n, &tmplist) {
+ down(&commit->c_lock);
+ list_for_each_safe(p, n, &commit->c_list) {
handle = list_entry(p, ocfs_journal_handle, h_list);
tmpstat = ocfs_journal_release_locks(handle, 0);
if (tmpstat < 0)
@@ -1756,6 +1853,7 @@
list_del(&(handle->h_list));
ocfs_free(handle);
}
+ up(&commit->c_lock);
flush_data:
/* flush data buffers if asked. */
Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/namei.c 2004-02-05 21:23:45 UTC (rev 23)
@@ -1241,7 +1241,7 @@
if (new_dir_bh)
brelse(new_dir_bh);
if (free_head)
- free_bitmap_free_head(free_head);
+ ocfs_free_bitmap_free_head(free_head);
if (status < 0)
ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
@@ -1591,7 +1591,7 @@
if (ret_head)
*ret_head = NULL;
- free_head = alloc_bitmap_free_head();
+ free_head = ocfs_alloc_bitmap_free_head();
if (free_head == NULL) {
LOG_ERROR_STATUS (status = -ENOMEM);
goto leave;
@@ -1843,7 +1843,7 @@
*ret_head = free_head;
else {
LOG_TRACE_STR("freeing bitmap_free_head");
- free_bitmap_free_head(free_head);
+ ocfs_free_bitmap_free_head(free_head);
}
}
Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/nm.c 2004-02-05 21:23:45 UTC (rev 23)
@@ -221,9 +221,6 @@
ocfs_super *osb;
char proc[16];
int status = 0;
-#ifdef DO_PERIODIC_SYNC
- int flush_counter = 0;
-#endif
__u8 *buffer = NULL;
ocfs_publish *publish;
__u32 i;
@@ -260,44 +257,6 @@
if (OcfsGlobalCtxt.hbm == 0)
OcfsGlobalCtxt.hbm = DISK_HBEAT_NO_COMM;
- status = ocfs_wait (osb->flush_event,
- atomic_read (&osb->flush_event_woken), OCFS_NM_HEARTBEAT_TIME);
- atomic_set (&osb->flush_event_woken, 0);
-
- if (status == -ETIMEDOUT)
- LOG_TRACE_STR("FLUSH_EVENT: timed out");
- else if (status == -EINTR)
- LOG_TRACE_STR("FLUSH_EVENT: interrupted");
- else if (status == 0)
- LOG_TRACE_STR("FLUSH_EVENT: woken!!!");
- else
- LOG_TRACE_STR("FLUSH_EVENT: ??????");
-
- if ((OcfsGlobalCtxt.flags & OCFS_FLAG_SHUTDOWN_VOL_THREAD) ||
- (osb->osb_flags & OCFS_OSB_FLAGS_BEING_DISMOUNTED))
- break;
-
- if (!time_after (jiffies, (unsigned long) (osb->hbt)))
- goto finally;
-
- if (osb->vol_state == VOLUME_MOUNTED) {
- if (osb->needs_flush && down_trylock(&osb->trans_lock) == 0) {
- if (osb->trans_in_progress == false) {
- flush_misses = 0;
- status = ocfs_commit_cache(osb, false);
- if (status < 0)
- LOG_ERROR_STATUS (status);
- }
- } else if (osb->needs_flush) {
- flush_misses++;
- if (flush_misses > OCFS_NM_MAX_FLUSH_MISSES) {
- printk("ocfs2: nm thread has not been "
- "able to commit cache in %d "
- "iterations!\n", flush_misses);
- }
- }
- }
-
/* try to prune some bh_sem hash entries if list is too long */
pruned = ocfs_bh_sem_hash_prune();
LOG_TRACE_ARGS("pruned %d entries from nm thread\n", pruned);
@@ -426,25 +385,16 @@
goto finally;
}
}
- osb->hbt = 50 + jiffies;
finally:
- status = 0; // ??????????????????????????
+ status = 0;
+
+ if ((OcfsGlobalCtxt.flags & OCFS_FLAG_SHUTDOWN_VOL_THREAD) ||
+ (osb->osb_flags & OCFS_OSB_FLAGS_BEING_DISMOUNTED))
+ break;
+ schedule_timeout (50);
+ }
- if (status < 0) {
- if (osb->osb_flags & OCFS_OSB_FLAGS_BEING_DISMOUNTED)
- break;
- }
-#ifdef DO_PERIODIC_SYNC
- /* do a syncdev every 2 minutes currently that is 500ms per cycle */
- if (flush_counter++ == 240) {
- ocfs_sync_blockdev(osb->sb);
- flush_counter = 0;
- }
-#endif
-
- } /* while (!OCFS_FLAG_SHUTDOWN_VOL_THREAD && !OCFS_OSB_FLAGS_BEING_DISMOUNTED) */
-
/* Flush all scheduled tasks */
#ifdef LINUX_2_5
flush_scheduled_work ();
@@ -452,7 +402,7 @@
flush_scheduled_tasks ();
#endif
- complete (&(osb->complete));
+ complete (&(osb->dlm_complete));
eek:
LOG_EXIT_LONG (0);
return 0;
@@ -989,40 +939,19 @@
}
/* We have the trans_lock! If it's in the
- * commited list, then dump cache and give it
- * to the other node. Otherwise, it's
+ * commited list, then kick the commit thread
+ * and vote RETRY this time. Otherwise, it's
* currently in use by another transaction. */
down(&(osb->journal.commit_sem));
in_cache = ocfs_search_commited(osb, lockres);
up(&(osb->journal.commit_sem));
if (in_cache) {
- /* if we keep the lockres locked, then
- * the call to release_lock in
- * commit_cache will deadlock. On the
- * other hand, we don't want it
- * destroyed behind us. */
- ocfs_get_lockres(lockres);
- ocfs_release_lockres(lockres);
+ atomic_set (&osb->flush_event_woken, 1);
+ wake_up (&osb->flush_event);
+ }
+ up(&osb->trans_lock);
- status = ocfs_commit_cache(osb, false);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- ocfs_put_lockres(lockres);
- goto leave;
- }
-
- status = ocfs_acquire_lockres_ex(lockres,
- (OCFS_NM_HEARTBEAT_TIME/2));
- ocfs_put_lockres(lockres);
- if (status < 0)
- LOG_TRACE_STR("Timed out locking "
- "lockres again.");
- else if (lockres->lock_holders == 0)
- goto give_lock;
- } else
- up(&osb->trans_lock);
-
/* Ok, either we couldn't find it in the
* cache, or it became busy again while we
* were dumping cache. */
Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c 2004-02-05 21:10:44 UTC (rev 22)
+++ trunk/src/super.c 2004-02-05 21:23:45 UTC (rev 23)
@@ -893,8 +893,9 @@
}
spin_unlock (&osb_id_lock);
+ ocfs_down_sem (&(osb->osb_res), true);
+
/* Launch the NM thread for the mounted volume */
- ocfs_down_sem (&(osb->osb_res), true);
osb->dlm_task = NULL;
child_pid = kernel_thread (ocfs_volume_thread, osb,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
@@ -905,8 +906,30 @@
status = -EFAIL;
goto leave;
} else {
- init_completion (&osb->complete);
+ init_completion (&osb->dlm_complete);
}
+
+ /* Launch the commit thread */
+ osb->commit = (ocfs_commit_task *)ocfs_malloc(sizeof(ocfs_commit_task));
+ if (osb->commit == NULL) {
+ LOG_ERROR_STATUS(status = -ENOMEM);
+ goto leave;
+ }
+ memset(osb->commit, 0, sizeof(ocfs_commit_task));
+ init_MUTEX(&osb->commit->c_lock);
+ INIT_LIST_HEAD(&osb->commit->c_list);
+ child_pid = kernel_thread (ocfs_commit_thread, osb,
+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+ if (child_pid < 0) {
+ LOG_ERROR_ARGS ("unable to launch ocfs2commit thread, error=%d",
+ child_pid);
+ ocfs_up_sem (&(osb->osb_res));
+ status = -EFAIL;
+ goto leave;
+ } else {
+ init_completion (&osb->commit->c_complete);
+ }
+
ocfs_up_sem (&(osb->osb_res));
/* Add proc entry for this volume */
@@ -1076,10 +1099,11 @@
if (osb->dlm_task) {
LOG_TRACE_STR ("Waiting for ocfs2nm to exit....");
send_sig (SIGINT, osb->dlm_task, 0);
- wait_for_completion (&(osb->complete));
+ wait_for_completion (&(osb->dlm_complete));
osb->dlm_task = NULL;
}
+
/* create map of all active nodes except self */
nodemap = (__u32)osb->publ_map;
tempmap = (1 << osb->node_num);
More information about the Ocfs2-commits
mailing list