[Ocfs2-commits] rev 8 - in trunk: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Tue Dec 9 18:38:14 CST 2003
Author: manish
Date: 2003-12-09 18:38:12 -0600 (Tue, 09 Dec 2003)
New Revision: 8
Modified:
trunk/dir.c
trunk/dlm.c
trunk/heartbeat.c
trunk/inc/ocfs.h
trunk/inode.c
trunk/nm.c
trunk/osb.c
Log:
sync
Modified: trunk/dir.c
===================================================================
--- trunk/dir.c 2003-12-05 03:45:26 UTC (rev 7)
+++ trunk/dir.c 2003-12-10 00:38:12 UTC (rev 8)
@@ -665,6 +665,10 @@
continue;
fe = FILEENT_GETBH(dir, arr, i);
+ if (fe == NULL) {
+ // buffer is locked, like the rename case
+ continue;
+ }
if ((fe->sync_flags & OCFS_SYNC_FLAG_NAME_DELETED) ||
(!(fe->sync_flags & OCFS_SYNC_FLAG_VALID))) {
Modified: trunk/dlm.c
===================================================================
--- trunk/dlm.c 2003-12-05 03:45:26 UTC (rev 7)
+++ trunk/dlm.c 2003-12-10 00:38:12 UTC (rev 8)
@@ -130,9 +130,11 @@
if (flags & FLAG_CHANGE_MASTER)
lockres->master_node_num = osb->node_num;
finito:
+#if STUPID_STUFF
ocfs_down_sem(&(osb->voting_lock), true);
osb->in_voting = NOT_VOTING;
ocfs_up_sem(&(osb->voting_lock));
+#endif
if (*disk_vote) {
tmpstat = ocfs_reset_voting (osb, lockres->sector_num,
@@ -151,7 +153,7 @@
int i = 0;
LOG_ENTRY_ARGS("do_other_stupid_things = %s\n", do_other_stupid_things ? "true" : "false");
-#if 0
+#ifdef STUPID_STUFF
if((osb->trans_in_progress) && (osb->needs_flush))
{
osb->trans_in_progress = false;
@@ -209,7 +211,6 @@
__u32 wait;
bool publish_flag = false;
struct buffer_head **bhs = NULL;
- int nr = 0;
LOG_ENTRY_ARGS ("(osb=0x%08x, id=%u.%u, ty=%u, fl=%u, vm=0x%08x)\n",
osb, HILO (lock_id), lock_type, flags, LO (vote_map));
@@ -287,12 +288,13 @@
OCFS_BH_PUT_DATA(bhs[osb->node_num]);
pub_off = osb->vol_layout.publ_sect_off + (osb->node_num * osb->sect_size);
- status = ocfs_write_bhs (osb, bhs, nr, 0, NULL);
+ status = ocfs_write_bh (osb, bhs[osb->node_num], 0, NULL);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto finally;
}
+ ocfs_sleep(2);
atomic_set (&osb->node_req_vote, 1);
@@ -693,7 +695,7 @@
status = -EAGAIN;
goto bail;
}
-
+#if STUPID_STUFF
ocfs_down_sem(&(osb->voting_lock), true);
if (osb->in_voting == SKIPPED_HEARTBEAT) {
osb->in_voting = DOING_HEARTBEAT;
@@ -705,8 +707,8 @@
} else {
ocfs_up_sem(&(osb->voting_lock));
}
+#endif
-
gotvotemap |= (1 << osb->node_num);
status = ocfs_get_vote_on_disk (osb, lock_id, lock_type, flags,
@@ -735,7 +737,10 @@
timewaited += WAIT_FOR_VOTE_INCREMENT;
}
- bail:
+ if (timewaited >= time_to_wait)
+ status = -EAGAIN;
+
+bail:
LOG_EXIT_STATUS (status);
return status;
} /* ocfs_wait_for_vote */
@@ -766,13 +771,15 @@
LOG_ENTRY ();
+#ifdef STUPID_STUFF
ocfs_down_sem(&(osb->voting_lock), true);
osb->in_voting = DOING_HEARTBEAT;
ocfs_up_sem(&(osb->voting_lock));
-
+#endif
status = ocfs_disk_request_vote (osb, lock_id, lock_type, flags,
vote_map, lock_seq_num);
+#ifdef STUPID_STUFF
ocfs_down_sem(&(osb->voting_lock), true);
if (osb->in_voting == SKIPPED_HEARTBEAT) {
osb->in_voting = DOING_HEARTBEAT;
@@ -784,7 +791,7 @@
} else {
ocfs_up_sem(&(osb->voting_lock));
}
-
+#endif
LOG_EXIT_STATUS (status);
return status;
} /* ocfs_request_vote */
@@ -964,9 +971,11 @@
}
bail:
+#ifdef STUPID_STUFF
ocfs_down_sem(&(osb->voting_lock), true);
osb->in_voting = NOT_VOTING;
ocfs_up_sem(&(osb->voting_lock));
+#endif
if (*disk_vote) {
tmpstat = ocfs_reset_voting (osb, lock_id, lock_type, vote_map);
@@ -1439,11 +1448,11 @@
k++;
LOG_TRACE_ARGS("attempting to get lock, pass: %d\n", k);
- if (lockres->master_node_num != osb->node_num)
- updated = false;
+ if (lockres->master_node_num == osb->node_num)
+ updated = true;
if (!updated) {
- status = ocfs_read_bh (osb, lock_id, b, lockflags, inode);
+ status = ocfs_read_bh (osb, lock_id, b, 0, inode);
if (status < 0) {
ocfs_release_lockres (lockres);
LOG_ERROR_STATUS (status);
@@ -1489,6 +1498,7 @@
lockres->master_node_num == OCFS_INVALID_NODE_NUM ||
!IS_NODE_ALIVE(osb->publ_map, lockres->master_node_num,
OCFS_MAXIMUM_NODES));
+
wait_for_release = (lockres->lock_type > OCFS_DLM_SHARED_LOCK);
wait_for_release = false;
get_x = (flags & (FLAG_FILE_DELETE | FLAG_FILE_RENAME)
@@ -1831,9 +1841,11 @@
LOG_ERROR_STATUS (tmpstat);
}
+#ifdef STUPID_STUFF
ocfs_down_sem(&(osb->voting_lock), true);
osb->in_voting = NOT_VOTING;
ocfs_up_sem(&(osb->voting_lock));
+#endif
fe = (ocfs_file_entry *)OCFS_BH_GET_DATA(*b);
@@ -2161,9 +2173,11 @@
}
lockres->lock_type = (__u8) OCFS_DLM_NO_LOCK;
+#ifdef STUPID_STUFF
ocfs_down_sem(&(osb->voting_lock), true);
osb->in_voting = NOT_VOTING;
ocfs_up_sem(&(osb->voting_lock));
+#endif
LOG_TRACE_STR ("okie dokie... ocfs_break_cache_lock done\n");
Modified: trunk/heartbeat.c
===================================================================
--- trunk/heartbeat.c 2003-12-05 03:45:26 UTC (rev 7)
+++ trunk/heartbeat.c 2003-12-10 00:38:12 UTC (rev 8)
@@ -238,7 +238,7 @@
OCFS_BH_PUT_DATA(bhs[i]);
}
- bail:
+bail:
LOG_EXIT ();
return;
} /* ocfs_update_publish_map */
Modified: trunk/inc/ocfs.h
===================================================================
--- trunk/inc/ocfs.h 2003-12-05 03:45:26 UTC (rev 7)
+++ trunk/inc/ocfs.h 2003-12-10 00:38:12 UTC (rev 8)
@@ -246,7 +246,13 @@
#define FIRST_FILE_ENTRY(dir) ((char *) ((char *)dir)+OCFS_SECTOR_SIZE)
#define FILEENT(dir,idx) (ocfs_file_entry *) ( ((char *)dir) + \
((dir->index[idx]+1) * OCFS_SECTOR_SIZE))
-#define FILEENT_GETBH(dir,bhs,idx) ((ocfs_file_entry *)OCFS_BH_GET_DATA(bhs[(dir->index[idx]+1)]))
+#define FILEENT_GETBH(dir,bhs,idx) ({ \
+ int _i = dir->index[idx]+1; \
+ ocfs_file_entry *_ret = NULL; \
+ if (!buffer_locked(bhs[_i])) \
+ _ret = (ocfs_file_entry *)OCFS_BH_GET_DATA(bhs[_i]); \
+ _ret; \
+ })
#define FILEENT_PUTBH(dir,bhs,idx) OCFS_BH_PUT_DATA(bhs[(dir->index[idx]+1)])
@@ -1902,7 +1908,8 @@
struct _ocfs_journal journal;
atomic_t clean_buffer_seq;
spinlock_t clean_buffer_lock;
- struct list_head lock_recovery_lists[32];
+ struct list_head lock_recovery_lists[OCFS_MAXIMUM_NODES];
+ __u64 last_publ_seq_num[OCFS_MAXIMUM_NODES];
};
typedef struct _ocfs_comm_info
Modified: trunk/inode.c
===================================================================
--- trunk/inode.c 2003-12-05 03:45:26 UTC (rev 7)
+++ trunk/inode.c 2003-12-10 00:38:12 UTC (rev 8)
@@ -1481,7 +1481,11 @@
transferred += err;
size -= err;
buf += err;
- totalioblocks += blocks;
+ if (large_io) {
+ totalioblocks += (blocks * 8);
+ } else {
+ totalioblocks += blocks;
+ }
} else {
printk(
"ocfs_rw_direct : brw_kiovec() %d\n",
Modified: trunk/nm.c
===================================================================
--- trunk/nm.c 2003-12-05 03:45:26 UTC (rev 7)
+++ trunk/nm.c 2003-12-10 00:38:12 UTC (rev 8)
@@ -31,12 +31,14 @@
static struct inode * ocfs_get_inode_from_offset(ocfs_super * osb, __u64 fileoff);
static int ocfs_release_dir_cache_lock (ocfs_super *osb, struct buffer_head **dir_bhs, struct inode *inode);
-static inline int get_process_vote_action(ocfs_super * osb, ocfs_lock_res *lockres, __u32 node_num,
- __u32 flags, int status, bool *master_alive, ocfs_inode **oin);
+static inline int get_process_vote_action(ocfs_super * osb, ocfs_lock_res *lockres, __u32 node_num, __u32 flags, int status, bool *master_alive, ocfs_inode **oin);
static int ocfs_disk_update_resource (ocfs_super * osb, ocfs_lock_res * lock_res, struct buffer_head **bh, __u32 timeout, struct inode *inode);
static int ocfs_search_commited(ocfs_super *osb, ocfs_lock_res *lockres);
static void ocfs_inc_inode_seq(ocfs_super *osb, struct inode *inode);
+static int ocfs_schedule_process_vote(ocfs_super *osb, struct buffer_head *bh, int vote_node);
+void ocfs_process_vote_worker(void *val);
+
static const char *process_vote_strings[] = {
"INVALID_REQUEST", // reply with a NO vote
"UPDATE_OIN_INODE", // update both oin and inode
@@ -114,7 +116,104 @@
} /* ocfs_recv_thread */
+struct ocfs_sched_vote {
+ ocfs_super *osb;
+ ocfs_vote_request_ctxt ctxt;
+ __u8 publish_sect[512];
+#ifdef LINUX_2_5
+ struct work_struct ipc_wq;
+#else
+ struct tq_struct ipc_tq;
+#endif
+};
+
+void ocfs_process_vote_worker(void *val)
+{
+ struct ocfs_sched_vote *sv = (struct ocfs_sched_vote *) val;
+ ocfs_super *osb = NULL;
+
+ LOG_ENTRY();
+
+ if (!val)
+ BUG();
+
+ osb = sv->osb;
+
+ ocfs_process_vote(osb, &(sv->ctxt));
+
+ /* we should free this when done. */
+ ocfs_free(sv);
+
+ LOG_EXIT();
+ return;
+}
+
/*
+ * ocfs_schedule_process_vote
+ *
+ */
+static int ocfs_schedule_process_vote(ocfs_super *osb,
+ struct buffer_head *bh,
+ int vote_node)
+{
+ int status = 0;
+ ocfs_vote_request_ctxt *ctxt = NULL;
+ ocfs_publish * publish;
+ struct ocfs_sched_vote *sv = NULL;
+
+ LOG_ENTRY_ARGS("(vote_node = %d, bh = 0x%x)\n", vote_node, bh);
+
+ publish = (ocfs_publish *) OCFS_BH_GET_DATA(bh);
+
+ if (osb->last_publ_seq_num[vote_node] == publish->publ_seq_num){
+ LOG_TRACE_ARGS("Already voted on node %d, seqnum (%u.%u)\n",
+ vote_node, HILO(publish->publ_seq_num));
+ OCFS_BH_PUT_DATA(bh);
+ status = 0;
+ goto bail;
+ }
+ osb->last_publ_seq_num[vote_node] = publish->publ_seq_num;
+
+ sv = ocfs_malloc(sizeof(struct ocfs_sched_vote));
+ if (sv == NULL) {
+ OCFS_BH_PUT_DATA(bh);
+ LOG_ERROR_STATUS(status = -ENOMEM);
+ goto bail;
+ }
+ memset(sv, 0, sizeof(struct ocfs_sched_vote));
+
+ ctxt = (ocfs_vote_request_ctxt *) &(sv->ctxt);
+ ctxt->u.publish = (ocfs_publish *) &(sv->publish_sect);
+ memcpy(ctxt->u.publish, publish, osb->sect_size);
+ OCFS_BH_PUT_DATA(bh);
+
+ ctxt->request_method = DISK_VOTE;
+ ctxt->node_num = vote_node;
+
+ sv->osb = osb;
+
+#ifdef LINUX_2_5
+ INIT_WORK (&sv->ipc_wq, ocfs_process_vote_worker, sv);
+ schedule_work (&sv->ipc_wq);
+#else
+ INIT_TQUEUE (&sv->ipc_tq, ocfs_process_vote_worker, sv);
+ schedule_task (&sv->ipc_tq);
+#endif
+
+bail:
+ /* if no error, then the workqueue should clear it? */
+ if ((status < 0) && ctxt) {
+ if (ctxt->u.publish)
+ ocfs_free(ctxt->u.publish);
+ ocfs_free(ctxt);
+ }
+
+ LOG_EXIT_STATUS(status);
+ return(status);
+} /* ocfs_schedule_process_vote */
+
+
+/*
* ocfs_volume_thread()
*
* This function is executed as a kernel thread for each mounted ocfs volume.
@@ -129,7 +228,6 @@
#endif
__u8 *buffer = NULL;
ocfs_publish *publish;
- ocfs_publish *publish_to_vote = NULL;
__u32 i;
__u32 highest_vote_node;
__u64 offset = 0;
@@ -221,15 +319,20 @@
goto finally;
}
+#ifdef STUPID_STUFF
/* Update the timestamp on disk to indicate that it is alive */
ocfs_down_sem (&(osb->voting_lock), true);
if (osb->in_voting == NOT_VOTING) {
ocfs_up_sem (&(osb->voting_lock));
+#endif
ocfs_nm_heart_beat (osb, HEARTBEAT_METHOD_DISK, false);
+#ifdef STUPID_STUFF
} else {
+ printk("(%u) ocfs_volume_thread: SKIPPING HEARTBEAT\n", ocfs_getpid());
osb->in_voting = SKIPPED_HEARTBEAT;
ocfs_up_sem (&(osb->voting_lock));
}
+#endif
/* release publish lock */
up (&(osb->publish_lock));
@@ -266,24 +369,24 @@
/* map of local node */
curr_node_map = (__u64) ((__u64)1 << osb->node_num);
-
+
/* Check for the highest node looking for a vote, if anybody is looking */
for (i = 0, which = OCFS_VOLCFG_NEWCFG_SECTORS; i < num_nodes; i++, which++) {
publish = (ocfs_publish *) OCFS_BH_GET_DATA(osb->cfg_bhs[which]);
-
+
if (publish->time == (__u64) 0)
goto loop;
-
+
if (publish->vote != FLAG_VOTE_NODE ||
!(publish->vote_map & curr_node_map))
goto loop;
-
+
LOG_TRACE_ARGS ("node(%u): vote=%d dirty=%d type=%u\n",
i, publish->vote, publish->dirty,
publish->vote_type);
-
+
highest_vote_node = i;
-
+
/* Check if the node is alive or not */
if (IS_NODE_ALIVE (osb->publ_map, highest_vote_node,
num_nodes)) {
@@ -302,31 +405,40 @@
publish = NULL;
OCFS_BH_PUT_DATA(osb->cfg_bhs[which]);
}
-
- if ((vote_node != OCFS_INVALID_NODE_NUM) && (vote_node != osb->node_num)) {
- ocfs_vote_request_ctxt ctxt;
+
+ if ((vote_node != OCFS_INVALID_NODE_NUM) &&
+ (vote_node != osb->node_num)) {
+ LOG_TRACE_ARGS("vote_node = %d\n", vote_node);
+
bh = osb->cfg_bhs[OCFS_VOLCFG_NEWCFG_SECTORS
+ osb->node_num];
+ down(&(osb->publish_lock));
publish = (ocfs_publish *) OCFS_BH_GET_DATA(bh);
- if (publish->vote)
+ if (publish->vote) {
publish->vote = 0;
+ OCFS_BH_PUT_DATA(bh);
+ status = ocfs_write_bh(osb, bh, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+ } else
+ OCFS_BH_PUT_DATA(bh);
publish = NULL;
- OCFS_BH_PUT_DATA(bh);
+ up(&(osb->publish_lock));
which = vote_node + OCFS_VOLCFG_NEWCFG_SECTORS;
bh = osb->cfg_bhs[which];
- publish_to_vote = (ocfs_publish *) OCFS_BH_GET_DATA(osb->cfg_bhs[which]);
- memset(&ctxt, 0, sizeof(ocfs_vote_request_ctxt));
- ctxt.request_method = DISK_VOTE;
- ctxt.node_num = vote_node;
- ctxt.u.publish = publish_to_vote;
- ocfs_process_vote (osb, &ctxt);
- OCFS_BH_PUT_DATA(osb->cfg_bhs[which]);
+ status= ocfs_schedule_process_vote(osb, bh, vote_node);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
}
osb->hbt = 50 + jiffies;
-
+
finally:
status = 0; // ??????????????????????????
@@ -343,6 +455,13 @@
#endif
} /* while (!OCFS_FLAG_SHUTDOWN_VOL_THREAD && !OCFS_OSB_FLAGS_BEING_DISMOUNTED) */
+ /* Flush all scheduled tasks */
+#ifdef LINUX_2_5
+ flush_scheduled_work ();
+#else
+ flush_scheduled_tasks ();
+#endif
+
complete (&(osb->complete));
eek:
LOG_EXIT_LONG (0);
@@ -365,11 +484,14 @@
{
int status = 0;
ocfs_file_entry *fe;
- int lockflags = (lock_res->sector_num >= osb->vol_layout.bitmap_off ? OCFS_BH_CACHED : 0);
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, 0x%08x)\n", osb, lock_res, bh);
- status = ocfs_read_bh (osb, lock_res->sector_num, bh, lockflags, inode);
+ /* Don't sync-read if we already own the lock as it may not
+ * have hit disk yet. */
+ status = ocfs_read_bh (osb, lock_res->sector_num, bh,
+ (lock_res->master_node_num == osb->node_num) ?
+ OCFS_BH_CACHED : 0, inode);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto finally;
@@ -479,6 +601,17 @@
goto finally;
}
+ /* If we found the lockres in the hash and it's asked for, we still
+ * need to return a buffer_head */
+ if (status >= 0) {
+ status = ocfs_read_bh(osb, (*lockres)->sector_num, b,
+ OCFS_BH_CACHED, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto finally;
+ }
+ }
+
if ((*lockres)->master_node_num != osb->node_num) {
status = ocfs_disk_update_resource (osb, *lockres, b, timeout, inode);
if (status < 0) {
@@ -492,7 +625,7 @@
*updated = 1;
}
- finally:
+finally:
if (status < 0)
*lockres = NULL;
@@ -572,11 +705,15 @@
int vote_type = INVALID_REQUEST;
bool my_node_wins = false;
+ LOG_ENTRY_ARGS("(status=%d)\n", status);
+
*oin = NULL;
*master_alive = true;
if (status < 0) {
- if (status == -ETIMEDOUT)
+ if (status == -ETIMEDOUT) {
+ LOG_TRACE_STR("(INVALID_REQUEST) status == -ETIMEDOUT");
return INVALID_REQUEST;
+ }
} else if (lockres) {
*master_alive = lockres->master_node_num != OCFS_INVALID_NODE_NUM &&
IS_NODE_ALIVE(osb->publ_map,
@@ -601,8 +738,10 @@
vote_type = CHANGE_MASTER;
else if (flags & FLAG_ADD_OIN_MAP)
vote_type = ADD_OIN_MAP;
- else
+ else {
+ LOG_TRACE_STR("(INVALID_REQUEST) am master, but no more types");
vote_type = INVALID_REQUEST;
+ }
} else {
if (*master_alive)
vote_type = NOT_MASTER;
@@ -614,9 +753,13 @@
/* the only allowable action if we failed to */
/* get the lockres is a simple inode update */
- if (status < 0 && vote_type != UPDATE_INODE)
+ if (status < 0 && vote_type != UPDATE_INODE) {
+ LOG_TRACE_STR("(INVALID_REQUEST) (status < 0 && vote_type != UPDATE_INODE)");
vote_type = INVALID_REQUEST;
+ }
+ LOG_EXIT_STATUS(vote_type);
+
return vote_type;
}
Modified: trunk/osb.c
===================================================================
--- trunk/osb.c 2003-12-05 03:45:26 UTC (rev 7)
+++ trunk/osb.c 2003-12-10 00:38:12 UTC (rev 8)
@@ -201,8 +201,6 @@
length = OCFS_MAXIMUM_NODES * osb->sect_size;
status = ocfs_read_bhs(osb, vol_layout->publ_sect_off, length,
publish_bhs, 0, NULL);
-/* status = ocfs_read_force_disk_ex (osb, (void **)&buffer, length,
- length, vol_layout->publ_sect_off);*/
if (status < 0) {
LOG_ERROR_STATUS (status);
goto finally;
@@ -210,6 +208,9 @@
ocfs_update_publish_map (osb, publish_bhs, true);
+ for(i = 0; i < OCFS_MAXIMUM_NODES; i++)
+ osb->last_publ_seq_num[i] = (__u64) (-1);
+
/* We might need to add a variable in Global List of osb to */
/* delay any creation, if any other node is already creating a file */
@@ -570,9 +571,6 @@
LOG_ENTRY ();
-// size = (__u32) (osb->vol_layout.dir_node_size / osb->sect_size)
-// * sizeof(struct buffer_head *);
-
size = (__u32) ( OCFS_DEFAULT_DIR_NODE_SIZE / osb->sect_size)
* sizeof(struct buffer_head *);
//NewDirNode = ocfs_malloc (size);
More information about the Ocfs2-commits
mailing list