[SSI] openssi/kernel/cluster/ssi/cfs inode.c, 1.63, 1.64 read.c, 1.23, 1.24 write.c, 1.40, 1.41

Roger Tsang <[email protected]> Fri, 05 Mar 2010 05:23:59 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv25466/cluster/ssi/cfs

Modified Files:
      Tag: OPENSSI-FC
	inode.c read.c write.c 
Log Message:
* CFS (#ifdef CFS_ASYNC_LOCAL_SYNC):
- Optimize away unnecesary initialization in cfs_read_rpcsetup(),
  cfs_write_rpcsetup().

* CFS (#ifdef CFS_CHARD_SYNC_FIX):
- Fix unstable data could have been lost due to server migrated or failover.
  Unstable data is flushed again (to the new server) in cfs_reflush_inode().
- Fix downed pages were not properly coalesced. Coalesce downed pages on per
  inode basis to reduce contention during failover.

* CFS (#ifdef CFS_PAGEVEC):
- Optimize away unnecesary initialization in cfs_commit_rpcsetup().

 cluster/ssi/cfs/inode.c            |    5 
 cluster/ssi/cfs/read.c             |   28 ++++
 cluster/ssi/cfs/write.c            |  170 +++++++++++++++++++++++++----
 include/cluster/ssi/cfs/cfs_fs.h   |    3 
 include/cluster/ssi/cfs/cfs_fs_i.h |   10 +
 include/cluster/ssi/cfs/cfs_page.h |    4 
 include/linux/config.h             |   10 +
 7 files changed, 206 insertions(+), 24 deletions(-)


Index: inode.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/inode.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- inode.c	17 Dec 2009 06:43:50 -0000	1.63
+++ inode.c	5 Mar 2010 05:23:57 -0000	1.64
@@ -1742,6 +1742,11 @@
 		INIT_LOCK(&(cp->c_tcblock));
 		for (idx = 0 ; idx < CFS_MAX_LISTS ; idx++)
 			INIT_LIST_HEAD(&(cp->c_ilists[idx]));
+#ifdef CFS_CHARD_SYNC_FIX
+		INIT_LIST_HEAD(&cp->c_down_list);
+		INIT_LIST_HEAD(&cp->c_dirty_down);
+		INIT_LIST_HEAD(&cp->c_read_down);
+#endif
 	}
 }
 

Index: read.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/read.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- read.c	17 Dec 2009 06:43:50 -0000	1.23
+++ read.c	5 Mar 2010 05:23:57 -0000	1.24
@@ -356,9 +356,10 @@
 
 #ifdef CFS_ASYNC_LOCAL_SYNC
 	if (!CFS_AT_SERVER(data->inode) || !CFS_SB_UP_MIP(itocmi(data->inode))) {
-		data->flags = RPC_TASK_ASYNC | (IS_SWAPFILE(req->wb_inode)? CFS_RPC_SWAPFLAGS : 0);
-	} else
-		data->flags = 0;
+		data->flags = RPC_TASK_ASYNC;
+		if (IS_SWAPFILE(req->wb_inode))
+			data->flags |= CFS_RPC_SWAPFLAGS;
+	}
 #else
 	/* N.B. Do we need to test? Never called for swapfile inode */
 	data->flags = RPC_TASK_ASYNC | (IS_SWAPFILE(req->wb_inode)? CFS_RPC_SWAPFLAGS : 0);
@@ -459,10 +460,20 @@
 #ifndef CFS_ASYNC_QUEUE
 #error not supported
 #endif
+#ifdef CFS_CHARD_SYNC_FIX
+		if (list_empty(itoc_down(data->inode))) {
+			list_add_tail(itoc_down(data->inode),
+					&CFS_SERVER(data->inode)->read_down);
+		}
+#endif
 		while (!list_empty(&(data->pages))) {
 			req = cfs_list_entry(data->pages.next);
 			cfs_list_remove_request(req);
+#ifdef CFS_CHARD_SYNC_FIX
+			cfs_list_add_request(req, &itoc(data->inode)->c_read_down);
+#else
 			cfs_list_add_request(req, &CFS_SERVER(data->inode)->read_down);
+#endif
 		}
 
 		UNLOCK_COND_LOCK(&mip->mi_cond_lock);
