[Ocfs2-commits] mfasheh commits r1605 - branches/dlm-glue/src
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Oct 29 17:05:24 CDT 2004
Author: mfasheh
Date: 2004-10-29 17:05:22 -0500 (Fri, 29 Oct 2004)
New Revision: 1605
Modified:
branches/dlm-glue/src/dlmglue.c
branches/dlm-glue/src/inode.c
branches/dlm-glue/src/journal.c
branches/dlm-glue/src/ocfs.h
branches/dlm-glue/src/ocfs_journal.h
branches/dlm-glue/src/proc.c
branches/dlm-glue/src/super.c
Log:
* get rid of the unused 'needs_flush' flag
* implement transaction ids on locks. commit thread no longer has to run a
long list of locks anymore as last transaction is recorded on them in
ocfs_commit_trans.
Modified: branches/dlm-glue/src/dlmglue.c
===================================================================
--- branches/dlm-glue/src/dlmglue.c 2004-10-29 01:33:20 UTC (rev 1604)
+++ branches/dlm-glue/src/dlmglue.c 2004-10-29 22:05:22 UTC (rev 1605)
@@ -971,6 +971,11 @@
LOG_ENTRY();
+#ifdef VERBOSE_LOCKING_TRACE
+ printk("Taking %s lock on inode %llu.\n",
+ ex ? "EXMODE" : "PRMODE", OCFS_I(inode)->ip_blkno);
+#endif
+
/* we skip recovery wait on journal inodes as those can be
* locked from ocfs_recover_node. */
if (!INODE_JOURNAL(inode)) {
@@ -1257,7 +1262,9 @@
OCFS_ASSERT(lock->l_level == LKM_EXMODE ||
lock->l_level == LKM_PRMODE);
- if (!lock->l_ro_holders && !lock->l_ex_holders) {
+ if (!lock->l_ro_holders
+ && !lock->l_ex_holders
+ && ocfs_inode_fully_checkpointed(inode)) {
new_level = ocfs2_highest_compat_lock_level(lock->l_blocking);
if (lock->l_level == LKM_EXMODE) {
__ocfs2_stuff_meta_lvb(inode);
@@ -1267,7 +1274,7 @@
return __ocfs2_downconvert_lock(lockres, lock, new_level,
set_lvb);
}
- if (lock->l_ex_holders)
+ if (!ocfs_inode_fully_checkpointed(inode))
ocfs_start_checkpoint(OCFS2_SB(inode->i_sb));
*requeue++;
Modified: branches/dlm-glue/src/inode.c
===================================================================
--- branches/dlm-glue/src/inode.c 2004-10-29 01:33:20 UTC (rev 1604)
+++ branches/dlm-glue/src/inode.c 2004-10-29 22:05:22 UTC (rev 1605)
@@ -314,8 +314,6 @@
init_rwsem(&i->ip_alloc_sem);
init_MUTEX(&(i->ip_io_sem));
- INIT_LIST_HEAD(&i->ip_pending_locks);
- INIT_LIST_HEAD(&i->ip_j_inode);
/* These should be set in read_inode2. */
i->ip_clusters = 0;
Modified: branches/dlm-glue/src/journal.c
===================================================================
--- branches/dlm-glue/src/journal.c 2004-10-29 01:33:20 UTC (rev 1604)
+++ branches/dlm-glue/src/journal.c 2004-10-29 22:05:22 UTC (rev 1605)
@@ -58,42 +58,34 @@
static int __ocfs_recovery_thread(void *arg);
static int ocfs_commit_cache (ocfs_super * osb);
static int ocfs_wait_on_mount(ocfs_super *osb);
-static void ocfs_handle_move_locks(ocfs_journal *journal,
- ocfs_journal_handle *handle);
+static void ocfs_handle_cleanup_locks(ocfs_journal *journal,
+ ocfs_journal_handle *handle,
+ int set_id);
static void ocfs_commit_unstarted_handle(ocfs_journal_handle *handle);
static int ocfs_journal_toggle_dirty(ocfs_super *osb,
int dirty);
/*
* ocfs_commit_cache()
- *
- * This is in journal.c for lack of a better place.
- *
*/
static int ocfs_commit_cache(ocfs_super *osb)
{
- int status = 0, tmpstat;
- unsigned int flushed = 0;
- unsigned int cmt_locks;
+ int status = 0;
+ unsigned int flushed;
+ unsigned long old_id;
ocfs_journal * journal = NULL;
- struct list_head *p, *n;
- ocfs_journal_lock *lock = NULL;
- struct inode *inode;
- ocfs_inode_private *ip;
LOG_ENTRY();
journal = osb->journal;
- /* Step 1: flush all pending commits and checkpoint the journal. */
+ /* Flush all pending commits and checkpoint the journal. */
down_write(&journal->trans_barrier);
if (atomic_read(&journal->num_trans) == 0) {
+ up_write(&journal->trans_barrier);
LOG_TRACE_STR("No transactions for me to flush!");
- /* now, we may have locks left to drop even though no
- * transactions are in the journal. */
-
- goto drop_locks;
+ goto finally;
}
journal_lock_updates(journal->k_journal);
@@ -105,91 +97,18 @@
goto finally;
}
- ocfs_inc_trans_id(journal);
+ old_id = ocfs_inc_trans_id(journal);
-drop_locks:
flushed = atomic_read(&journal->num_trans);
atomic_set(&journal->num_trans, 0);
-
- /* Step 2: Drop any locks acquired during transactions which
- * have just been checkpointed. */
- spin_lock(&journal->cmt_lock);
-
- cmt_locks = atomic_read(&journal->num_cmt_locks);
-
- atomic_add(atomic_read(&journal->num_cmt_locks),
- &journal->num_chkpt_locks);
- atomic_set(&journal->num_cmt_locks, 0);
-
- /* move the locks off each inode onto the commit threads list. */
- list_for_each_safe(p, n, &journal->committing_inodes) {
- ip = list_entry(p, ocfs_inode_private, ip_j_inode);
- inode = ip->ip_inode;
-
- if (!list_empty(&OCFS_I(inode)->ip_pending_locks))
- list_splice_init(&OCFS_I(inode)->ip_pending_locks,
- (&journal->checkpointing_locks)->prev);
-
- /* we can now remove the inode from the committing
- * list. */
- list_del_init(&OCFS_I(inode)->ip_j_inode);
- }
- osb->needs_flush = 0;
-
- spin_unlock(&journal->cmt_lock);
-
- /* TODO: Can we assert this anymore and move these lock
- * releases back up?
- *
- * Once we've got cmt_lock, we can let
- * transactions start again -- it should protect us against
- * people mucking with the committed list... */
up_write(&journal->trans_barrier);
#ifdef VERBOSE_COMMIT_THREAD
- if (flushed || cmt_locks)
- printk("(%u) commit_thread: flushed %u transactions, "
- "releasing %u locks\n", current->pid, flushed,
- cmt_locks);
+ printk("(%u) commit_thread: flushed transaction %lu (%u handles)\n",
+ current->pid, journal->trans_id, flushed);
#endif
-#ifdef VERBOSE_COMMIT_THREAD
- if (flushed || cmt_locks)
- printk("(%u) commit_thread: after optimization, %u locks "
- "to release\n", current->pid,
- atomic_read(&journal->num_chkpt_locks));
-#endif
-
- p = n = NULL;
- list_for_each_safe(p, n, &journal->checkpointing_locks) {
- if (!atomic_read(&journal->num_chkpt_locks))
- BUG();
-
- lock = list_entry(p, ocfs_journal_lock, jl_lock_list);
-
- list_del(&(lock->jl_lock_list));
-
- if (!lock->jl_inode)
- BUG();
-
-#if 0
- /* enable this for tons of output, which will likely
- * hang your box :) */
- printk("commit_thread: release lock %u (inode %llu)\n",
- atomic_read(&journal->num_chkpt_locks),
- OCFS_I(lock->jl_inode)->ip_blkno);
-#endif
- tmpstat = 0;
- OCFS_ASSERT(!INODE_DELETED(lock->jl_inode));
- ocfs2_meta_unlock(lock->jl_inode, 1);
- iput(lock->jl_inode);
-
- atomic_dec(&journal->num_chkpt_locks);
- kmem_cache_free(OcfsGlobalCtxt.lock_cache, lock);
- }
-
ocfs2_kick_vote_thread(osb);
-
finally:
LOG_EXIT_STATUS (status);
return status;
@@ -435,10 +354,7 @@
/* You are allowed to add journal locks before the transaction
* has started. */
osb = handle->osb;
- ocfs_handle_move_locks(osb->journal, handle);
- spin_lock(&osb->journal->cmt_lock);
- osb->needs_flush = 1;
- spin_unlock(&osb->journal->cmt_lock);
+ ocfs_handle_cleanup_locks(osb->journal, handle, 0);
kfree(handle);
LOG_EXIT();
@@ -488,10 +404,7 @@
BUG();
}
- ocfs_handle_move_locks(osb->journal, handle);
- spin_lock(&osb->journal->cmt_lock);
- osb->needs_flush = 1;
- spin_unlock(&osb->journal->cmt_lock);
+ ocfs_handle_cleanup_locks(osb->journal, handle, 1);
up_read(&journal->trans_barrier);
@@ -654,9 +567,6 @@
list_add_tail(&(lock->jl_lock_list), &(handle->locks));
handle->num_locks++;
- spin_lock(&handle->journal->cmt_lock);
- atomic_inc(&handle->journal->num_cmt_locks);
- spin_unlock(&handle->journal->cmt_lock);
status = 0;
bail:
@@ -664,19 +574,9 @@
return status;
}
-/* move the locks off a journal handle and onto the
- * inode->ip_pending_locks. makes sure the inodes are on
- * journal->committing_inodes so that the commit thread can get them
- * after checkpoint.
- *
- * You want to do this before dropping trans_barrier to prevent the commit
- * thread from missing the locks.
- *
- * TODO: When we get rid of the last checkpointed transactions, we can
- * just put locks right on the inode in ocfs_handle_add_lock...
- */
-static void ocfs_handle_move_locks(ocfs_journal *journal,
- ocfs_journal_handle *handle)
+static void ocfs_handle_cleanup_locks(ocfs_journal *journal,
+ ocfs_journal_handle *handle,
+ int set_id)
{
struct list_head *p, *n;
ocfs_journal_lock *lock;
@@ -688,18 +588,15 @@
handle->num_locks--;
inode = lock->jl_inode;
-
- spin_lock(&journal->cmt_lock);
- /* add the lock to the inode */
- list_add_tail(&lock->jl_lock_list,
- &OCFS_I(inode)->ip_pending_locks);
- /* and make sure the inode is on the journals list */
- if (list_empty(&OCFS_I(inode)->ip_j_inode))
- list_add_tail(&OCFS_I(inode)->ip_j_inode,
- &journal->committing_inodes);
- spin_unlock(&journal->cmt_lock);
+ if (set_id)
+ ocfs_set_inode_lock_trans(journal, inode);
+ ocfs2_meta_unlock(inode, 1);
+ if (atomic_read(&inode->i_count) == 1)
+ LOG_ERROR_ARGS("Inode %llu, I'm doing a last iput "
+ "for!", OCFS_I(inode)->ip_blkno);
+ iput(inode);
+ kmem_cache_free(OcfsGlobalCtxt.lock_cache, lock);
}
- return;
}
#define OCFS_DEFAULT_COMMIT_INTERVAL (HZ * 5)
@@ -720,8 +617,6 @@
if (!osb)
BUG();
- spin_lock_init(&(osb->journal->cmt_lock));
-
/* already have the inode for our journal */
inode = ocfs_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE, osb->node_num);
if (inode == NULL) {
@@ -791,13 +686,9 @@
osb->journal->version = OCFS_JOURNAL_CURRENT_VERSION;
osb->journal->lockbh = bh;
atomic_set(&(osb->journal->num_trans), 0);
- atomic_set(&(osb->journal->num_cmt_locks), 0);
- atomic_set(&(osb->journal->num_chkpt_locks), 0);
init_rwsem(&(osb->journal->trans_barrier));
osb->journal->state = OCFS_JOURNAL_LOADED;
osb->journal->trans_id = (unsigned long) 1;
- INIT_LIST_HEAD(&(osb->journal->committing_inodes));
- INIT_LIST_HEAD(&(osb->journal->checkpointing_locks));
*dirty = (fe->id1.journal1.i_flags & OCFS2_JOURNAL_DIRTY_FL);
status = 0;
@@ -1518,15 +1409,12 @@
/* we can trust num_trans here because we're
* in shutdown and nobody other than ourselves
* should be able to start more. */
- if ((atomic_read(&journal->num_trans) == 0)
- && (atomic_read(&journal->num_cmt_locks) == 0))
+ if (atomic_read(&journal->num_trans) == 0)
break;
#ifdef VERBOSE_COMMIT_THREAD
- printk("(%u) commit_thread: %u transactions, %u locks"
- "pending on shutdown\n",
- current->pid,
- atomic_read(&journal->num_trans),
- atomic_read(&journal->num_cmt_locks));
+ printk("(%u) commit_thread: %u transactions pending "
+ "on shutdown\n",
+ current->pid, atomic_read(&journal->num_trans));
#endif
goto skip_sleep;
}
@@ -1535,4 +1423,3 @@
complete (&(commit->c_complete));
return 0;
}
-
Modified: branches/dlm-glue/src/ocfs.h
===================================================================
--- branches/dlm-glue/src/ocfs.h 2004-10-29 01:33:20 UTC (rev 1604)
+++ branches/dlm-glue/src/ocfs.h 2004-10-29 22:05:22 UTC (rev 1605)
@@ -211,6 +211,7 @@
unsigned int l_ro_holders;
unsigned int l_ex_holders;
dlm_lockstatus l_lksb;
+ unsigned long l_last_trans; /* protected by trans_inc_lock */
u32 l_local_seq;
/* used from AST/BAST funcs. */
@@ -293,14 +294,6 @@
__u32 ip_dir_start_lookup;
- /* ip_pending_locks and ip_j_inode are protected by the
- * journals cmt_lock.
- * ip_pending_locks: disk locks for this inode which have to be
- * released once their transaction checkpoints
- * ip_j_inode: list_head for journal->committing_inodes. */
- struct list_head ip_pending_locks;
- struct list_head ip_j_inode;
-
/* protected by trans_inc_lock, which transaction were we
* created on? Zero if none. */
unsigned long ip_created_trans;
@@ -425,7 +418,6 @@
int s_sectsize_bits;
int s_clustersize;
int s_clustersize_bits;
- int needs_flush;
struct proc_dir_entry *proc_sub_dir; /* points to /proc/fs/ocfs2/<maj_min> */
ocfs_alloc_bm cluster_bitmap;
Modified: branches/dlm-glue/src/ocfs_journal.h
===================================================================
--- branches/dlm-glue/src/ocfs_journal.h 2004-10-29 01:33:20 UTC (rev 1604)
+++ branches/dlm-glue/src/ocfs_journal.h 2004-10-29 22:05:22 UTC (rev 1605)
@@ -67,54 +67,53 @@
unsigned long trans_id;
/* locking order: trans_lock -> cmt_lock */
spinlock_t cmt_lock; /* protects the committed list */
- atomic_t num_cmt_locks; /* number of delayed
- * locks */
- atomic_t num_chkpt_locks;
struct rw_semaphore trans_barrier;
-
- struct list_head committing_inodes; /* list of all
- * inodes that
- * have committed
- * and are
- * awaiting a
- * checkpoint. Protected
- * by cmt_lock. */
- struct list_head checkpointing_locks; /* locks
- * pending release
- * after a checkpoint
- * -- this variable
- * is unlocked as
- * commit_thread is
- * the only guy who
- * looks at it! */
};
extern spinlock_t trans_inc_lock;
/* wrap trans_id so we never have it equal to zero. */
-static inline void ocfs_inc_trans_id(ocfs_journal *j)
+static inline unsigned long ocfs_inc_trans_id(ocfs_journal *j)
{
+ unsigned long old_id;
spin_lock(&trans_inc_lock);
- j->trans_id++;
+ old_id = j->trans_id++;
if (!j->trans_id)
j->trans_id = 1;
spin_unlock(&trans_inc_lock);
+ return old_id;
}
-static inline int ocfs_trans_checkpointed(ocfs_journal *j,
- unsigned long trans_id)
+static inline void ocfs_set_inode_lock_trans(ocfs_journal *journal,
+ struct inode *inode)
{
+ ocfs2_lock *lock = &OCFS_I(inode)->ip_lockres.lr_meta;
+
+ spin_lock(&trans_inc_lock);
+ lock->l_last_trans = journal->trans_id;
+ spin_unlock(&trans_inc_lock);
+}
+
+/* Used to figure out whether it's safe to drop a metadata lock on an
+ * inode. Returns true if all the inodes changes have been
+ * checkpointed to disk. You should be holding the spinlock on the
+ * metadata lock while calling this to be sure that nobody can take
+ * the lock at put it on another transaction. */
+static inline int ocfs_inode_fully_checkpointed(struct inode *inode)
+{
int ret;
+ ocfs2_lock *lock = &OCFS_I(inode)->ip_lockres.lr_meta;
+ ocfs_journal *journal = OCFS2_SB(inode->i_sb)->journal;
+
spin_lock(&trans_inc_lock);
- ret = time_after(trans_id, j->trans_id);
+ ret = time_after(journal->trans_id, lock->l_last_trans);
spin_unlock(&trans_inc_lock);
return ret;
}
-/* convenience function to check if an inode has been checkpointed
- * yet. Replaces ocfs_journal_new_file_search. Will do you a favor and
- * set created_trans = 0 when you've been checkpointed.
- * returns '1' if the inode hasn't been checkpointed yet. */
+/* convenience function to check if an inode is still new (has never
+ * hit disk) Will do you a favor and set created_trans = 0 when you've
+ * been checkpointed. returns '1' if the inode is still new. */
static inline int ocfs_inode_is_new(struct inode *inode)
{
int ret;
@@ -144,11 +143,6 @@
typedef struct _ocfs_journal_lock ocfs_journal_lock;
struct _ocfs_journal_lock {
struct inode *jl_inode;
- /* lock_list: we are either on
- * - handle->locks: if still running
- * - inode->ip_pending_locks: if waiting for checkpoint
- * - journal->checkpointing_locks: awaiting release after checkpoint
- */
struct list_head jl_lock_list;
};
Modified: branches/dlm-glue/src/proc.c
===================================================================
--- branches/dlm-glue/src/proc.c 2004-10-29 01:33:20 UTC (rev 1604)
+++ branches/dlm-glue/src/proc.c 2004-10-29 22:05:22 UTC (rev 1605)
@@ -427,18 +427,14 @@
"Volume size : %llu\n" \
"Failed Large Allocs : %u\n" \
"Retry Large Allocs : %u\n" \
- "Open Transactions: : %u\n" \
- "Delayed Locks : %u\n" \
- "Checkpointing Locks : %u\n"
+ "Open Transactions: : %u\n"
len = sprintf (page, PROC_STATS, pubmap,
osb->num_nodes, osb->s_clustersize,
ocfs2_clusters_to_bytes(osb->sb, osb->cluster_bitmap.validbits),
osb->cluster_bitmap.failed,
osb->cluster_bitmap.ok_retries,
- atomic_read(&osb->journal->num_trans),
- atomic_read(&osb->journal->num_cmt_locks),
- atomic_read(&osb->journal->num_chkpt_locks));
+ atomic_read(&osb->journal->num_trans));
ret = ocfs_proc_calc_metrics (page, start, off, count, eof, len);
Modified: branches/dlm-glue/src/super.c
===================================================================
--- branches/dlm-glue/src/super.c 2004-10-29 01:33:20 UTC (rev 1604)
+++ branches/dlm-glue/src/super.c 2004-10-29 22:05:22 UTC (rev 1605)
@@ -1094,7 +1094,6 @@
init_MUTEX (&(osb->recovery_lock));
init_MUTEX (&(osb->orphan_recovery_lock));
- osb->needs_flush = 0;
osb->disable_recovery = 0;
atomic_set (&osb->num_recovery_threads, 0);
More information about the Ocfs2-commits
mailing list