[Ocfs2-commits] mfasheh commits r864 - in trunk/src: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Apr 23 14:23:24 CDT 2004
Author: mfasheh
Date: 2004-04-23 13:23:23 -0500 (Fri, 23 Apr 2004)
New Revision: 864
Modified:
trunk/src/alloc.c
trunk/src/dlm.c
trunk/src/file.c
trunk/src/inc/journal.h
trunk/src/journal.c
trunk/src/namei.c
trunk/src/nm.c
trunk/src/oin.c
Log:
* ocfs_journal_add_lock: don't take "id" as a parameter anymore. We'll use
lockres->sector_num in ocfs_journal_release_locks instead. This avoids a
race with rename. ocfs_search_committed had to also be changed to avoid
using the "id" parameter off the ocfs_journal_lock struct.
* Create an ugly, racy, no good hack in ocfs_rename to change
lockres->sector_num and to remove buffer heads from the journal delayed
lock list. This will be fixed properly shortly as lockres is merged onto
inode.
* Get rid of the OCFS_OIN_IN_USE flag as it's not really used in any
meaningfull way.
Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c 2004-04-22 19:46:12 UTC (rev 863)
+++ trunk/src/alloc.c 2004-04-23 18:23:23 UTC (rev 864)
@@ -3110,8 +3110,7 @@
ocfs_uninitialize_bitmap(&bitmap);
if (bLockAcquired && delay_lockrel) {
- ocfs_journal_add_lock(handle, lockId,
- OCFS_DLM_EXCLUSIVE_LOCK,
+ ocfs_journal_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE,
lockres, bh, NULL);
tmpstat = 0;
Modified: trunk/src/dlm.c
===================================================================
--- trunk/src/dlm.c 2004-04-22 19:46:12 UTC (rev 863)
+++ trunk/src/dlm.c 2004-04-23 18:23:23 UTC (rev 864)
@@ -814,9 +814,8 @@
lockres->lock_holders++;
#warning I hope these lock flags are alright.
ocfs_get_lockres(lockres);
- ocfs_journal_add_lock(handle, lockres->sector_num,
- lockres->lock_type, 0, lockres,
- *bh, inode);
+ ocfs_journal_add_lock(handle, lockres->lock_type, 0,
+ lockres, *bh, inode);
} else
status = ocfs_write_bh (osb, *bh, 0, inode);
if (status < 0)
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-04-22 19:46:12 UTC (rev 863)
+++ trunk/src/file.c 2004-04-23 18:23:23 UTC (rev 864)
@@ -94,7 +94,6 @@
int mode = file->f_flags;
ocfs_super *osb = NULL;
bool bAcquiredOIN = false;
- bool bClearInUse = false;
struct buffer_head *fe_bh = NULL;
ocfs_sem *oin_sem = NULL;
int truncate_pages = 0;
@@ -119,11 +118,8 @@
/* If the in use flag is set, forget about it. This will go
* eventually. */
- if (!(OCFS_I(inode)->oin_flags & OCFS_OIN_IN_TEARDOWN) &&
- !(OCFS_I(inode)->oin_flags & OCFS_OIN_DELETE_ON_CLOSE)) {
- OCFS_SET_FLAG (OCFS_I(inode)->oin_flags, OCFS_OIN_IN_USE);
- bClearInUse = true;
- } else {
+ if ((OCFS_I(inode)->oin_flags & OCFS_OIN_IN_TEARDOWN) ||
+ (OCFS_I(inode)->oin_flags & OCFS_OIN_DELETE_ON_CLOSE)) {
if (OCFS_I(inode)->oin_flags & OCFS_OIN_IN_TEARDOWN)
LOG_ERROR_STR ("oin in teardown");
else
@@ -155,7 +151,6 @@
}
goto leave;
}
- bClearInUse = true;
status = ocfs_inode_fill_ext_map (osb, fe_bh, inode);
if (status < 0) {
@@ -221,11 +216,6 @@
OCFS_I(inode)->open_hndl_cnt++;
- /* We should clear the in use now as we are safe from the case */
- /* where the voting thread can vote and we have an open in */
- /* progress */
- OCFS_CLEAR_FLAG (OCFS_I(inode)->oin_flags, OCFS_OIN_IN_USE);
-
if (bAcquiredOIN) {
ocfs_up_sem (oin_sem);
bAcquiredOIN = false;
@@ -244,20 +234,6 @@
status = 0;
leave:
- if (bClearInUse) {
- if (!bAcquiredOIN && oin_sem) {
- ocfs_down_sem (oin_sem, true);
- bAcquiredOIN = true;
- }
-
- OCFS_CLEAR_FLAG (OCFS_I(inode)->oin_flags, OCFS_OIN_IN_USE);
-
- if (bAcquiredOIN && oin_sem) {
- ocfs_up_sem (oin_sem);
- bAcquiredOIN = false;
- }
- }
-
if (bAcquiredOIN && oin_sem) {
ocfs_up_sem (oin_sem);
bAcquiredOIN = false;
@@ -353,8 +329,7 @@
if (OCFS_I(inode)->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO)
OCFS_CLEAR_FLAG(OCFS_I(inode)->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
- if (OCFS_I(inode)->oin_flags & OCFS_OIN_NEEDS_DELETION ||
- OCFS_I(inode)->oin_flags & OCFS_OIN_IN_USE) {
+ if (OCFS_I(inode)->oin_flags & OCFS_OIN_NEEDS_DELETION) {
ocfs_up_sem (&(OCFS_I(inode)->main_res));
LOG_ERROR_STR("Not deleting lockrse on a last close! eek!");
goto bail;
@@ -547,7 +522,7 @@
if (status < 0) {
ocfs_abort_trans(handle);
} else {
- ocfs_journal_add_lock(handle, lockId, locktype, lockFlags,
+ ocfs_journal_add_lock(handle, locktype, lockFlags,
lockres, bh, inode);
bAcquiredLock = false;
@@ -1191,7 +1166,7 @@
if (bFileLockAcquired)
lockFlags |= FLAG_FILE_UPDATE_OIN;
- ocfs_journal_add_lock(handle, lockId, locktype,
+ ocfs_journal_add_lock(handle, locktype,
lockFlags, lockres,
bh, inode);
bAcquiredLock = false;
Modified: trunk/src/inc/journal.h
===================================================================
--- trunk/src/inc/journal.h 2004-04-22 19:46:12 UTC (rev 863)
+++ trunk/src/inc/journal.h 2004-04-23 18:23:23 UTC (rev 864)
@@ -94,7 +94,6 @@
typedef struct _ocfs_journal_lock ocfs_journal_lock;
struct _ocfs_journal_lock {
- __u64 id;
__u32 type;
__u32 flags;
struct _ocfs_lock_res * res;
@@ -329,7 +328,7 @@
int ocfs_journal_dirty(ocfs_journal_handle *handle,
struct buffer_head *bh);
void ocfs_journal_add_lock(ocfs_journal_handle *handle,
- __u64 id, __u32 type, __u32 flags,
+ __u32 type, __u32 flags,
struct _ocfs_lock_res *lockres,
struct buffer_head *bh,
struct inode *inode);
Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c 2004-04-22 19:46:12 UTC (rev 863)
+++ trunk/src/journal.c 2004-04-23 18:23:23 UTC (rev 864)
@@ -222,6 +222,7 @@
int status = 0;
int tmpstat;
struct list_head *p, *n;
+ __u64 id;
LOG_ENTRY();
@@ -235,15 +236,25 @@
list_for_each_safe(p, n, &(handle->locks)) {
lock = list_entry(p, ocfs_journal_lock, lock_list);
- tmpstat = ocfs_release_lock(osb, lock->id, lock->type,
- lock->flags, lock->res,
- (abort ? NULL : lock->bh),
- lock->inode);
- if (tmpstat < 0) {
- LOG_ERROR_ARGS("Could not release lock %u.%u\n",
- HILO(lock->id));
- LOG_ERROR_STATUS(tmpstat);
- status = tmpstat;
+ id = lock->res->sector_num;
+
+ /* The file may have been deleted before we got to
+ * this lock release. If so, just skip it.
+ * *** This test of the deleted flag is not locked!!! */
+ if ((!lock->inode)
+ || (lock->inode && !INODE_DELETED(lock->inode))) {
+
+ tmpstat = ocfs_release_lock(osb, lock->res->sector_num,
+ lock->type,
+ lock->flags, lock->res,
+ (abort ? NULL : lock->bh),
+ lock->inode);
+ if (tmpstat < 0) {
+ LOG_ERROR_ARGS("Could not release lock: "
+ "%u.%u\n", HILO(id));
+ LOG_ERROR_STATUS(tmpstat);
+ status = tmpstat;
+ }
}
ocfs_put_lockres(lock->res);
if (lock->bh != NULL)
@@ -769,14 +780,15 @@
/* We are expecting to be run on the current running transaction, so
* we use the spin_lock here. You really shouldn't be calling this on
* other transactions anyway... */
-void ocfs_journal_add_lock(ocfs_journal_handle *handle, __u64 id, __u32 type,
+void ocfs_journal_add_lock(ocfs_journal_handle *handle, __u32 type,
__u32 flags, struct _ocfs_lock_res *lockres,
struct buffer_head *bh, struct inode *inode)
{
ocfs_journal_lock *lock;
LOG_ENTRY_ARGS("(id=%u.%u, type=%u, flags=%u, res=0x%08x, "
- "bh=0x%08x)\n", HILO(id), type, flags, lockres, bh);
+ "bh=0x%08x)\n", HILO(lockres->sector_num), type, flags,
+ lockres, bh);
lock = ocfs_malloc(sizeof(ocfs_journal_lock));
if (lock == NULL) {
@@ -786,7 +798,6 @@
BUG();
}
- lock->id = id;
lock->type = type;
lock->flags = flags;
lock->res = lockres;
Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c 2004-04-22 19:46:12 UTC (rev 863)
+++ trunk/src/namei.c 2004-04-23 18:23:23 UTC (rev 864)
@@ -219,9 +219,9 @@
}
/* Ok, we got the lock -- we'd better add it to our transaction */
- ocfs_journal_add_lock(handle, parent_off,
- OCFS_DLM_ENABLE_CACHE_LOCK,
- FLAG_FILE_CREATE | FLAG_DIR, lockres, lock_bh, dir);
+ ocfs_journal_add_lock(handle, OCFS_DLM_ENABLE_CACHE_LOCK,
+ FLAG_FILE_CREATE | FLAG_DIR, lockres, lock_bh,
+ dir);
/* do the real work now. */
status = ocfs_mknod_locked(osb, dir, dentry, mode, dev, lock_bh,
@@ -617,7 +617,6 @@
ocfs_down_sem (&(OCFS_I(inode)->main_res), true);
OCFS_CLEAR_FLAG (OCFS_I(inode)->oin_flags, OCFS_OIN_DELETE_ON_CLOSE);
- OCFS_CLEAR_FLAG (OCFS_I(inode)->oin_flags, OCFS_OIN_IN_USE);
ocfs_up_sem (&(OCFS_I(inode)->main_res));
goto bail;
}
@@ -744,9 +743,9 @@
}
} else if (handle) {
if (id2_locked)
- ocfs_journal_add_lock(handle, id2, type2, flags2,
+ ocfs_journal_add_lock(handle, type2, flags2,
*res2, *bh2, inode2);
- ocfs_journal_add_lock(handle, id1, type1, flags1, *res1, *bh1,
+ ocfs_journal_add_lock(handle, type1, flags1, *res1, *bh1,
inode1);
}
@@ -849,6 +848,90 @@
return(status);
}
+static int ocfs_ugly_rename_lockres(ocfs_super *osb, __u64 oldoff,
+ __u64 newoff, ocfs_lock_res *lockres);
+
+/* this assumes that lockres is already hashed! */
+static int ocfs_ugly_rename_lockres(ocfs_super *osb, __u64 oldoff,
+ __u64 newoff, ocfs_lock_res *lockres)
+{
+ ocfs_lock_res *dest_lockres = NULL;
+ ocfs_lock_res *found_lockres = NULL;
+ int status = 0;
+ ocfs_journal *journal = &osb->journal;
+ ocfs_journal_handle *handle=NULL;
+ ocfs_journal_lock *j_lock;
+ struct list_head *tmp1, *tmp2;
+
+ LOG_ENTRY();
+
+ if (!lockres)
+ goto bail;
+
+ ocfs_get_lockres(lockres);
+
+ /* lookup the destination 1st:
+ * We may be renaming on top of another file
+ * and that files lockres is still in the
+ * hash. Delete it now. */
+ status = ocfs_lookup_sector_node (osb, newoff, &dest_lockres);
+
+ if (dest_lockres) {
+ printk("ocfs2: old lockres = 0x%p, "
+ "dest_lockres = 0x%p!\n", lockres,
+ dest_lockres);
+ /* this message is a warning that the line below is
+ * not to be put in a released version of ocfs. ITS
+ * BUGGY! */
+ ocfs_remove_sector_node (osb, dest_lockres);
+ ocfs_put_lockres(dest_lockres);
+ dest_lockres = NULL;
+ }
+
+ /* ok, now remove our own lockres from the hash. */
+ ocfs_remove_sector_node (osb, lockres);
+
+ /* change the value. */
+ ocfs_acquire_lockres(lockres);
+ lockres->sector_num = newoff;
+ ocfs_release_lockres(lockres);
+
+ /* and rehash it. */
+ status = ocfs_insert_sector_node(osb, lockres, &found_lockres);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+ if (found_lockres) {
+ LOG_ERROR_STR("Damn, we raced insert!");
+
+ BUG();
+ }
+
+ /* and now for an ugly journal hack! */
+ down(&journal->commit_sem);
+ list_for_each(tmp1, &(journal->commited)) {
+ handle = list_entry(tmp1, ocfs_journal_handle, h_list);
+
+ list_for_each(tmp2, &handle->locks) {
+ j_lock = list_entry(tmp2, ocfs_journal_lock,
+ lock_list);
+ if (j_lock->bh) {
+ brelse(j_lock->bh);
+ j_lock->bh = NULL;
+ }
+ }
+
+ }
+
+ up(&journal->commit_sem);
+bail:
+ ocfs_put_lockres(lockres);
+
+ LOG_EXIT_STATUS(status);
+ return(status);
+}
+
/*
* ocfs_rename()
*
@@ -945,8 +1028,6 @@
!(OCFS_I(new_inode)->oin_flags & OCFS_OIN_DELETE_ON_CLOSE)) {
/* OIN exists and it's not marked for deletion! */
ocfs_down_sem (&(OCFS_I(new_inode)->main_res), true);
- OCFS_SET_FLAG (OCFS_I(new_inode)->oin_flags,
- OCFS_OIN_IN_USE);
status = ocfs_verify_update_inode (osb, new_inode, &needs_trunc);
ocfs_up_sem (&(OCFS_I(new_inode)->main_res));
delete_target_oin = true;
@@ -1058,8 +1139,6 @@
tmpoff, handle, new_dentry,
new_dir);
if (status < 0) {
- /* TODO: we should make this transactional such that */
- /* either we get the new file or the old file stays. */
LOG_ERROR_STATUS (status);
goto finally;
}
@@ -1146,6 +1225,17 @@
HILO(tmpfe->this_sector));
/* move the inode offset over to the new entry */
+ status = ocfs_ugly_rename_lockres(osb,
+ GET_INODE_FEOFF(old_inode),
+ tmpfe->this_sector,
+ oldfe_lockres);
+ if (status < 0) {
+ ocfs_up_sem(&OCFS_I(old_inode)->main_res);
+ up(&old_inode->i_sem);
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+
SET_INODE_FEOFF(old_inode, tmpfe->this_sector);
if (S_ISDIR(old_inode->i_mode)) {
/* the vote offset doesn't actually change for
Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c 2004-04-22 19:46:12 UTC (rev 863)
+++ trunk/src/nm.c 2004-04-23 18:23:23 UTC (rev 864)
@@ -760,8 +760,12 @@
list_for_each(lock_p, &(handle->locks)) {
lock= list_entry(lock_p, ocfs_journal_lock, lock_list);
- if (lock->id == lockres->sector_num) {
+ if (lock->res->sector_num == lockres->sector_num) {
found = 1;
+
+ if (lock->res != lockres)
+ BUG();
+
break;
}
}
@@ -954,15 +958,9 @@
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
- /* If OIN_IN_USE is set we should go back and retry */
- for (i=0; i<5 && OCFS_I(inode)->oin_flags & OCFS_OIN_IN_USE; i++) {
- ocfs_up_sem (oin_sem);
- if (needs_trunc) {
- ocfs_truncate_inode_pages(inode, 0);
- needs_trunc = 0;
- }
- ocfs_sleep (20);
- ocfs_down_sem (oin_sem, true);
+ if (needs_trunc) {
+ ocfs_truncate_inode_pages(inode, 0);
+ needs_trunc = 0;
}
if (OCFS_I(inode)->open_hndl_cnt > 0) {
Modified: trunk/src/oin.c
===================================================================
--- trunk/src/oin.c 2004-04-22 19:46:12 UTC (rev 863)
+++ trunk/src/oin.c 2004-04-23 18:23:23 UTC (rev 864)
@@ -269,7 +269,7 @@
int status = 0;
ocfs_file_entry *fe = NULL;
bool local_handle = true;
- __u32 flags = OCFS_OIN_IN_USE;
+ __u32 flags = 0;
LOG_ENTRY ();
@@ -308,7 +308,6 @@
goto leave;
}
}
- OCFS_I(inode)->oin_flags |= OCFS_OIN_IN_USE;
leave:
if (local_handle && handle) {
More information about the Ocfs2-commits
mailing list