@@ -844,12 +855,23 @@
 {
 #ifdef CFS_ASYNC_QUEUE
 	int err;
+#ifdef CFS_CHARD_SYNC_FIX
+	cnode_t *cnode, *tmp;
 
+	list_for_each_entry_safe(cnode, tmp, &server->read_down, c_down_list) {
+		list_del_init(&cnode->c_down_list);
+		err = cfs_pagein_list(&cnode->c_read_down, server->rpages);
+		if (err < 0)
+			printk(KERN_ERR "%s: error %d\n",
+				__FUNCTION__, err);
+	}
+#else /* CFS_CHARD_SYNC_FIX */
 	if (!list_empty(&server->read_down)) {
 		err = cfs_pagein_list(&server->read_down, server->rpages);
 		if (err < 0)
 			printk(KERN_ERR "%s: error %d\n", __FUNCTION__, err);
 	}
+#endif /* !CFS_CHARD_SYNC_FIX */
 #else /* CFS_ASYNC_QUEUE */
 	struct cfs_page		*req;
 	LIST_HEAD(one_request);

Index: write.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/write.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- write.c	17 Dec 2009 06:43:50 -0000	1.40
+++ write.c	5 Mar 2010 05:23:57 -0000	1.41
@@ -469,6 +469,9 @@
 #ifdef CFS_FILE_WRITE_LIVELOCK_FIX
 	int flushing = sem_flushing(&inode->i_sem);
 #endif
+#ifdef CFS_CHARD_SYNC_FIX
+	clusternode_t node;
+#endif
 
 	err = generic_writepages(mapping, wbc);
 	if (err)
@@ -509,13 +512,19 @@
 			npages = (unsigned int)lpages;
 	}
 
+#ifdef CFS_CHARD_SYNC_FIX
+	node = itocmi(inode)->mi_server;
+#endif
 	err = cfs_flush_inode(inode, index, npages, wb_priority(wbc));
 #else
 	err = cfs_flush_inode(inode, 0, 0, wb_priority(wbc));
-#endif
+#endif /* !CFS_COMMIT_FILE_RANGE */
 	if (err < 0)
 		goto out;
 	wbc->nr_to_write -= err;
+#ifdef CFS_CHARD_SYNC_FIX
+wait_on_requests:
+#endif
 	if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) {
 #ifdef CFS_COMMIT_FILE_RANGE
 		err = cfs_wait_on_requests(inode, index, npages);
@@ -527,13 +536,23 @@
 	}
 #ifndef KERNEL2613
 #ifdef CFS_COMMIT_FILE_RANGE
+#ifdef CFS_CHARD_SYNC_FIX
+	/* If server failed over, flush unstable data to new server. */
+	if (node != itocmi(inode)->mi_server) {
+		node = itocmi(inode)->mi_server;
+		err = cfs_reflush_inode(inode, index, npages, wb_priority(wbc));
+		if (err < 0)
+			goto out;
+		goto wait_on_requests;
+	}
+#endif
 	err = cfs_commit_inode(inode, index, npages, wb_priority(wbc));
 #else
 	err = cfs_commit_inode(inode, 0, 0, wb_priority(wbc));
-#endif
+#endif /* !CFS_COMMIT_FILE_RANGE */
 #else
 	err = cfs_commit_inode(inode, wb_priority(wbc));
-#endif
+#endif /* !KERNEL2613 */
 	if (err > 0) {
 		wbc->nr_to_write -= err;
 		err = 0;
@@ -1116,11 +1135,15 @@
 		}
 		end_page_writeback(page);
 
