[Ocfs2-commits] mfasheh commits r957 - in trunk/src: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu May 27 20:55:35 CDT 2004
Author: mfasheh
Date: 2004-05-27 19:55:33 -0500 (Thu, 27 May 2004)
New Revision: 957
Modified:
trunk/src/alloc.c
trunk/src/file.c
trunk/src/inc/journal.h
trunk/src/inc/ocfs.h
trunk/src/inode.c
trunk/src/journal.c
trunk/src/namei.c
Log:
* Hold i_sem on inodes under change until we make our commit/abort decision.
Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c 2004-05-27 23:47:45 UTC (rev 956)
+++ trunk/src/alloc.c 2004-05-28 00:55:33 UTC (rev 957)
@@ -2681,7 +2681,7 @@
} else { /* local lock */
local_lock = 1;
- down(&bitmap_inode->i_sem);
+ ocfs_handle_add_inode(handle, bitmap_inode);
/* Get the allocation lock here */
status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
@@ -2819,13 +2819,9 @@
if (bm_lock != NULL)
OCFS_BH_PUT_DATA(bh);
- if (local_lock) {
- up (&bitmap_inode->i_sem);
+ if (local_lock && bh)
+ brelse(bh);
- if (bh != NULL)
- brelse(bh);
- }
-
if (local_inode)
iput(bitmap_inode);
@@ -2977,7 +2973,6 @@
}
newFileSize += extent;
-// bitMapSize = newFileSize / (blockSize * 8);
bitMapSize = newFileSize >> (blockSizeBits+3);
/* Does this need the buffer_head? if so, we need to
@@ -3517,7 +3512,7 @@
}
/* lock bitmap here */
- down(&main_bm_inode->i_sem);
+ ocfs_handle_add_inode(handle, main_bm_inode);
/* Get the allocation lock here */
status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
@@ -3525,7 +3520,6 @@
&main_bm_bh,
main_bm_inode);
if (status < 0) {
- up(&main_bm_inode->i_sem);
main_bm_bh = NULL;
if (status != -EINTR)
LOG_ERROR_STATUS (status);
@@ -3588,7 +3582,6 @@
bail:
/* if we locked the main bitmap, cleanup after ourselves. */
if (main_bm_bh) {
- up(&main_bm_inode->i_sem);
brelse(main_bm_bh);
}
@@ -3642,10 +3635,10 @@
if (!use_global) {
down(&osb->local_alloc_sem);
+ handle->flags |= OCFS_HANDLE_LOCAL_ALLOC;
status = ocfs_find_space_from_local(osb, bitswanted,
cluster_off, cluster_count,
handle);
- up(&osb->local_alloc_sem);
/* If we've run out of space for our local alloc, lets
* try the global one just in case... */
if (status == -ENOSPC)
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-05-27 23:47:45 UTC (rev 956)
+++ trunk/src/file.c 2004-05-28 00:55:33 UTC (rev 957)
@@ -1254,10 +1254,9 @@
goto leave;
}
- down(&ext_alloc_inode->i_sem);
+ ocfs_handle_add_inode(handle, ext_alloc_inode);
status = ocfs_allocate_extent (osb, bh, handle,
actualDiskOffset, actualLength, inode);
- up(&ext_alloc_inode->i_sem);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto leave;
Modified: trunk/src/inc/journal.h
===================================================================
--- trunk/src/inc/journal.h 2004-05-27 23:47:45 UTC (rev 956)
+++ trunk/src/inc/journal.h 2004-05-28 00:55:33 UTC (rev 957)
@@ -160,12 +160,15 @@
* created file
* sitting on this
* journal handle */
+ struct list_head inode_list;
};
/* should we checkpoint this handle on commit? */
#define OCFS_HANDLE_CHECKPOINT 1
/* should we sync-commit this handle? */
#define OCFS_HANDLE_SYNC 2
+/* was local alloc used (should we release the sem?) */
+#define OCFS_HANDLE_LOCAL_ALLOC 4
static inline void ocfs_handle_set_checkpoint(ocfs_journal_handle *handle,
int checkpoint)
@@ -250,6 +253,7 @@
* ocfs_journal_add_lock to indicate that a lock needs
* to be released at the end of that handle. Locks
* will be released in the order that they are added.
+ * ocfs_handle_add_inode - Add a locked inode to a transaction.
*/
/* You must always start_trans with a number of buffs > 0, but it's
* perfectly legal to go through an entire transaction without having
@@ -299,22 +303,16 @@
__u32 type, __u32 flags,
struct buffer_head *bh,
struct inode *inode);
-
-/*
- * Trans Lock:
- * Right now OCFS2 only supports a single transaction at a
- * time. Transactions are locked out by using trans_lock.
+/*
+ * Some transactions require us to leave inodes in a locked state
+ * until we either commit or abort because the buffer state can change
+ * in abort_trans. Use this function to lock those inodes and put them
+ * on the handle where they'll be cleaned up after the transaction
+ * completes.
*/
-#define ocfs_take_trans_lock(osb) \
- do { \
- down(&osb->trans_lock); \
- } while (0)
+void ocfs_handle_add_inode(ocfs_journal_handle *handle,
+ struct inode *inode);
-#define ocfs_release_trans_lock(osb) \
- do { \
- up (&osb->trans_lock); \
- } while (0)
-
/*
* Credit Macros:
* Convenience macros to calculate number of credits needed.
@@ -349,8 +347,6 @@
* complicated, use this function to determine how many credits are
* needed for an extend. Unfortunately, we're in bytes because the
* rest of the file system is.
- *
- * PLEASE can we fix up our include file mess so this can be a static inline?!
*/
static inline int ocfs_calc_extend_credits(__u32 bytes_wanted,
__u32 cluster_size)
Modified: trunk/src/inc/ocfs.h
===================================================================
--- trunk/src/inc/ocfs.h 2004-05-27 23:47:45 UTC (rev 956)
+++ trunk/src/inc/ocfs.h 2004-05-28 00:55:33 UTC (rev 957)
@@ -1447,6 +1447,8 @@
ocfs_lock_res i_lockres;
__u32 i_dir_start_lookup;
+
+ struct list_head handle_list;
} ocfs_inode_private;
/* Eventually, the 'flags' and 'oin_flags' fields need to be
Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c 2004-05-27 23:47:45 UTC (rev 956)
+++ trunk/src/inode.c 2004-05-28 00:55:33 UTC (rev 957)
@@ -331,6 +331,7 @@
i->open_hndl_cnt = 0;
ocfs_extent_map_init (&i->map);
INIT_LIST_HEAD(&i->recovery_list);
+ INIT_LIST_HEAD(&i->handle_list);
/* These should be set in read_inode2. */
i->alloc_size = 0ULL;
Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c 2004-05-27 23:47:45 UTC (rev 956)
+++ trunk/src/journal.c 2004-05-28 00:55:33 UTC (rev 957)
@@ -34,6 +34,21 @@
TRANS_CACHE
} release_locks_action;
+/*
+ * Trans Lock:
+ * Right now OCFS2 only supports a single transaction at a
+ * time. Transactions are locked out by using trans_lock.
+ */
+#define ocfs_take_trans_lock(osb) \
+ do { \
+ down(&osb->trans_lock); \
+ } while (0)
+
+#define ocfs_release_trans_lock(osb) \
+ do { \
+ up (&osb->trans_lock); \
+ } while (0)
+
static int ocfs_checkpoint_handle(ocfs_journal_handle *handle);
static int ocfs_revoke_handle(ocfs_journal_handle *handle);
static int ocfs_journal_toggle_mounted(ocfs_super *osb, int node_num, int value);
@@ -85,6 +100,7 @@
spin_lock_init(&(retval->list_lock));
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;
@@ -215,6 +231,52 @@
return(retval);
}
+void ocfs_handle_add_inode(ocfs_journal_handle *handle, struct inode *inode)
+{
+ if (!handle)
+ BUG();
+
+ if (!inode)
+ BUG();
+
+ if (!list_empty(&OCFS_I(inode)->handle_list)) {
+ /* I think this can happen to the main bitmap inode if
+ * we extend a regular file and also have to extend a
+ * system file in the same transaction */
+ LOG_ERROR_ARGS("Inode %lu already has a transaction!\n",
+ inode->i_ino);
+ return;
+ }
+
+ atomic_inc(&inode->i_count);
+
+ down(&inode->i_sem);
+
+ list_del(&(OCFS_I(inode)->handle_list));
+ list_add_tail(&(OCFS_I(inode)->handle_list), &(handle->inode_list));
+
+ return;
+}
+
+static void ocfs_handle_unlock_inodes(ocfs_journal_handle *handle)
+{
+ struct list_head *p, *n;
+ struct inode *inode;
+ ocfs_inode_private *ip;
+
+ list_for_each_safe(p, n, &handle->inode_list) {
+ ip = list_entry(p, ocfs_inode_private, handle_list);
+ inode = ip->inode;
+
+ list_del(&OCFS_I(inode)->handle_list);
+ INIT_LIST_HEAD(&OCFS_I(inode)->handle_list);
+
+ up(&inode->i_sem);
+ iput(inode);
+ }
+ return;
+}
+
/* This does no locking of the handle, so make sure that the handle
* isn't on journal->curr. If the handle is on journal->commited, then
* you want to be holding the commit_sem before calling this. */
@@ -442,6 +504,11 @@
commit_head = handle->commit_bits;
handle->commit_bits = NULL;
+ /* release inode semaphores we took during this transaction */
+ ocfs_handle_unlock_inodes(handle);
+ if (handle->flags | OCFS_HANDLE_LOCAL_ALLOC)
+ up(&osb->local_alloc_sem);
+
/* This has to happen after we release the other locks. */
ocfs_release_trans_lock(osb);
@@ -597,6 +664,11 @@
if (retval < 0)
LOG_ERROR_STATUS(retval);
+ /* release inode semaphores we took during this transaction */
+ ocfs_handle_unlock_inodes(handle);
+ if (handle->flags | OCFS_HANDLE_LOCAL_ALLOC)
+ up(&osb->local_alloc_sem);
+
/* This has to happen after we release the other locks. */
ocfs_release_trans_lock(osb);
@@ -1667,12 +1739,6 @@
(osb->osb_flags & OCFS_OSB_FLAGS_BEING_DISMOUNTED))
finish = 1;
- //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 && finish == 0)
Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c 2004-05-27 23:47:45 UTC (rev 956)
+++ trunk/src/namei.c 2004-05-28 00:55:33 UTC (rev 957)
@@ -327,12 +327,11 @@
goto leave;
}
- down(&inode_alloc_inode->i_sem);
+ ocfs_handle_add_inode(handle, inode_alloc_inode);
status = ocfs_alloc_node_block (osb, osb->inode_size,
&bitmapOffset, &fileOffset,
osb->node_num, DISK_ALLOC_INODE,
handle);
- up(&inode_alloc_inode->i_sem);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto leave;
More information about the Ocfs2-commits
mailing list