[Ocfs2-commits] mfasheh commits r1420 - trunk/src
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Sep 3 15:42:56 CDT 2004
Author: mfasheh
Date: 2004-09-03 15:42:54 -0500 (Fri, 03 Sep 2004)
New Revision: 1420
Modified:
trunk/src/alloc.c
trunk/src/file.c
trunk/src/inode.c
trunk/src/journal.c
trunk/src/namei.c
trunk/src/ocfs_journal.h
Log:
* allow us to take cluster locks outside of transactions. This is the
right way to do thing, and paves the way for a number of enhancements,
including less starvation potential, and fewer journal / dlm
deadlocks. We still have system files left to do.
Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c 2004-09-03 20:41:38 UTC (rev 1419)
+++ trunk/src/alloc.c 2004-09-03 20:42:54 UTC (rev 1420)
@@ -341,7 +341,7 @@
/* start the transaction here to preserve ordering with the
* bitmap io_sems... */
- handle = ocfs_start_trans(osb, credits);
+ handle = ocfs_start_trans(osb, NULL, credits);
if (!handle) {
status = -ENOMEM;
LOG_ERROR_STATUS(status);
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-09-03 20:41:38 UTC (rev 1419)
+++ trunk/src/file.c 2004-09-03 20:42:54 UTC (rev 1420)
@@ -424,7 +424,6 @@
{
int status = 0;
ocfs2_dinode *fileEntry = NULL;
- u32 lock_flags = 0;
struct buffer_head *bh = NULL;
ocfs_journal_handle *handle = NULL;
@@ -436,21 +435,29 @@
}
#endif
- /* Start a transaction - need a minimal amount of block credits (1) */
- handle = ocfs_start_trans(osb, 1);
+ handle = ocfs_alloc_handle(osb);
if (handle == NULL) {
LOG_ERROR_STATUS(status);
goto leave;
}
- status = ocfs_acquire_lock (osb, OCFS_LKM_EXMODE, lock_flags,
- &bh, inode);
+ status = ocfs_acquire_lock (osb, OCFS_LKM_EXMODE, 0, &bh, inode);
if (status < 0) {
if (status != -EINTR)
LOG_ERROR_STATUS (status);
goto leave;
}
+ ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, FLAG_FILE_UPDATE_OIN,
+ inode);
+
+ /* Start a transaction - need a minimal amount of block credits (1) */
+ handle = ocfs_start_trans(osb, handle, 1);
+ if (handle == NULL) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
fileEntry = (ocfs2_dinode *) bh->b_data;
if (!IS_VALID_FILE_ENTRY(fileEntry)) {
@@ -481,12 +488,6 @@
leave:
if (handle) {
- if (!status)
- lock_flags |= FLAG_FILE_UPDATE_OIN;
-
- ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE,
- lock_flags, inode);
-
if (status < 0)
ocfs_abort_trans(handle);
else
@@ -863,8 +864,7 @@
LOG_TRACE_ARGS("new_alloc_size = %llu\n", new_alloc_size);
- /* start a journal transaction */
- handle = ocfs_start_trans(osb, OCFS_FILE_TRUNCATE_CREDITS);
+ handle = ocfs_alloc_handle(osb);
if (handle == NULL) {
LOG_ERROR_STATUS (status = -ENOMEM);
goto leave;
@@ -889,6 +889,12 @@
goto leave;
}
+ handle = ocfs_start_trans(osb, handle, OCFS_FILE_TRUNCATE_CREDITS);
+ if (handle == NULL) {
+ LOG_ERROR_STATUS (status = -ENOMEM);
+ goto leave;
+ }
+
/* add this fe to the journal transaction */
status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
if (status < 0) {
@@ -1062,8 +1068,7 @@
credits = ocfs_calc_extend_credits(osb->sb,
(__u32) alloc_size);
- /* cannot call start_trans with a locked buffer head. */
- handle = ocfs_start_trans(osb, credits);
+ handle = ocfs_alloc_handle(osb);
if (handle == NULL) {
LOG_ERROR_STATUS(status = -ENOMEM);
goto leave;
@@ -1080,6 +1085,12 @@
OCFS_LKM_EXMODE,
FLAG_FILE_EXTEND|FLAG_FILE_UPDATE_OIN,
inode);
+
+ handle = ocfs_start_trans(osb, handle, credits);
+ if (handle == NULL) {
+ LOG_ERROR_STATUS(status = -ENOMEM);
+ goto leave;
+ }
} else {
handle = passed_handle;
}
Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c 2004-09-03 20:41:38 UTC (rev 1419)
+++ trunk/src/inode.c 2004-09-03 20:42:54 UTC (rev 1420)
@@ -604,27 +604,6 @@
goto clear_inode;
}
- lock_kernel();
-
- /* Oop, lets be carefull of lock / trans ordering here... */
- handle = ocfs_start_trans(osb, OCFS_FILE_DELETE_CREDITS);
- if (handle == NULL) {
- unlock_kernel();
- LOG_ERROR_STATUS(-ENOMEM);
- goto clear_inode;
- }
-
- ocfs_handle_add_inode(handle, orphan_dir_inode);
-
- status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, FLAG_DIR,
- &orphan_dir_bh, orphan_dir_inode);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- goto bail_locked;
- }
- ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, FLAG_DIR,
- orphan_dir_inode);
-
/* acquire_lock and friends will igrab / iput this guy, so we
* take an extra ref. to avoid recursive calls to
* delete_inode. */
@@ -641,30 +620,51 @@
* about deleting it. */
if (status != -EBUSY)
LOG_ERROR_STATUS(status);
- goto bail_locked;
+ goto clear_inode;
}
- /* check OCFS_SYNC_FLAG_ORPHANED */
fe = (ocfs2_dinode *) fe_bh->b_data;
if (!(fe->i_flags & OCFS2_ORPHANED_FL)) {
/* for lack of a better error? */
status = -EEXIST;
LOG_ERROR_STATUS(status);
- goto bail_locked;
+ goto clear_inode;
}
/* has someone already deleted us?! baaad... */
if (fe->i_dtime) {
status = -EEXIST;
LOG_ERROR_STATUS(status);
- goto bail_locked;
+ goto clear_inode;
}
if (fe->i_links_count) {
status = -EBUSY;
LOG_ERROR_STATUS(status);
+ goto clear_inode;
+ }
+
+ /* Oop, lets be carefull of lock / trans ordering here... */
+ handle = ocfs_start_trans(osb, NULL, OCFS_FILE_DELETE_CREDITS);
+ if (handle == NULL) {
+ unlock_kernel();
+ LOG_ERROR_STATUS(-ENOMEM);
+ goto clear_inode;
+ }
+
+ ocfs_handle_add_inode(handle, orphan_dir_inode);
+
+ lock_kernel();
+
+ status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, FLAG_DIR,
+ &orphan_dir_bh, orphan_dir_inode);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
goto bail_locked;
}
+ ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, FLAG_DIR,
+ orphan_dir_inode);
+
status = ocfs_orphan_del(osb, handle, orphan_dir_inode, inode,
orphan_dir_bh);
@@ -706,13 +706,14 @@
unlock_kernel();
+clear_inode:
if (orphan_dir_bh)
brelse(orphan_dir_bh);
if (fe_bh)
brelse(fe_bh);
+ if (orphan_dir_inode)
+ iput(orphan_dir_inode);
- iput(orphan_dir_inode);
-clear_inode:
/* we must clear inode. */
clear_inode(inode);
LOG_EXIT();
Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c 2004-09-03 20:41:38 UTC (rev 1419)
+++ trunk/src/journal.c 2004-09-03 20:42:54 UTC (rev 1420)
@@ -66,6 +66,7 @@
static void ocfs_handle_move_locks(ocfs_journal *journal,
ocfs_journal_handle *handle);
static void ocfs_journal_optimize_lock_list(ocfs_journal *journal);
+static void ocfs_commit_unstarted_handle(ocfs_journal_handle *handle);
static void ocfs_journal_optimize_lock_list(ocfs_journal *journal)
{
@@ -152,6 +153,8 @@
static int ocfs_commit_cache(ocfs_super *osb)
{
int status = 0, tmpstat;
+ unsigned int flushed = 0;
+ unsigned int cmt_locks;
ocfs_journal * journal = NULL;
struct list_head *p, *n;
ocfs_journal_lock *lock = NULL;
@@ -167,15 +170,17 @@
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!");
- goto finally;
+ /* now, we may have locks left to drop even though no
+ * transactions are in the journal. */
+
+ goto drop_locks;
}
journal_lock_updates(journal->k_journal);
status = journal_flush(journal->k_journal);
+ journal_unlock_updates(journal->k_journal);
if (status < 0) {
- journal_unlock_updates(journal->k_journal);
up_write(&journal->trans_barrier);
LOG_ERROR_STATUS(status);
goto finally;
@@ -183,19 +188,18 @@
ocfs_inc_trans_id(journal);
-#ifdef VERBOSE_COMMIT_THREAD
- printk("(%u) commit_thread: flushed %u transactions, releasing %u "
- "locks\n", current->pid, atomic_read(&journal->num_trans),
- atomic_read(&journal->num_cmt_locks));
-#endif
+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);
+ &journal->num_chkpt_locks);
atomic_set(&journal->num_cmt_locks, 0);
/* move the locks off each inode onto the commit threads list. */
@@ -221,13 +225,21 @@
* Once we've got cmt_lock, we can let
* transactions start again -- it should protect us against
* people mucking with the committed list... */
- journal_unlock_updates(journal->k_journal);
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);
+#endif
+
ocfs_journal_optimize_lock_list(journal);
#ifdef VERBOSE_COMMIT_THREAD
- printk("(%u) commit_thread: after optimization, %u locks to release\n",
- current->pid, atomic_read(&journal->num_chkpt_locks));
+ 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;
@@ -370,9 +382,42 @@
ocfs_journal_get_undo_access(handle, bh)
#endif
-ocfs_journal_handle * ocfs_start_trans(ocfs_super *osb, int max_buffs)
+ocfs_journal_handle * ocfs_alloc_handle(ocfs_super *osb)
{
ocfs_journal_handle * retval = NULL;
+
+ retval = ocfs_malloc(sizeof(*retval));
+ if (!retval) {
+ LOG_ERROR_STR("Failed to allocate memory for journal handle!");
+ return(NULL);
+ }
+ memset(retval, 0, sizeof(*retval));
+
+ retval->max_buffs = 0;
+ retval->num_buffs = 0;
+ retval->num_locks = 0;
+ retval->num_co = 0;
+ retval->commit_bits = NULL;
+ retval->buffs = NULL;
+ retval->co_buffs = NULL;
+ retval->k_handle = NULL;
+
+ INIT_LIST_HEAD(&(retval->h_list));
+ INIT_LIST_HEAD(&(retval->locks));
+ INIT_LIST_HEAD(&(retval->inode_list));
+ retval->journal = osb->journal;
+ retval->osb = osb;
+
+ return(retval);
+}
+
+/* pass it NULL and it will allocate a new handle object for you. If
+ * you pass it a handle however, it may still return NULL, in which
+ * case it has free'd the passed handle for you. */
+ocfs_journal_handle * ocfs_start_trans(ocfs_super *osb,
+ ocfs_journal_handle *handle,
+ int max_buffs)
+{
journal_t * journal = osb->journal->k_journal;
LOG_ENTRY_ARGS ("(max_buffs = %d)\n", max_buffs);
@@ -388,63 +433,56 @@
BUG();
}
- retval = ocfs_malloc(sizeof(*retval));
- if (!retval) {
+ if (!handle)
+ handle = ocfs_alloc_handle(osb);
+ if (!handle) {
LOG_ERROR_STR("Failed to allocate memory for journal handle!");
goto done_free;
}
- memset(retval, 0, sizeof(*retval));
- retval->buffs = ocfs_malloc(sizeof(struct buffer_head *) * max_buffs);
- if (!retval->buffs) {
+ handle->buffs = ocfs_malloc(sizeof(struct buffer_head *) * max_buffs);
+ if (!handle->buffs) {
LOG_ERROR_STR("Failed to allocate memory for journal buffs!");
goto done_free;
}
- memset(retval->buffs, 0, sizeof(struct buffer_head *) * max_buffs);
+ memset(handle->buffs, 0, sizeof(struct buffer_head *) * max_buffs);
- retval->co_buffs = ocfs_malloc(sizeof(ocfs_journal_copyout)*max_buffs);
- if (!retval->co_buffs) {
+ handle->co_buffs = ocfs_malloc(sizeof(ocfs_journal_copyout)*max_buffs);
+ if (!handle->co_buffs) {
LOG_ERROR_STR("Failed to allocate memory for journal co_buffs!");
goto done_free;
}
- memset(retval->co_buffs, 0, sizeof(ocfs_journal_copyout) * max_buffs);
+ memset(handle->co_buffs, 0, sizeof(ocfs_journal_copyout) * max_buffs);
- INIT_LIST_HEAD(&(retval->h_list));
- INIT_LIST_HEAD(&(retval->locks));
- INIT_LIST_HEAD(&(retval->inode_list));
- retval->max_buffs = max_buffs;
- retval->num_buffs = 0;
- retval->num_locks = 0;
- retval->num_co = 0;
+ handle->max_buffs = max_buffs;
- retval->journal = osb->journal;
- retval->osb = osb;
- retval->commit_bits = NULL;
-
down_read(&osb->journal->trans_barrier);
/* actually start the transaction now */
- retval->k_handle = journal_start(journal, max_buffs);
- if (IS_ERR(retval->k_handle)) {
+ handle->k_handle = journal_start(journal, max_buffs);
+ if (IS_ERR(handle->k_handle)) {
up_read(&osb->journal->trans_barrier);
LOG_ERROR_STR("journal_start() failed!");
- LOG_ERROR_STATUS((int)PTR_ERR(retval->k_handle));
- retval->k_handle = NULL;
+ LOG_ERROR_STATUS((int)PTR_ERR(handle->k_handle));
+ handle->k_handle = NULL;
goto done_free;
}
atomic_inc(&(osb->journal->num_trans));
+ handle->flags |= OCFS_HANDLE_STARTED;
- LOG_EXIT_PTR(retval);
- return(retval);
+ LOG_EXIT_PTR(handle);
+ return(handle);
done_free:
- if (retval) {
- if (retval->buffs)
- kfree(retval->buffs);
- kfree(retval);
+ if (handle) {
+ ocfs_commit_unstarted_handle(handle);
+
+ if (handle->buffs)
+ kfree(handle->buffs);
+ kfree(handle);
}
LOG_EXIT_PTR(NULL);
return(NULL);
@@ -452,12 +490,10 @@
void ocfs_handle_add_inode(ocfs_journal_handle *handle, struct inode *inode)
{
- if (!handle)
- BUG();
+ OCFS_ASSERT(handle);
+ OCFS_ASSERT(inode);
+ OCFS_ASSERT((handle->flags & OCFS_HANDLE_STARTED));
- if (!inode)
- BUG();
-
if (OCFS_I(inode)->ip_handle == handle) {
/* sanity check */
if (list_empty(&OCFS_I(inode)->ip_handle_list))
@@ -522,6 +558,32 @@
} \
} while (0)
+/* This is trivial so we do it out of the main commit/abort
+ * paths. Beware, it can be called from start_trans too! */
+static void ocfs_commit_unstarted_handle(ocfs_journal_handle *handle)
+{
+ ocfs_super *osb;
+
+ LOG_ENTRY();
+
+ OCFS_ASSERT(!(handle->flags & OCFS_HANDLE_STARTED));
+ OCFS_ASSERT(!handle->commit_bits);
+ OCFS_ASSERT(!handle->num_co);
+ OCFS_ASSERT(!handle->num_buffs);
+
+ osb = handle->osb;
+ /* You are allowed to add journal locks before the transaction
+ * has started. */
+ ocfs_handle_move_locks(osb->journal, handle);
+ spin_lock(&osb->journal->cmt_lock);
+ osb->needs_flush = 1;
+ spin_unlock(&osb->journal->cmt_lock);
+
+ kfree(handle);
+ LOG_EXIT();
+ return;
+}
+
/*
* ocfs_commit_trans
*/
@@ -535,9 +597,13 @@
ocfs_bitmap_free_head *commit_head;
LOG_ENTRY();
- if (!handle)
- BUG();
+ OCFS_ASSERT(handle);
+ if (!(handle->flags & OCFS_HANDLE_STARTED)) {
+ ocfs_commit_unstarted_handle(handle);
+ goto bail;
+ }
+
osb = handle->osb;
kern_handle = handle->k_handle;
kern_trans = kern_handle->h_transaction;
@@ -597,6 +663,7 @@
kfree(handle);
+bail:
LOG_EXIT();
return;
@@ -622,6 +689,11 @@
OCFS_ASSERT(handle);
OCFS_ASSERT(!(handle->flags & OCFS_HANDLE_ALWAYS_COMMITS));
+ if (!(handle->flags & OCFS_HANDLE_STARTED)) {
+ ocfs_commit_unstarted_handle(handle);
+ goto bail;
+ }
+
osb = handle->osb;
journal = osb->journal;
@@ -724,6 +796,7 @@
kfree(handle->buffs);
kfree(handle);
+bail:
LOG_EXIT();
return;
} /* ocfs_abort_trans */
@@ -737,6 +810,8 @@
int i;
int found = 0;
+ OCFS_ASSERT((handle->flags & OCFS_HANDLE_STARTED));
+
LOG_ENTRY_ARGS("(bh->b_blocknr=%llu, type=%d (\"%s\"), "
"bh->b_size = %hu)\n",
(unsigned long long)bh->b_blocknr, type,
@@ -855,6 +930,8 @@
int status = -1;
int i;
+ OCFS_ASSERT((handle->flags & OCFS_HANDLE_STARTED));
+
LOG_ENTRY_ARGS("(bh->b_blocknr=%llu)\n",
(unsigned long long)bh->b_blocknr);
@@ -940,7 +1017,9 @@
list_add_tail(&(lock->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);
LOG_EXIT();
return;
@@ -1728,7 +1807,6 @@
static int ocfs_wait_on_mount(ocfs_super *osb)
{
-
retry:
if (atomic_read(&osb->vol_state) == VOLUME_MOUNTED)
return 0;
@@ -1858,12 +1936,15 @@
/* 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)
+ if ((atomic_read(&journal->num_trans) == 0)
+ && (atomic_read(&journal->num_cmt_locks) == 0))
break;
#ifdef VERBOSE_COMMIT_THREAD
- printk("(%u) commit_thread: %u transactions pending "
- "on shutdown\n",
- current->pid, atomic_read(&journal->num_trans));
+ 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));
#endif
goto skip_sleep;
}
Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c 2004-09-03 20:41:38 UTC (rev 1419)
+++ trunk/src/namei.c 2004-09-03 20:42:54 UTC (rev 1420)
@@ -231,8 +231,7 @@
goto leave;
}
- /* start the transaction */
- handle = ocfs_start_trans(osb, OCFS_MKNOD_CREDITS);
+ handle = ocfs_alloc_handle(osb);
if (handle == NULL) {
LOG_ERROR_STATUS (status = -ENOMEM);
goto leave;
@@ -257,6 +256,12 @@
goto leave;
}
+ handle = ocfs_start_trans(osb, handle, OCFS_MKNOD_CREDITS);
+ if (handle == NULL) {
+ LOG_ERROR_STATUS (status = -ENOMEM);
+ goto leave;
+ }
+
/* do the real work now. */
status = ocfs_mknod_locked(osb, dir, dentry, mode, dev,
&new_fe_bh, parent_fe_bh, handle, inode);
@@ -354,9 +359,8 @@
else if (status < 0 && status != -EINTR)
LOG_ERROR_STATUS(status);
- if (new_fe_bh) {
+ if (new_fe_bh)
brelse(new_fe_bh);
- }
if (parent_fe_bh != NULL)
brelse(parent_fe_bh);
@@ -582,13 +586,11 @@
goto bail;
}
- /* mknod credits is a bit heavy, but we can tune this later. */
- handle = ocfs_start_trans(osb, OCFS_MKNOD_CREDITS);
+ handle = ocfs_alloc_handle(osb);
if (handle == NULL) {
err = -ENOMEM;
goto bail;
}
- ocfs_handle_set_always_commits(handle, 1);
down_write(&OCFS_I(dir)->ip_io_sem);
drop_dir_sem = 1;
@@ -619,6 +621,14 @@
goto bail;
}
+ /* mknod credits is a bit heavy, but we can tune this later. */
+ handle = ocfs_start_trans(osb, handle, OCFS_MKNOD_CREDITS);
+ if (handle == NULL) {
+ err = -ENOMEM;
+ goto bail;
+ }
+ ocfs_handle_set_always_commits(handle, 1);
+
err = ocfs_journal_access(handle, fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
if (err < 0) {
LOG_ERROR_STATUS(err);
@@ -703,17 +713,16 @@
status = -EPERM;
goto bail;
}
- status = -EFAIL;
- down_write(&OCFS_I(dir)->ip_io_sem);
- down_write(&OCFS_I(inode)->ip_io_sem);
-
- handle = ocfs_start_trans(osb, OCFS_FILE_DELETE_CREDITS);
+ handle = ocfs_alloc_handle(osb);
if (handle == NULL) {
LOG_ERROR_STATUS (status = -ENOMEM);
- goto leave;
+ goto bail;
}
+ down_write(&OCFS_I(dir)->ip_io_sem);
+ down_write(&OCFS_I(inode)->ip_io_sem);
+
status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, FLAG_DIR,
&parent_node_bh, parentInode);
if (status < 0) {
@@ -755,6 +764,12 @@
}
}
+ handle = ocfs_start_trans(osb, handle, OCFS_FILE_DELETE_CREDITS);
+ if (handle == NULL) {
+ LOG_ERROR_STATUS (status = -ENOMEM);
+ goto leave;
+ }
+
status = ocfs_journal_access(handle, fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
if (status < 0) {
LOG_ERROR_STATUS (status);
@@ -763,7 +778,8 @@
fe = (ocfs2_dinode *) fe_bh->b_data;
if (fe->i_links_count != inode->i_nlink) {
- printk("ocfs_unlink: hmm, inode has nlink = %u, fe has link_cnt = %u. Setting inode from fe.\n",
+ printk("ocfs_unlink: hmm, inode has nlink = %u, fe has "
+ "link_cnt = %u. Setting inode from fe.\n",
inode->i_nlink, fe->i_links_count);
inode->i_nlink = fe->i_links_count;
}
@@ -1017,8 +1033,7 @@
goto bail;
}
- /* start our transaction */
- handle = ocfs_start_trans(osb, OCFS_FILE_RENAME_CREDITS);
+ handle = ocfs_alloc_handle(osb);
if (handle == NULL) {
LOG_ERROR_STATUS(status = -ENOMEM);
goto bail;
@@ -1161,7 +1176,15 @@
"new_blkno=%llu newfebh=%p bhblocknr=%llu\n",
new_de, newfe_blkno, newfe_bh, newfe_bh ?
(unsigned long long)newfe_bh->b_blocknr : 0ULL);
+ }
+ handle = ocfs_start_trans(osb, handle, OCFS_FILE_RENAME_CREDITS);
+ if (handle == NULL) {
+ LOG_ERROR_STATUS(status = -ENOMEM);
+ goto bail;
+ }
+
+ if (new_de) {
status = ocfs_journal_access(handle, newfe_bh,
OCFS_JOURNAL_ACCESS_WRITE);
if (status < 0) {
@@ -1212,7 +1235,6 @@
LOG_ERROR_STATUS(status);
goto finally;
}
-
} else {
/* if the name was not found in new_dir, add it now */
status = ocfs_add_entry (handle, new_dentry, old_inode,
@@ -1498,8 +1520,7 @@
credits = ocfs_calc_symlink_credits(sb, newsize);
- /* start the transaction */
- handle = ocfs_start_trans(osb, credits);
+ handle = ocfs_alloc_handle(osb);
if (handle == NULL) {
LOG_ERROR_STATUS (status = -ENOMEM);
goto bail;
@@ -1523,6 +1544,12 @@
goto abort_trans;
}
+ handle = ocfs_start_trans(osb, handle, credits);
+ if (handle == NULL) {
+ LOG_ERROR_STATUS (status = -ENOMEM);
+ goto bail;
+ }
+
status = ocfs_mknod_locked(osb, dir, dentry,
S_IFLNK | S_IRWXUGO, 0,
&new_fe_bh, parent_fe_bh, handle,
Modified: trunk/src/ocfs_journal.h
===================================================================
--- trunk/src/ocfs_journal.h 2004-09-03 20:41:38 UTC (rev 1419)
+++ trunk/src/ocfs_journal.h 2004-09-03 20:42:54 UTC (rev 1420)
@@ -212,13 +212,14 @@
struct list_head inode_list;
};
+#define OCFS_HANDLE_STARTED 1
/* should we sync-commit this handle? */
-#define OCFS_HANDLE_SYNC 1
+#define OCFS_HANDLE_SYNC 2
/* This is really the right way to do things, but until we fix all the
* code, it's a performance improvement for a handle which never
* aborts. Should be set before passing any buffers to
* journal_access! */
-#define OCFS_HANDLE_ALWAYS_COMMITS 2
+#define OCFS_HANDLE_ALWAYS_COMMITS 4
static inline void ocfs_handle_free_all_copyout(ocfs_journal_handle *handle)
{
@@ -289,12 +290,18 @@
/*
* Transaction Handling:
* Manage the lifetime of a transaction handle.
- *
+ *
+ * ocfs_alloc_handle - Only allocate a handle so we can start putting
+ * cluster locks on it. To actually change blocks,
+ * call ocfs_start_trans with the handle returned
+ * from this function. You may call ocfs_commit_trans
+ * and ocfs_abort_trans at any time in the lifetime
+ * of a handle.
* ocfs_start_trans - Begin a transaction. Give it an upper estimate of
* the number of blocks that will be changed during
* this handle.
* ocfs_commit_trans - Complete a handle.
- * ocfs_abort_trans - Abort a running handle.
+ * ocfs_abort_trans - Abort a handle.
* ocfs_journal_access - Notify the handle that we want to journal this
* buffer. Will have to call ocfs_journal_dirty once
* we've actually dirtied it. Type is one of . or .
@@ -309,7 +316,10 @@
/* You must always start_trans with a number of buffs > 0, but it's
* perfectly legal to go through an entire transaction without having
* dirtied any buffers. */
-ocfs_journal_handle *ocfs_start_trans(struct _ocfs_super *osb, int max_buffs);
+ocfs_journal_handle *ocfs_alloc_handle(ocfs_super *osb);
+ocfs_journal_handle *ocfs_start_trans(struct _ocfs_super *osb,
+ ocfs_journal_handle *handle,
+ int max_buffs);
void ocfs_commit_trans(ocfs_journal_handle *handle);
void ocfs_abort_trans(ocfs_journal_handle *handle);
/*
More information about the Ocfs2-commits
mailing list