+#ifdef CFS_CHARD_SYNC_FIX
+		if (data->stable != CFS_UNSTABLE) {
+#else
 		/* If he specified sync or a csoft mount, then we don't need
 		 * to commit.  This should make csoft faster for write.
 		 */
 		if (data->stable != CFS_UNSTABLE ||
 		    !CFS_SB_HARD_MIP(itocmi(data->inode))) {
+#endif
 			cfs_inode_remove_request(req);
 			dprintk(" OK\n");
 			goto next;
@@ -1173,10 +1196,20 @@
 #ifndef CFS_ASYNC_QUEUE
 #error not supported
 #endif
+#ifdef CFS_CHARD_SYNC_FIX
+		if (list_empty(itoc_down(data->inode))) {
+			list_add_tail(itoc_down(data->inode),
+					&CFS_SERVER(data->inode)->dirty_down);
+		}
+#endif
 		while (!list_empty(&data->pages)) {
 			req = cfs_list_entry(data->pages.next);
 			cfs_list_remove_request(req);
+#ifdef CFS_CHARD_SYNC_FIX
+			cfs_list_add_request(req, &itoc(data->inode)->c_dirty_down);
+#else
 			cfs_list_add_request(req, &CFS_SERVER(data->inode)->dirty_down);
+#endif
 		}
 
 		UNLOCK_COND_LOCK(&mip->mi_cond_lock);
@@ -1446,8 +1479,9 @@
 	 * See related [ ssic-linux-Bugs-686748 ]
 	 *	-Roger
 	 */
-	data->flags = ((CFS_AT_SERVER(inode) && CFS_SB_UP_SB(inode->i_sb)) ||
-			(how & FLUSH_SYNC)) ? 0 : RPC_TASK_ASYNC;
+	if (!(how & FLUSH_SYNC) &&
+	    (!CFS_AT_SERVER(inode) || !CFS_SB_UP_SB(inode->i_sb)))
+		data->flags = RPC_TASK_ASYNC;
 #else
 	/* Set the initial flags for the task.  */
 	data->flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
@@ -1457,7 +1491,7 @@
 #ifdef CFS_ONLY_REMOTE_IS_CHARD
 	if ((how & FLUSH_STABLE) && !CFS_AT_SERVER(inode)) {
 #else
-	if (how & FLUSH_STABLE) { 
+	if (how & FLUSH_STABLE) {
 #endif
 		if (!itoc(inode)->ncommit)
 			stable = CFS_FILE_SYNC;
@@ -1679,6 +1713,9 @@
  */
 static int cfs_commit_result(struct cfs_write_data *data, int status)
 {
+#ifdef CFS_CHARD_SYNC_FIX
+	unsigned int res;
+#endif
 	struct cfs_page	*req;
 	cfs_mntinfo_t *mip;
 
@@ -1708,17 +1745,35 @@
 		printk(KERN_WARNING "CFS: commit handler down off %llo len %d\n",
 			data->offset, data->count);
 
-#ifndef CFS_COMMIT_DOWN
-#error not supported
+#ifdef CFS_CHARD_SYNC_FIX
+		if (list_empty(itoc_down(data->inode))) {
+			list_add_tail(itoc_down(data->inode),
+					&CFS_SERVER(data->inode)->dirty_down);
+		}
+		res = 0;
 #endif
 		while (!list_empty(&data->pages)) {
 			req = cfs_list_entry(data->pages.next);
 			cfs_list_remove_request(req);
+#ifdef CFS_CHARD_SYNC_FIX
+			cfs_mark_request_dirty(req);
+			cfs_list_remove_request(req);
+			cfs_list_add_request(req, &itoc(data->inode)->c_dirty_down);
+			res++;
+#else
+#ifdef CFS_COMMIT_DOWN
 			cfs_list_add_request(req, &CFS_SERVER(data->inode)->commit_down);
+#else
+#error not supported
+#endif
+#endif /* !CFS_CHARD_SYNC_FIX */
 		}
 
 		UNLOCK_COND_LOCK(&mip->mi_cond_lock);
 
+#ifdef CFS_CHARD_SYNC_FIX
+		sub_page_state(nr_unstable,res);
+#endif
 		cfs_commit_free(data);
 		return 0;
 	}
@@ -1992,7 +2047,8 @@
 #endif
 #ifdef CFS_PAGEVEC
 	/* Set the initial flags for the task.  */
-	data->flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
+	if (!(how & FLUSH_SYNC))
+		data->flags = RPC_TASK_ASYNC;
 
 #ifdef CFS_ASYNC_QUEUE
 	data->priority = flush_task_priority(how);
@@ -2087,6 +2143,50 @@
 	return res;
 }
 
+#ifdef CFS_CHARD_SYNC_FIX
+/*
+ * Flush requests marked for commit.
+ */
+int
+cfs_reflush_inode(
+	struct inode *inode,
+	unsigned long idx_start,
+	unsigned int npages,
+	int how)
+{
+	struct cfs_server *server = CFS_SERVER(inode);
+	struct cfs_page *req;
+	cnode_t *cp = itoc(inode);
+	LIST_HEAD(head);
+	unsigned int res;
+	int error = 0;
+
+	spin_lock(&cp->req_lock);
+	res = cfs_scan_commit(inode, &head, idx_start, npages);
+	spin_unlock(&cp->req_lock);
+	if (!res)
+		return 0;
+
+	while (!list_empty(&head)) {
+		req = cfs_list_entry((&head)->next);
+		cfs_list_remove_request(req);
+		cfs_mark_request_dirty(req);
+	}
+
+	/* Taken from cfs_flush_inode() */
+	/* For single writes, FLUSH_STABLE is more efficient */
+	if (res == cp->npages && cp->npages <= server->wpages) {
+	       if (res > 1 || cfs_list_entry(head.next)->wb_bytes <= server->wsize)
+		       how |= FLUSH_STABLE;
+	}
+	error = cfs_flush_list(&head, server->wpages, how);
+	if (error < 0)
+		return error;
+
+	return res;
+}
+#endif /* CFS_CHARD_SYNC_FIX */
+
 #ifndef KERNEL2613
 int cfs_commit_inode(struct inode *inode, unsigned long idx_start,
 		    unsigned int npages, int how)
@@ -2113,9 +2213,6 @@
 	if (error < 0)
 		return error;
 #else /* !KERNEL2613 */
-#ifdef CFS_COMMIT_FILE_RANGE
-#error CFS_COMMIT_FILE_RANGE requires undef KERNEL2613
-#endif
 	res = cfs_scan_commit(inode, &head, 0, 0);
 	if (res) {
 		spin_unlock(&cp->req_lock);
@@ -2130,8 +2227,10 @@
 int cfs_sync_inode(struct inode *inode, unsigned long idx_start,
 		  unsigned int npages, int how)
 {
-	int	error,
-		wait;
+#ifdef CFS_CHARD_SYNC_FIX
+	clusternode_t node = itocmi(inode)->mi_server;
+#endif
+	int error, wait;
 
 	wait = how & FLUSH_WAIT;
 	how &= ~FLUSH_WAIT;
@@ -2140,6 +2239,13 @@
 		error = 0;
 		if (wait)
 			error = cfs_wait_on_requests(inode, idx_start, npages);
+#ifdef CFS_CHARD_SYNC_FIX
+		/* If server failed over, flush unstable data to new server. */
+		if (node != itocmi(inode)->mi_server) {
+			node = itocmi(inode)->mi_server;
+			error = cfs_reflush_inode(inode, idx_start, npages, how);
+		}
+#endif
 		if (error == 0)
 			error = cfs_flush_inode(inode, idx_start, npages, how);
 		if (error == 0)
@@ -2186,7 +2292,7 @@
 		printk(KERN_INFO "cfs_write_data: not all structures were freed\n");
 }
 
-#ifndef CFS_COMMIT_DOWN
+#if !defined(CFS_COMMIT_DOWN) && !defined(CFS_CHARD_SYNC_FIX)
 /* This is part of cfs_sync_all_data() port to SSI-1.9+ and is used by
  * our process_cnodes() call in cfs_sync_all_data().
  */
@@ -2262,20 +2368,45 @@
 	cfs_free_cnode_idx(idx);
 #endif
 }
-#endif /* !CFS_COMMIT_DOWN */
+#endif /* !defined(CFS_COMMIT_DOWN) && !defined(CFS_CHARD_SYNC_FIX) */
 
 void
 cfs_sync_all_data(struct cfs_server *server)
 {
 #ifdef CFS_ASYNC_QUEUE
+#ifdef CFS_CHARD_SYNC_FIX
+	struct inode *inode;
+	cnode_t *cnode, *tmp;
+	int err;
+
+	/*
+	 * Flush downed dirty pages to disk
+	 */
+	list_for_each_entry_safe(cnode, tmp, &server->dirty_down, c_down_list) {
+		list_del_init(&cnode->c_down_list);
+
+		inode = igrab(ctoi(cnode));
+		err = cfs_flush_list(&cnode->c_dirty_down, server->wpages, 0);
+		if (err > 0) {
+			(void) cfs_wait_on_requests(inode, 0, 0);
+			err = cfs_commit_inode(inode, 0, 0, 0);
+		}
+		iput(inode);
+
+		if (err < 0)
+			printk(KERN_ERR "%s: error %d\n",
+				__FUNCTION__, err);
+	}
+#else /* CFS_CHARD_SYNC_FIX */
 	int err = 0;
 
-#ifndef CFS_COMMIT_DOWN
-#error not supported
-#endif
+#ifdef CFS_COMMIT_DOWN
 	/* Flush downed commit pages to disk */
 	if (!list_empty(&server->commit_down))
 		err = cfs_commit_list(&server->commit_down, 0);
+#else
+#error not supported
+#endif
 
 	/*
 	 * Flush downed dirty pages to disk
@@ -2285,6 +2416,7 @@
 
 	if (err < 0)
 		printk(KERN_ERR "%s: error %d\n", __FUNCTION__, err);
+#endif /* !CFS_CHARD_SYNC_FIX */
 #else /* CFS_ASYNC_QUEUE */
 	struct list_head	*pos, *tmp;
 	struct cfs_page		*req;


------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev