[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® 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